Merge "Removed vsync offset check from display info equality" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 834398e..ac756ea 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -1573,6 +1573,13 @@
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
+java_aconfig_library {
+    name: "power_flags_lib_host",
+    aconfig_declarations: "power_flags",
+    host_supported: true,
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
 // Content
 aconfig_declarations {
     name: "android.content.flags-aconfig",
diff --git a/apct-tests/perftests/autofill/src/android/view/autofill/AutofillTestWatcher.java b/apct-tests/perftests/autofill/src/android/view/autofill/AutofillTestWatcher.java
index f65067f..afdc361 100644
--- a/apct-tests/perftests/autofill/src/android/view/autofill/AutofillTestWatcher.java
+++ b/apct-tests/perftests/autofill/src/android/view/autofill/AutofillTestWatcher.java
@@ -174,7 +174,9 @@
 
         public static void onConnected() {
             Log.i(TAG, "onConnected:  sServiceWatcher=" + sServiceWatcher);
-
+            if (sServiceWatcher == null) {
+                sServiceWatcher = new ServiceWatcher();
+            }
             sServiceWatcher.mConnected.countDown();
         }
 
diff --git a/boot/boot-image-profile-extra.txt b/boot/boot-image-profile-extra.txt
index fd51f9c..ced0d17 100644
--- a/boot/boot-image-profile-extra.txt
+++ b/boot/boot-image-profile-extra.txt
@@ -45,3 +45,24 @@
 HSPLandroid/os/MessageQueue$StackNodeType;->*
 HSPLandroid/os/MessageQueue$StateNode;->*
 HSPLandroid/os/MessageQueue$TimedParkStateNode;->*
+HSPLandroid/os/PerfettoTrace$Category;->*
+HSPLandroid/os/PerfettoTrace;->*
+HSPLandroid/os/PerfettoTrackEventExtra;->*
+HSPLandroid/os/PerfettoTrackEventExtra$BuilderImpl;->*
+HSPLandroid/os/PerfettoTrackEventExtra$NoOpBuilder;->*
+HSPLandroid/os/PerfettoTrackEventExtra$ArgBool;->*
+HSPLandroid/os/PerfettoTrackEventExtra$ArgInt64;->*
+HSPLandroid/os/PerfettoTrackEventExtra$ArgDouble;->*
+HSPLandroid/os/PerfettoTrackEventExtra$ArgString;->*
+HSPLandroid/os/PerfettoTrackEventExtra$CounterInt64;->*
+HSPLandroid/os/PerfettoTrackEventExtra$CounterDouble;->*
+HSPLandroid/os/PerfettoTrackEventExtra$CounterTrack;->*
+HSPLandroid/os/PerfettoTrackEventExtra$NamedTrack;->*
+HSPLandroid/os/PerfettoTrackEventExtra$Flow;->*
+HSPLandroid/os/PerfettoTrackEventExtra$Proto;->*
+HSPLandroid/os/PerfettoTrackEventExtra$FieldInt64;->*
+HSPLandroid/os/PerfettoTrackEventExtra$FieldDouble;->*
+HSPLandroid/os/PerfettoTrackEventExtra$FieldString;->*
+HSPLandroid/os/PerfettoTrackEventExtra$FieldNested;->*
+HSPLandroid/os/PerfettoTrackEventExtra$Pool;->*
+HSPLandroid/os/PerfettoTrackEventExtra$RingBuffer;->*
diff --git a/cmds/screencap/Android.bp b/cmds/screencap/Android.bp
index 16026ec..9f350b1 100644
--- a/cmds/screencap/Android.bp
+++ b/cmds/screencap/Android.bp
@@ -7,25 +7,66 @@
     default_applicable_licenses: ["frameworks_base_license"],
 }
 
-cc_binary {
-    name: "screencap",
-
-    srcs: ["screencap.cpp"],
-
-    shared_libs: [
-        "libcutils",
-        "libutils",
-        "libbinder",
-        "libjnigraphics",
-        "libhwui",
-        "libui",
-        "libgui",
-    ],
+cc_defaults {
+    name: "screencap_defaults",
 
     cflags: [
         "-Wall",
         "-Werror",
-        "-Wunused",
         "-Wunreachable-code",
+        "-Wunused",
+    ],
+
+    shared_libs: [
+        "libbinder",
+        "libcutils",
+        "libgui",
+        "libhwui",
+        "libjnigraphics",
+        "libui",
+        "libutils",
+    ],
+}
+
+cc_library {
+    name: "libscreencap",
+
+    defaults: [
+        "screencap_defaults",
+    ],
+
+    srcs: ["screencap_utils.cpp"],
+}
+
+cc_binary {
+    name: "screencap",
+
+    defaults: [
+        "screencap_defaults",
+    ],
+
+    srcs: ["screencap.cpp"],
+
+    static_libs: [
+        "libscreencap",
+    ],
+}
+
+cc_test {
+    name: "libscreencap_test",
+
+    defaults: [
+        "screencap_defaults",
+    ],
+
+    test_suites: ["device-tests"],
+
+    srcs: [
+        "tests/screencap_test.cpp",
+    ],
+
+    static_libs: [
+        "libgmock",
+        "libscreencap",
     ],
 }
diff --git a/cmds/screencap/TEST_MAPPING b/cmds/screencap/TEST_MAPPING
new file mode 100644
index 0000000..05c598e
--- /dev/null
+++ b/cmds/screencap/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+  "presubmit": [
+    {
+      "name": "libscreencap_test"
+    }
+  ],
+  "hwasan-presubmit": [
+    {
+      "name": "libscreencap_test"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index d563ad3..9ff1161 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -37,6 +37,9 @@
 #include <ui/GraphicTypes.h>
 #include <ui/PixelFormat.h>
 
+#include "utils/Errors.h"
+#include "screencap_utils.h"
+
 using namespace android;
 
 #define COLORSPACE_UNKNOWN    0
@@ -145,24 +148,6 @@
     return NO_ERROR;
 }
 
-status_t capture(const DisplayId displayId,
-            const gui::CaptureArgs& captureArgs,
-            ScreenCaptureResults& outResult) {
-    sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
-    ScreenshotClient::captureDisplay(displayId, captureArgs, captureListener);
-
-    ScreenCaptureResults captureResults = captureListener->waitForResults();
-    if (!captureResults.fenceResult.ok()) {
-        fprintf(stderr, "Failed to take screenshot. Status: %d\n",
-                fenceStatus(captureResults.fenceResult));
-        return 1;
-    }
-
-    outResult = captureResults;
-
-    return 0;
-}
-
 status_t saveImage(const char* fn, std::optional<AndroidBitmapCompressFormat> format,
                    const ScreenCaptureResults& captureResults) {
     void* base = nullptr;
@@ -427,15 +412,12 @@
 
     std::vector<ScreenCaptureResults> results;
     const size_t numDisplays = displaysToCapture.size();
-    for (int i=0; i<numDisplays; i++) {
-        ScreenCaptureResults result;
-
+    for (int i = 0; i < numDisplays; i++) {
         // 1. Capture the screen
-        if (const status_t captureStatus =
-            capture(displaysToCapture[i], captureArgs, result) != 0) {
-
-            fprintf(stderr, "Capturing failed.\n");
-            return captureStatus;
+        auto captureResult = screencap::capture(displaysToCapture[i], captureArgs);
+        if (!captureResult.ok()) {
+            fprintf(stderr, "%sCapturing failed.\n", captureResult.error().message().c_str());
+            return 1;
         }
 
         // 2. Save the capture result as an image.
@@ -453,7 +435,7 @@
         if (!filename.empty()) {
             fn = filename.c_str();
         }
-        if (const status_t saveImageStatus = saveImage(fn, format, result) != 0) {
+        if (const status_t saveImageStatus = saveImage(fn, format, captureResult.value()) != 0) {
             fprintf(stderr, "Saving image failed.\n");
             return saveImageStatus;
         }
diff --git a/cmds/screencap/screencap_utils.cpp b/cmds/screencap/screencap_utils.cpp
new file mode 100644
index 0000000..03ade73
--- /dev/null
+++ b/cmds/screencap/screencap_utils.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "screencap_utils.h"
+
+#include "gui/SyncScreenCaptureListener.h"
+
+namespace android::screencap {
+
+base::Result<gui::ScreenCaptureResults> capture(const DisplayId displayId,
+                                                const gui::CaptureArgs& captureArgs) {
+    sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
+    auto captureDisplayStatus =
+            ScreenshotClient::captureDisplay(displayId, captureArgs, captureListener);
+
+    gui::ScreenCaptureResults captureResults = captureListener->waitForResults();
+    if (!captureResults.fenceResult.ok()) {
+        status_t captureStatus = fenceStatus(captureResults.fenceResult);
+        std::stringstream errorMsg;
+        errorMsg << "Failed to take take screenshot. ";
+        if (captureStatus == NAME_NOT_FOUND) {
+            errorMsg << "Display Id '" << displayId.value << "' is not valid.\n";
+        }
+        return base::ResultError(errorMsg.str(), captureStatus);
+    }
+
+    return captureResults;
+}
+
+} // namespace android::screencap
\ No newline at end of file
diff --git a/cmds/screencap/screencap_utils.h b/cmds/screencap/screencap_utils.h
new file mode 100644
index 0000000..6580e3f
--- /dev/null
+++ b/cmds/screencap/screencap_utils.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <android-base/result.h>
+#include <android/gui/DisplayCaptureArgs.h>
+
+#include "gui/ScreenCaptureResults.h"
+#include "ui/DisplayId.h"
+
+#pragma once
+
+namespace android::screencap {
+base::Result<gui::ScreenCaptureResults> capture(const DisplayId displayId,
+                                                const gui::CaptureArgs& captureArgs);
+} // namespace android::screencap
diff --git a/cmds/screencap/tests/screencap_test.cpp b/cmds/screencap/tests/screencap_test.cpp
new file mode 100644
index 0000000..b7bfca9
--- /dev/null
+++ b/cmds/screencap/tests/screencap_test.cpp
@@ -0,0 +1,68 @@
+// Copyright (C) 2025 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT 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 <binder/ProcessState.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <gui/SurfaceComposerClient.h>
+
+#include "android/gui/CaptureArgs.h"
+#include "gmock/gmock.h"
+#include "gui/ScreenCaptureResults.h"
+#include "screencap_utils.h"
+#include "ui/DisplayId.h"
+
+using ::android::DisplayId;
+using ::android::OK;
+using ::android::PhysicalDisplayId;
+using ::android::ProcessState;
+using ::android::SurfaceComposerClient;
+using ::android::gui::CaptureArgs;
+using ::android::gui::ScreenCaptureResults;
+using ::testing::AllOf;
+using ::testing::HasSubstr;
+
+class ScreenCapTest : public ::testing::Test {
+protected:
+    static void SetUpTestSuite() {
+        // These lines are copied from screencap.cpp.  They are necessary to call binder.
+        ProcessState::self()->setThreadPoolMaxThreadCount(0);
+        ProcessState::self()->startThreadPool();
+    }
+};
+
+TEST_F(ScreenCapTest, Capture_InvalidDisplayNumber) {
+    DisplayId display;
+    display.value = -1;
+
+    CaptureArgs args;
+    auto result = ::android::screencap::capture(display, args);
+    EXPECT_FALSE(result.ok());
+    EXPECT_THAT(result.error().message(),
+                AllOf(HasSubstr("Display Id"), HasSubstr("is not valid.")));
+}
+
+TEST_F(ScreenCapTest, Capture_SuccessWithPhysicalDisplay) {
+    const std::vector<PhysicalDisplayId> physicalDisplays =
+            SurfaceComposerClient::getPhysicalDisplayIds();
+
+    ASSERT_FALSE(physicalDisplays.empty());
+    DisplayId display;
+    display.value = physicalDisplays.front().value;
+
+    CaptureArgs args;
+    auto result = ::android::screencap::capture(display, args);
+    EXPECT_TRUE(result.ok());
+    // TODO consider verifying actual captured image.
+}
\ No newline at end of file
diff --git a/core/api/current.txt b/core/api/current.txt
index 2192965..dd60677 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -1207,7 +1207,6 @@
     field public static final int minResizeHeight = 16843670; // 0x1010396
     field public static final int minResizeWidth = 16843669; // 0x1010395
     field public static final int minSdkVersion = 16843276; // 0x101020c
-    field @FlaggedApi("android.sdk.major_minor_versioning_scheme") public static final int minSdkVersionFull = 16844461; // 0x10106ad
     field public static final int minWidth = 16843071; // 0x101013f
     field public static final int minimumHorizontalAngle = 16843901; // 0x101047d
     field public static final int minimumVerticalAngle = 16843902; // 0x101047e
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index ab82411..9a848d4 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -16052,7 +16052,7 @@
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isLteCdmaEvdoGsmWcdmaEnabled();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isMobileDataPolicyEnabled(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isNrDualConnectivityEnabled();
-    method @FlaggedApi("com.android.internal.telephony.flags.enable_modem_cipher_transparency") @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isNullCipherNotificationsEnabled();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isNullCipherNotificationsEnabled();
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isOpportunisticNetworkEnabled();
     method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String);
@@ -16097,7 +16097,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMobileDataPolicyEnabled(int, boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setNrDualConnectivityState(int);
-    method @FlaggedApi("com.android.internal.telephony.flags.enable_modem_cipher_transparency") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setNullCipherNotificationsEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setNullCipherNotificationsEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 0b0738e..c60a2d4 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1722,6 +1722,7 @@
   public final class DisplayManager {
     method public boolean areUserDisabledHdrTypesAllowed();
     method @RequiresPermission(android.Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE) public void clearGlobalUserPreferredDisplayMode();
+    method @FlaggedApi("com.android.server.display.feature.flags.display_topology") @Nullable @RequiresPermission("android.permission.MANAGE_DISPLAYS") public android.hardware.display.DisplayTopology getDisplayTopology();
     method @Nullable public android.view.Display.Mode getGlobalUserPreferredDisplayMode();
     method @NonNull public android.hardware.display.HdrConversionMode getHdrConversionModeSetting();
     method @NonNull public int[] getSupportedHdrOutputTypes();
@@ -1747,6 +1748,13 @@
     field public static final int VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH = 64; // 0x40
   }
 
+  @FlaggedApi("com.android.server.display.feature.flags.display_topology") public final class DisplayTopology implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.util.SparseArray<android.graphics.RectF> getAbsoluteBounds();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.display.DisplayTopology> CREATOR;
+  }
+
 }
 
 package android.hardware.fingerprint {
diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java
index e0a9371..9d1d9c7 100644
--- a/core/java/android/app/AutomaticZenRule.java
+++ b/core/java/android/app/AutomaticZenRule.java
@@ -162,7 +162,7 @@
      * both to fields in the rule itself (such as its name) and items with sub-fields.
      * @hide
      */
-    public static final int MAX_STRING_LENGTH = 1000;
+    public static final int MAX_STRING_LENGTH = 500;
 
     /**
      * The maximum string length for the trigger description rule, given UI constraints.
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 3fb0822..bc01f93 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -270,6 +270,7 @@
 
     int[] getAllowedAdjustmentKeyTypes();
     void setAssistantAdjustmentKeyTypeState(int type, boolean enabled);
+    String[] getAdjustmentDeniedPackages(String key);
     boolean isAdjustmentSupportedForPackage(String key, String pkg);
     void setAdjustmentSupportedForPackage(String key, String pkg, boolean enabled);
 
diff --git a/core/java/android/app/IUiModeManager.aidl b/core/java/android/app/IUiModeManager.aidl
index 3b83024..6d4ad75 100644
--- a/core/java/android/app/IUiModeManager.aidl
+++ b/core/java/android/app/IUiModeManager.aidl
@@ -51,7 +51,7 @@
      * Return the current running mode.
      */
     int getCurrentModeType();
-    
+
     /**
      * Sets the night mode.
      * <p>
@@ -161,61 +161,69 @@
     boolean setNightModeActivated(boolean active);
 
     /**
-    * Returns custom start clock time
-    */
+     * Returns custom start clock time
+     */
     long getCustomNightModeStart();
 
     /**
-    * Sets custom start clock time
-    */
+     * Sets custom start clock time
+     */
     void setCustomNightModeStart(long time);
 
     /**
-    * Returns custom end clock time
-    */
+     * Returns custom end clock time
+     */
     long getCustomNightModeEnd();
 
     /**
-    * Sets custom end clock time
-    */
+     * Sets custom end clock time
+     */
     void setCustomNightModeEnd(long time);
 
     /**
-    * Sets projection state for the caller for the given projection type.
-    */
+     * Sets projection state for the caller for the given projection type.
+     */
     boolean requestProjection(in IBinder binder, int projectionType, String callingPackage);
 
     /**
-    * Releases projection state for the caller for the given projection type.
-    */
+     * Releases projection state for the caller for the given projection type.
+     */
     boolean releaseProjection(int projectionType, String callingPackage);
 
     /**
-    * Registers a listener for changes to projection state.
-    */
+     * Registers a listener for changes to projection state.
+     */
     @EnforcePermission("READ_PROJECTION_STATE")
     void addOnProjectionStateChangedListener(in IOnProjectionStateChangedListener listener, int projectionType);
 
     /**
-    * Unregisters a listener for changes to projection state.
-    */
+     * Unregisters a listener for changes to projection state.
+     */
     @EnforcePermission("READ_PROJECTION_STATE")
     void removeOnProjectionStateChangedListener(in IOnProjectionStateChangedListener listener);
 
     /**
-    * Returns packages that have currently set the given projection type.
-    */
+     * Returns packages that have currently set the given projection type.
+     */
     @EnforcePermission("READ_PROJECTION_STATE")
     List<String> getProjectingPackages(int projectionType);
 
     /**
-    * Returns currently set projection types.
-    */
+     * Returns currently set projection types.
+     */
     @EnforcePermission("READ_PROJECTION_STATE")
     int getActiveProjectionTypes();
 
     /**
-    * Returns the contrast for the current user
-    */
+     * Returns the contrast for the current user.
+     */
     float getContrast();
+
+
+    /**
+     * Returns the force invert state.
+     *
+     * @hide
+     */
+    int getForceInvertState();
 }
diff --git a/core/java/android/app/IUiModeManagerCallback.aidl b/core/java/android/app/IUiModeManagerCallback.aidl
index 47c18a8..550779d 100644
--- a/core/java/android/app/IUiModeManagerCallback.aidl
+++ b/core/java/android/app/IUiModeManagerCallback.aidl
@@ -24,4 +24,5 @@
 */
 oneway interface IUiModeManagerCallback {
   void notifyContrastChanged(float contrast);
+  void notifyForceInvertStateChanged(int forceInvertState);
 }
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index b5ac4e7..d91838c 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -205,6 +205,15 @@
     public static final String EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS = "check_dpm";
 
     /**
+     * When switching to a secure user, system server will expect a callback when the UI has
+     * completed the switch.
+     *
+     * @hide
+     */
+    public static final String LOCK_ON_USER_SWITCH_CALLBACK = "onSwitchCallback";
+
+
+    /**
      *
      * Password lock type, see {@link #setLock}
      *
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index ba49149..dce15b8 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5999,8 +5999,10 @@
             setHeaderlessVerticalMargins(contentView, p, hasSecondLine);
 
             // Update margins to leave space for the top line (but not for headerless views like
-            // HUNS, which use a different layout that already accounts for that).
-            if (Flags.notificationsRedesignTemplates() && !p.mHeaderless) {
+            // HUNS, which use a different layout that already accounts for that). Templates that
+            // have content that will be displayed under the small icon also use a different margin.
+            if (Flags.notificationsRedesignTemplates()
+                    && !p.mHeaderless && !p.mHasContentInLeftMargin) {
                 int margin = getContentMarginTop(mContext,
                         R.dimen.notification_2025_content_margin_top);
                 contentView.setViewLayoutMargin(R.id.notification_main_column,
@@ -7597,11 +7599,19 @@
         }
 
         private int getCompactHeadsUpBaseLayoutResource() {
-            return R.layout.notification_template_material_compact_heads_up_base;
+            if (Flags.notificationsRedesignTemplates()) {
+                return R.layout.notification_2025_template_compact_heads_up_base;
+            } else {
+                return R.layout.notification_template_material_compact_heads_up_base;
+            }
         }
 
         private int getMessagingCompactHeadsUpLayoutResource() {
-            return R.layout.notification_template_material_messaging_compact_heads_up;
+            if (Flags.notificationsRedesignTemplates()) {
+                return R.layout.notification_2025_template_compact_heads_up_messaging;
+            } else {
+                return R.layout.notification_template_material_messaging_compact_heads_up;
+            }
         }
 
         private int getExpandedBaseLayoutResource() {
@@ -8927,16 +8937,6 @@
         }
 
         /**
-         * @hide
-         */
-        public boolean displayCustomViewInline() {
-            // This is a lie; True is returned for conversations to make sure that the custom
-            // view is not used instead of the template, but it will not actually be included.
-            return Flags.notificationNoCustomViewConversations()
-                    && mConversationType != CONVERSATION_TYPE_LEGACY;
-        }
-
-        /**
          * @return the text that should be displayed in the statusBar when heads upped.
          * If {@code null} is returned, the default implementation will be used.
          *
@@ -9502,7 +9502,8 @@
                     .text(null)
                     .hideLeftIcon(isOneToOne)
                     .hideRightIcon(hideRightIcons || isOneToOne)
-                    .headerTextSecondary(isHeaderless ? null : conversationTitle);
+                    .headerTextSecondary(isHeaderless ? null : conversationTitle)
+                    .hasContentInLeftMargin(true);
             RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(
                     isConversationLayout
                             ? mBuilder.getConversationLayoutResource()
@@ -14673,6 +14674,7 @@
         Icon mPromotedPicture;
         boolean mCallStyleActions;
         boolean mAllowTextWithProgress;
+        boolean mHasContentInLeftMargin;
         int mTitleViewId;
         int mTextViewId;
         @Nullable CharSequence mTitle;
@@ -14698,6 +14700,7 @@
             mPromotedPicture = null;
             mCallStyleActions = false;
             mAllowTextWithProgress = false;
+            mHasContentInLeftMargin = false;
             mTitleViewId = R.id.title;
             mTextViewId = R.id.text;
             mTitle = null;
@@ -14764,6 +14767,11 @@
             return this;
         }
 
+        public StandardTemplateParams hasContentInLeftMargin(boolean hasContentInLeftMargin) {
+            mHasContentInLeftMargin = hasContentInLeftMargin;
+            return this;
+        }
+
         final StandardTemplateParams hideSnoozeButton(boolean hideSnoozeButton) {
             this.mHideSnoozeButton = hideSnoozeButton;
             return this;
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index 5754984..f6c789d5 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -121,6 +121,24 @@
     }
 
     /**
+     * Listener for the force invert state. To listen for changes to
+     * the force invert state on the device, implement this interface and
+     * register it with the system by calling {@link #addForceInvertStateChangeListener}.
+     *
+     * @hide
+     */
+    public interface ForceInvertStateChangeListener {
+
+        /**
+         * Called when the force invert state changes.
+         *
+         * @param forceInvertState The force invert state in {@link #getForceInvertState}
+         * @hide
+         */
+        void onForceInvertStateChanged(@ForceInvertType int forceInvertState);
+    }
+
+    /**
      * Broadcast sent when the device's UI has switched to car mode, either
      * by being placed in a car dock or explicit action of the user.  After
      * sending the broadcast, the system will start the intent
@@ -374,6 +392,36 @@
     @SystemApi
     public static final int MODE_NIGHT_CUSTOM_TYPE_BEDTIME = 1;
 
+    /** @hide */
+    @IntDef(prefix = {"Force_Invert_Type_"}, value = {
+            FORCE_INVERT_TYPE_OFF,
+            FORCE_INVERT_TYPE_DARK,
+            FORCE_INVERT_TYPE_LIGHT,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ForceInvertType {}
+
+    /**
+     * Constant for {@link #getForceInvertState()}: Do not force invert.
+     *
+     * @hide
+     */
+    public static final int FORCE_INVERT_TYPE_OFF = 0;
+
+    /**
+     * Constant for {@link #getForceInvertState()}: Force apps to be dark.
+     *
+     * @hide
+     */
+    public static final int FORCE_INVERT_TYPE_DARK = 1;
+
+    /**
+     * Constant for {@link #getForceInvertState()}: Force apps to be light.
+     *
+     * @hide
+     */
+    public static final int FORCE_INVERT_TYPE_LIGHT = 2;
+
     private static Globals sGlobals;
 
     /**
@@ -405,6 +453,8 @@
         private final IUiModeManager mService;
         private final Object mGlobalsLock = new Object();
 
+        @ForceInvertType
+        private int mForceInvertState = FORCE_INVERT_TYPE_OFF;
         private float mContrast = ContrastUtils.CONTRAST_DEFAULT_VALUE;
 
         /**
@@ -414,16 +464,63 @@
         private final ArrayMap<ContrastChangeListener, Executor>
                 mContrastChangeListeners = new ArrayMap<>();
 
+        private final ArrayMap<ForceInvertStateChangeListener, Executor>
+                mForceInvertStateChangeListeners = new ArrayMap<>();
+
         Globals(IUiModeManager service) {
             mService = service;
             try {
                 mService.addCallback(this);
                 mContrast = mService.getContrast();
+                mForceInvertState = mService.getForceInvertState();
             } catch (RemoteException e) {
                 Log.e(TAG, "Setup failed: UiModeManagerService is dead", e);
             }
         }
 
+        @ForceInvertType
+        private int getForceInvertState() {
+            synchronized (mGlobalsLock) {
+                return mForceInvertState;
+            }
+        }
+
+        private void addForceInvertStateChangeListener(ForceInvertStateChangeListener listener,
+                Executor executor) {
+            synchronized (mGlobalsLock) {
+                mForceInvertStateChangeListeners.put(listener, executor);
+            }
+        }
+
+        private void removeForceInvertStateChangeListener(ForceInvertStateChangeListener listener) {
+            synchronized (mGlobalsLock) {
+                mForceInvertStateChangeListeners.remove(listener);
+            }
+        }
+
+        @Override
+        public void notifyForceInvertStateChanged(@ForceInvertType int forceInvertState) {
+            final Map<ForceInvertStateChangeListener, Executor> listeners = new ArrayMap<>();
+            synchronized (mGlobalsLock) {
+                // if value changed in the settings, update the cached value and notify listeners
+                if (mForceInvertState == forceInvertState) {
+                    return;
+                }
+
+                mForceInvertState = forceInvertState;
+                listeners.putAll(mForceInvertStateChangeListeners);
+            }
+
+            listeners.forEach((listener, executor) -> {
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() -> listener.onForceInvertStateChanged(forceInvertState));
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            });
+        }
+
         private float getContrast() {
             synchronized (mGlobalsLock) {
                 return mContrast;
@@ -1453,4 +1550,44 @@
         Objects.requireNonNull(listener);
         sGlobals.removeContrastChangeListener(listener);
     }
+
+    /**
+     * Returns the force invert state for the user.
+     *
+     * @hide
+     */
+    @ForceInvertType
+    public int getForceInvertState() {
+        return sGlobals.getForceInvertState();
+    }
+
+    /**
+     * Registers a {@link ForceInvertStateChangeListener} for the current user.
+     *
+     * @param executor The executor on which the listener should be called back.
+     * @param listener The listener.
+     *
+     * @hide
+     */
+    public void addForceInvertStateChangeListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull ForceInvertStateChangeListener listener) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(listener);
+        sGlobals.addForceInvertStateChangeListener(listener, executor);
+    }
+
+    /**
+     * Unregisters a {@link ForceInvertStateChangeListener} for the current user.
+     * If the listener was not registered, does nothing and returns.
+     *
+     * @param listener The listener to unregister.
+     *
+     * @hide
+     */
+    public void removeForceInvertStateChangeListener(
+            @NonNull ForceInvertStateChangeListener listener) {
+        Objects.requireNonNull(listener);
+        sGlobals.removeForceInvertStateChangeListener(listener);
+    }
 }
diff --git a/core/java/android/app/contextualsearch/flags.aconfig b/core/java/android/app/contextualsearch/flags.aconfig
index c19921d..d81ec1e 100644
--- a/core/java/android/app/contextualsearch/flags.aconfig
+++ b/core/java/android/app/contextualsearch/flags.aconfig
@@ -27,7 +27,10 @@
     name: "contextual_search_window_layer"
     namespace: "sysui_integrations"
     description: "Identify live contextual search UI to exclude from contextual search screenshot."
-    bug: "372510690"
+    bug: "390176823"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
 }
 
 flag {
@@ -35,4 +38,4 @@
     namespace: "sysui_integrations"
     description: "Add audio playing status to the contextual search invocation intent."
     bug: "372935419"
-}
\ No newline at end of file
+}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 8c7e93a..0369b7d9 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -7967,7 +7967,7 @@
      * @param flags Additional option flags to modify the data returned.
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching receiver, ordered from best to worst. If there are
-     *         no matching receivers, an empty list or null is returned.
+     *         no matching receivers, returns an empty list.
      */
     @NonNull
     public abstract List<ResolveInfo> queryBroadcastReceivers(@NonNull Intent intent, int flags);
@@ -7994,7 +7994,7 @@
      * @param userHandle UserHandle of the user being queried.
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching receiver, ordered from best to worst. If there are
-     *         no matching receivers, an empty list or null is returned.
+     *         no matching receivers, returns an empty list.
      * @hide
      */
     @SuppressWarnings("HiddenAbstractMethod")
@@ -8111,8 +8111,8 @@
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching service, ordered from best to worst. In other
      *         words, the first item is what would be returned by
-     *         {@link #resolveService}. If there are no matching services, an
-     *         empty list or null is returned.
+     *         {@link #resolveService}. If there are no matching services,
+     *         returns an empty list.
      */
     @NonNull
     public abstract List<ResolveInfo> queryIntentServices(@NonNull Intent intent,
@@ -8140,8 +8140,8 @@
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching service, ordered from best to worst. In other
      *         words, the first item is what would be returned by
-     *         {@link #resolveService}. If there are no matching services, an
-     *         empty list or null is returned.
+     *         {@link #resolveService}. If there are no matching services,
+     *         returns an empty list.
      * @hide
      */
     @SuppressWarnings("HiddenAbstractMethod")
@@ -8173,8 +8173,8 @@
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching service, ordered from best to worst. In other
      *         words, the first item is what would be returned by
-     *         {@link #resolveService}. If there are no matching services, an
-     *         empty list or null is returned.
+     *         {@link #resolveService}. If there are no matching services,
+     *         returns an empty list.
      * @hide
      */
     @NonNull
@@ -8208,7 +8208,7 @@
      * @param userId The user id.
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching provider, ordered from best to worst. If there are
-     *         no matching services, an empty list or null is returned.
+     *         no matching services, returns an empty list.
      * @hide
      */
     @SuppressWarnings("HiddenAbstractMethod")
@@ -8240,7 +8240,7 @@
      * @param user The user being queried.
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching provider, ordered from best to worst. If there are
-     *         no matching services, an empty list or null is returned.
+     *         no matching services, returns an empty list.
      * @hide
      */
     @NonNull
@@ -8274,7 +8274,7 @@
      * @param flags Additional option flags to modify the data returned.
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching provider, ordered from best to worst. If there are
-     *         no matching services, an empty list or null is returned.
+     *         no matching services, returns an empty list.
      */
     @NonNull
     public abstract List<ResolveInfo> queryIntentContentProviders(@NonNull Intent intent,
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index 4e6fb8d..e6082d0 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -615,3 +615,10 @@
     bug: "346553745"
     is_exported: true
 }
+
+flag {
+     namespace: "multi_user"
+     name: "logout_user_api"
+     description: "Add API to logout user"
+     bug: "350045389"
+}
diff --git a/core/java/android/content/pm/parsing/ApkLite.java b/core/java/android/content/pm/parsing/ApkLite.java
index 1d8209d..b8cf709 100644
--- a/core/java/android/content/pm/parsing/ApkLite.java
+++ b/core/java/android/content/pm/parsing/ApkLite.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.ArchivedPackageParcel;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -184,6 +185,11 @@
      */
     private final @Nullable ArchivedPackageParcel mArchivedPackage;
 
+    /**
+     *  pageSizeCompat info from manifest file
+     */
+    private final int mPageSizeCompat;
+
     public ApkLite(String path, String packageName, String splitName, boolean isFeatureSplit,
             String configForSplit, String usesSplitName, boolean isSplitRequired, int versionCode,
             int versionCodeMajor, int revisionCode, int installLocation,
@@ -200,7 +206,8 @@
             List<String> usesStaticLibraries, long[] usesStaticLibrariesVersionsMajor,
             String[][] usesStaticLibrariesCertDigests,
             boolean updatableSystem,
-            String emergencyInstaller, List<SharedLibraryInfo> declaredLibraries) {
+            String emergencyInstaller, List<SharedLibraryInfo> declaredLibraries,
+            int pageSizeCompat) {
         mPath = path;
         mPackageName = packageName;
         mSplitName = splitName;
@@ -245,6 +252,7 @@
         mEmergencyInstaller = emergencyInstaller;
         mArchivedPackage = null;
         mDeclaredLibraries = declaredLibraries;
+        mPageSizeCompat = pageSizeCompat;
     }
 
     public ApkLite(String path, ArchivedPackageParcel archivedPackage) {
@@ -292,6 +300,7 @@
         mEmergencyInstaller = null;
         mArchivedPackage = archivedPackage;
         mDeclaredLibraries = null;
+        mPageSizeCompat = ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED;
     }
 
     /**
@@ -676,11 +685,19 @@
         return mArchivedPackage;
     }
 
+    /**
+     *  pageSizeCompat info from manifest file
+     */
+    @DataClass.Generated.Member
+    public int getPageSizeCompat() {
+        return mPageSizeCompat;
+    }
+
     @DataClass.Generated(
-            time = 1731589363302L,
+            time = 1738189581427L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/content/pm/parsing/ApkLite.java",
-            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mRevisionCode\nprivate final  int mInstallLocation\nprivate final  int mMinSdkVersion\nprivate final  int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final  boolean mFeatureSplit\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mProfileableByShell\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final  boolean mOverlayIsStatic\nprivate final  int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final  int mRollbackDataPolicy\nprivate final  boolean mHasDeviceAdminReceiver\nprivate final  boolean mIsSdkLibrary\nprivate final  boolean mIsStaticLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesStaticLibraries\nprivate final @android.annotation.Nullable long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesStaticLibrariesCertDigests\nprivate final  boolean mUpdatableSystem\nprivate final @android.annotation.Nullable java.lang.String mEmergencyInstaller\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
+            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mRevisionCode\nprivate final  int mInstallLocation\nprivate final  int mMinSdkVersion\nprivate final  int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final  boolean mFeatureSplit\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mProfileableByShell\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final  boolean mOverlayIsStatic\nprivate final  int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final  int mRollbackDataPolicy\nprivate final  boolean mHasDeviceAdminReceiver\nprivate final  boolean mIsSdkLibrary\nprivate final  boolean mIsStaticLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesStaticLibraries\nprivate final @android.annotation.Nullable long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesStaticLibrariesCertDigests\nprivate final  boolean mUpdatableSystem\nprivate final @android.annotation.Nullable java.lang.String mEmergencyInstaller\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\nprivate final  int mPageSizeCompat\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 71d0a04..26252a9 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -22,6 +22,7 @@
 
 import android.annotation.NonNull;
 import android.app.admin.DeviceAdminReceiver;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.SharedLibraryInfo;
@@ -459,6 +460,7 @@
         boolean overlayIsStatic = false;
         int overlayPriority = 0;
         int rollbackDataPolicy = 0;
+        int pageSizeCompat = ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED;
 
         String requiredSystemPropertyName = null;
         String requiredSystemPropertyValue = null;
@@ -516,6 +518,10 @@
                 boolean hasBindDeviceAdminPermission =
                         android.Manifest.permission.BIND_DEVICE_ADMIN.equals(permission);
 
+                pageSizeCompat = parser.getAttributeIntValue(ANDROID_RES_NAMESPACE,
+                        "pageSizeCompat",
+                        ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_UNDEFINED);
+
                 final int innerDepth = parser.getDepth();
                 int innerType;
                 while ((innerType = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -817,7 +823,7 @@
                         usesSdkLibrariesVersionsMajor, usesSdkLibrariesCertDigests, isStaticLibrary,
                         usesStaticLibraries, usesStaticLibrariesVersions,
                         usesStaticLibrariesCertDigests, updatableSystem, emergencyInstaller,
-                        declaredLibraries));
+                        declaredLibraries, pageSizeCompat));
     }
 
     private static ParseResult<String[]> parseAdditionalCertificates(ParseInput input,
diff --git a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
index d2d3a68..c7403c0 100644
--- a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
@@ -339,36 +339,6 @@
     }
 
     /**
-     * Check if a package is compatible with this platform with regards to its
-     * its minSdkVersionFull.
-     *
-     * @param minSdkVersionFullString    A string representation of a major.minor version,
-     *                                   e.g. "12.34"
-     * @param platformMinSdkVersionFull The major and minor version of the platform, i.e. the value
-     *                                  of Build.VERSION.SDK_INT_FULL
-     * @param input                     A ParseInput object to report success or failure
-     */
-    public static ParseResult<Void> verifyMinSdkVersionFull(@NonNull String minSdkVersionFullString,
-            int platformMinSdkVersionFull, @NonNull ParseInput input) {
-        int minSdkVersionFull;
-        try {
-            minSdkVersionFull = Build.parseFullVersion(minSdkVersionFullString);
-        } catch (IllegalStateException e) {
-            return input.error(PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
-                    e.getMessage());
-        }
-        if (minSdkVersionFull <= platformMinSdkVersionFull) {
-            return input.success(null);
-        }
-        return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK,
-                "Requires newer sdk version "
-                + Build.fullVersionToString(minSdkVersionFull)
-                + " (current version is "
-                + Build.fullVersionToString(platformMinSdkVersionFull)
-                + ")");
-    }
-
-    /**
      * Computes the targetSdkVersion to use at runtime. If the package is not compatible with this
      * platform, populates {@code outError[0]} with an error message.
      * <p>
diff --git a/core/java/android/content/pm/parsing/PackageLite.java b/core/java/android/content/pm/parsing/PackageLite.java
index 0e11eec..43a3645 100644
--- a/core/java/android/content/pm/parsing/PackageLite.java
+++ b/core/java/android/content/pm/parsing/PackageLite.java
@@ -138,6 +138,11 @@
      */
     private final @Nullable ArchivedPackageParcel mArchivedPackage;
 
+    /**
+     *  pageSizeCompat info from manifest file
+     */
+    private final int mPageSizeCompat;
+
     public PackageLite(String path, String baseApkPath, ApkLite baseApk,
             String[] splitNames, boolean[] isFeatureSplits, String[] usesSplitNames,
             String[] configForSplit, String[] splitApkPaths, int[] splitRevisionCodes,
@@ -182,6 +187,7 @@
         mTargetSdk = targetSdk;
         mDeclaredLibraries = baseApk.getDeclaredLibraries();
         mArchivedPackage = baseApk.getArchivedPackage();
+        mPageSizeCompat = baseApk.getPageSizeCompat();
     }
 
     /**
@@ -511,11 +517,19 @@
         return mArchivedPackage;
     }
 
+    /**
+     *  pageSizeCompat info from manifest file
+     */
+    @DataClass.Generated.Member
+    public int getPageSizeCompat() {
+        return mPageSizeCompat;
+    }
+
     @DataClass.Generated(
-            time = 1731591578587L,
+            time = 1738193799106L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/content/pm/parsing/PackageLite.java",
-            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mTargetSdk\nprivate final  int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final  int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mProfileableByShell\nprivate final  boolean mUseEmbeddedDex\nprivate final  boolean mIsSdkLibrary\nprivate final  boolean mIsStaticLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesStaticLibraries\nprivate final @android.annotation.Nullable long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesStaticLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic  java.util.List<java.lang.String> getAllApkPaths()\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
+            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mTargetSdk\nprivate final  int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final  int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mProfileableByShell\nprivate final  boolean mUseEmbeddedDex\nprivate final  boolean mIsSdkLibrary\nprivate final  boolean mIsStaticLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesStaticLibraries\nprivate final @android.annotation.Nullable long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesStaticLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\nprivate final  int mPageSizeCompat\npublic  java.util.List<java.lang.String> getAllApkPaths()\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java
index 7dc6afb..a7fbce5 100644
--- a/core/java/android/hardware/biometrics/BiometricConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricConstants.java
@@ -188,6 +188,24 @@
     int BIOMETRIC_ERROR_CONTENT_VIEW_MORE_OPTIONS_BUTTON = 22;
 
     /**
+     * The error code returned after lock out error happens, the error dialog shows, and the users
+     * dismisses the dialog. This is a placeholder that is currently only used by the support
+     * library.
+     *
+     * @hide
+     */
+    int BIOMETRIC_ERROR_LOCKOUT_ERROR_DIALOG_DISMISSED = 23;
+
+    /**
+     * The error code returned after biometric hardware error happens, the error dialog shows, and
+     * the users dismisses the dialog.This is a placeholder that is currently only used by the
+     * support library.
+     *
+     * @hide
+     */
+    int BIOMETRIC_ERROR_BIOMETRIC_HARDWARE_ERROR_DIALOG_DISMISSED = 24;
+
+    /**
      * This constant is only used by SystemUI. It notifies SystemUI that authentication was paused
      * because the authentication attempt was unsuccessful.
      * @hide
@@ -219,6 +237,8 @@
             BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE,
             BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS,
             BIOMETRIC_ERROR_CONTENT_VIEW_MORE_OPTIONS_BUTTON,
+            BIOMETRIC_ERROR_LOCKOUT_ERROR_DIALOG_DISMISSED,
+            BIOMETRIC_ERROR_BIOMETRIC_HARDWARE_ERROR_DIALOG_DISMISSED,
             BIOMETRIC_PAUSED_REJECTED})
     @Retention(RetentionPolicy.SOURCE)
     @interface Errors {}
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 89a6b02..56d2727 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -1616,7 +1616,13 @@
             // request if no repeating request is active. A default capture request is created here
             // for initial use. The capture callback will provide capture results that include the
             // actual capture parameters used for the streaming.
-            CaptureRequest.Builder builder = createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+            CameraMetadataNative templatedRequest = mRemoteDevice.createDefaultRequest(
+                    CameraDevice.TEMPLATE_PREVIEW);
+
+            CaptureRequest.Builder builder = new CaptureRequest.Builder(
+                    templatedRequest, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE,
+                    getId(), /*physicalCameraIdSet*/ null);
+
             for (Surface surface : surfaces) {
                 builder.addTarget(surface);
             }
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index a96de4b..fded882 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -1873,6 +1873,8 @@
      */
     @RequiresPermission(MANAGE_DISPLAYS)
     @Nullable
+    @TestApi
+    @FlaggedApi(Flags.FLAG_DISPLAY_TOPOLOGY)
     public DisplayTopology getDisplayTopology() {
         return mGlobal.getDisplayTopology();
     }
diff --git a/core/java/android/hardware/display/DisplayTopology.java b/core/java/android/hardware/display/DisplayTopology.java
index 555ff4b..4ed0fc0 100644
--- a/core/java/android/hardware/display/DisplayTopology.java
+++ b/core/java/android/hardware/display/DisplayTopology.java
@@ -21,8 +21,10 @@
 import static android.hardware.display.DisplayTopology.TreeNode.POSITION_RIGHT;
 import static android.hardware.display.DisplayTopology.TreeNode.POSITION_TOP;
 
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.graphics.PointF;
 import android.graphics.RectF;
 import android.os.Parcel;
@@ -39,6 +41,7 @@
 import androidx.annotation.NonNull;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.display.feature.flags.Flags;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -59,6 +62,8 @@
  *
  * @hide
  */
+@TestApi
+@FlaggedApi(Flags.FLAG_DISPLAY_TOPOLOGY)
 public final class DisplayTopology implements Parcelable {
     private static final String TAG = "DisplayTopology";
     private static final float EPSILON = 0.0001f;
@@ -82,6 +87,7 @@
      * @param px The value in logical pixels
      * @param dpi The logical density of the display
      * @return The value in density-independent pixels
+     * @hide
      */
     public static float pxToDp(float px, int dpi) {
         return px * DisplayMetrics.DENSITY_DEFAULT / dpi;
@@ -91,6 +97,7 @@
      * @param dp The value in density-independent pixels
      * @param dpi The logical density of the display
      * @return The value in logical pixels
+     * @hide
      */
     public static float dpToPx(float dp, int dpi) {
         return dp * dpi / DisplayMetrics.DENSITY_DEFAULT;
@@ -108,8 +115,14 @@
      */
     private int mPrimaryDisplayId = Display.INVALID_DISPLAY;
 
+    /**
+     * @hide
+     */
     public DisplayTopology() {}
 
+    /**
+     * @hide
+     */
     public DisplayTopology(@Nullable TreeNode root, int primaryDisplayId) {
         mRoot = root;
         if (mRoot != null) {
@@ -124,15 +137,24 @@
         mPrimaryDisplayId = primaryDisplayId;
     }
 
+    /**
+     * @hide
+     */
     public DisplayTopology(Parcel source) {
         this(source.readTypedObject(TreeNode.CREATOR), source.readInt());
     }
 
+    /**
+     * @hide
+     */
     @Nullable
     public TreeNode getRoot() {
         return mRoot;
     }
 
+    /**
+     * @hide
+     */
     public int getPrimaryDisplayId() {
         return mPrimaryDisplayId;
     }
@@ -144,6 +166,7 @@
      * @param displayId The logical display ID
      * @param width The width of the display
      * @param height The height of the display
+     * @hide
      */
     public void addDisplay(int displayId, float width, float height) {
         addDisplay(displayId, width, height, /* shouldLog= */ true);
@@ -155,6 +178,7 @@
      * @param width The new width
      * @param height The new height
      * @return True if the topology has changed.
+     * @hide
      */
     public boolean updateDisplay(int displayId, float width, float height) {
         TreeNode display = findDisplay(displayId, mRoot);
@@ -178,6 +202,7 @@
      * one by one.
      * @param displayId The logical display ID
      * @return True if the display was present in the topology and removed.
+     * @hide
      */
     public boolean removeDisplay(int displayId) {
         if (findDisplay(displayId, mRoot) == null) {
@@ -221,6 +246,7 @@
      *               are the display IDs.
      * @throws IllegalArgumentException if the keys in {@code positions} are not the exact display
      *                                  IDs in this topology, no more, no less
+     * @hide
      */
     public void rearrange(Map<Integer, PointF> newPos) {
         if (mRoot == null) {
@@ -346,6 +372,7 @@
 
     /**
      * Clamp offsets and remove any overlaps between displays.
+     * @hide
      */
     public void normalize() {
         if (mRoot == null) {
@@ -494,6 +521,7 @@
 
     /**
      * @return A deep copy of the topology that will not be modified by the system.
+     * @hide
      */
     public DisplayTopology copy() {
         TreeNode rootCopy = mRoot == null ? null : mRoot.copy();
@@ -505,6 +533,7 @@
      * (0, 0).
      * @return Map from logical display ID to the display's absolute bounds
      */
+    @NonNull
     public SparseArray<RectF> getAbsoluteBounds() {
         Map<TreeNode, RectF> bounds = new HashMap<>();
         getInfo(bounds, /* depths= */ null, /* parents= */ null, mRoot, /* x= */ 0, /* y= */ 0,
@@ -529,6 +558,7 @@
 
     /**
      * Print the object's state and debug information into the given stream.
+     * @hide
      * @param pw The stream to dump information to.
      */
     public void dump(PrintWriter pw) {
@@ -629,6 +659,9 @@
         return result;
     }
 
+    /**
+     * @hide
+     */
     @Nullable
     public static TreeNode findDisplay(int displayId, @Nullable TreeNode startingNode) {
         if (startingNode == null) {
@@ -725,6 +758,7 @@
      * @param densityPerDisplay The logical display densities, indexed by logical display ID
      * @return The graph representation of the topology. If there is a corner adjacency, the same
      * display will appear twice in the list of adjacent displays with both possible placements.
+     * @hide
      */
     @Nullable
     public DisplayTopologyGraph getGraph(SparseIntArray densityPerDisplay) {
@@ -750,7 +784,7 @@
                 new SparseArray<>();
         for (int id : displayIds) {
             if (densityPerDisplay.get(id) == 0) {
-                Slog.w(TAG, "Cannot construct graph, no density for display " + id);
+                Slog.e(TAG, "Cannot construct graph, no density for display " + id);
                 return null;
             }
             adjacentDisplaysPerId.append(id, new ArrayList<>(Math.min(10, displayIds.size())));
@@ -839,6 +873,9 @@
         }
     }
 
+    /**
+     * @hide
+     */
     public static final class TreeNode implements Parcelable {
         public static final int POSITION_LEFT = 0;
         public static final int POSITION_TOP = 1;
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index ae017e8..23722ed 100644
--- a/core/java/android/hardware/input/input_framework.aconfig
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -225,3 +225,11 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "key_event_activity_detection"
+    namespace: "input"
+    is_exported: true
+    description: "Key Event Activity Detection"
+    bug: "356412905"
+}
diff --git a/core/java/android/os/ChildZygoteProcess.java b/core/java/android/os/ChildZygoteProcess.java
index d8f825a..84fd0ca 100644
--- a/core/java/android/os/ChildZygoteProcess.java
+++ b/core/java/android/os/ChildZygoteProcess.java
@@ -67,12 +67,15 @@
         if (mDead.get()) {
             return true;
         }
+        StrictMode.ThreadPolicy oldStrictModeThreadPolicy = StrictMode.allowThreadDiskReads();
         try {
             if (Os.stat("/proc/" + mPid).st_uid == mUid) {
                 return false;
             }
         } catch (ErrnoException e) {
             // Do nothing, it's dead.
+        } finally {
+            StrictMode.setThreadPolicy(oldStrictModeThreadPolicy);
         }
         mDead.set(true);
         return true;
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
index 877f130..349a2f0 100644
--- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java
+++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
@@ -24,8 +24,6 @@
 import android.app.ActivityThread;
 import android.app.Instrumentation;
 import android.compat.annotation.UnsupportedAppUsage;
-import android.os.Process;
-import android.os.UserHandle;
 import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 import android.ravenwood.annotation.RavenwoodRedirect;
 import android.ravenwood.annotation.RavenwoodRedirectionClass;
@@ -95,6 +93,13 @@
     private int mAsyncMessageCount;
 
     /**
+     * @hide
+     */
+    private final AtomicLong mMessageCount = new AtomicLong();
+    private final Thread mThread;
+    private final long mTid;
+
+    /**
      * Select between two implementations of message queue. The legacy implementation is used
      * by default as it provides maximum compatibility with applications and tests that
      * reach into MessageQueue via the mMessages field. The concurrent implemmentation is used for
@@ -128,6 +133,8 @@
         mUseConcurrent = sIsProcessAllowedToUseConcurrent && !isInstrumenting();
         mQuitAllowed = quitAllowed;
         mPtr = nativeInit();
+        mThread = Thread.currentThread();
+        mTid = Process.myTid();
     }
 
     private static void initIsProcessAllowedToUseConcurrent() {
@@ -218,6 +225,32 @@
         }
     }
 
+    private void decAndTraceMessageCount() {
+        mMessageCount.decrementAndGet();
+        traceMessageCount();
+    }
+
+    private void incAndTraceMessageCount(Message msg, long when) {
+        mMessageCount.incrementAndGet();
+        msg.mSendingThreadName = Thread.currentThread().getName();
+        msg.mEventId.set(PerfettoTrace.getFlowId());
+
+        traceMessageCount();
+        PerfettoTrace.instant(PerfettoTrace.MQ_CATEGORY, "message_queue_send")
+                .addFlow(msg.mEventId.get())
+                .addArg("receiving_thread", mThread.getName())
+                .addArg("delay", when - SystemClock.uptimeMillis())
+                .addArg("what", msg.what)
+                .emit();
+    }
+
+    /** @hide */
+    private void traceMessageCount() {
+        PerfettoTrace.counter(PerfettoTrace.MQ_CATEGORY, mMessageCount.get())
+                .usingThreadCounterTrack(mTid, mThread.getName())
+                .emit();
+    }
+
     // Disposes of the underlying message queue.
     // Must only be called on the looper thread or the finalizer.
     private void dispose() {
@@ -800,6 +833,7 @@
             Message msg = nextMessage(false, false);
             if (msg != null) {
                 msg.markInUse();
+                decAndTraceMessageCount();
                 return msg;
             }
 
@@ -909,6 +943,7 @@
                         if (msg.isAsynchronous()) {
                             mAsyncMessageCount--;
                         }
+                        decAndTraceMessageCount();
                         if (TRACE) {
                             Trace.setCounter("MQ.Delivered", mMessagesDelivered.incrementAndGet());
                         }
@@ -1075,6 +1110,7 @@
 
             msg.markInUse();
             msg.arg1 = token;
+            incAndTraceMessageCount(msg, when);
 
             if (!enqueueMessageUnchecked(msg, when)) {
                 Log.wtf(TAG_C, "Unexpected error while adding sync barrier!");
@@ -1090,6 +1126,7 @@
             msg.markInUse();
             msg.when = when;
             msg.arg1 = token;
+            incAndTraceMessageCount(msg, when);
 
             if (Flags.messageQueueTailTracking() && mLast != null && mLast.when <= when) {
                 /* Message goes to tail of list */
@@ -1196,6 +1233,7 @@
                 needWake = mMessages == null || mMessages.target != null;
             }
             p.recycleUnchecked();
+            decAndTraceMessageCount();
 
             // If the loop is quitting then it is already awake.
             // We can assume mPtr != 0 when mQuitting is false.
@@ -1252,6 +1290,8 @@
 
             msg.markInUse();
             msg.when = when;
+            incAndTraceMessageCount(msg, when);
+
             Message p = mMessages;
             boolean needWake;
             if (p == null || when == 0 || when < p.when) {
@@ -1391,6 +1431,7 @@
                 if (msg.isAsynchronous()) {
                     mAsyncMessageCount--;
                 }
+                decAndTraceMessageCount();
                 if (TRACE) {
                     Trace.setCounter("MQ.Delivered", mMessagesDelivered.incrementAndGet());
                 }
@@ -1642,6 +1683,7 @@
                     mAsyncMessageCount--;
                 }
                 p.recycleUnchecked();
+                decAndTraceMessageCount();
                 p = n;
             }
 
@@ -1660,6 +1702,7 @@
                             mAsyncMessageCount--;
                         }
                         n.recycleUnchecked();
+                        decAndTraceMessageCount();
                         p.next = nn;
                         if (p.next == null) {
                             mLast = p;
@@ -1718,6 +1761,7 @@
                             mAsyncMessageCount--;
                         }
                         n.recycleUnchecked();
+                        decAndTraceMessageCount();
                         p.next = nn;
                         if (p.next == null) {
                             mLast = p;
@@ -1759,6 +1803,7 @@
                     mAsyncMessageCount--;
                 }
                 p.recycleUnchecked();
+                decAndTraceMessageCount();
                 p = n;
             }
 
@@ -1777,6 +1822,7 @@
                             mAsyncMessageCount--;
                         }
                         n.recycleUnchecked();
+                        decAndTraceMessageCount();
                         p.next = nn;
                         if (p.next == null) {
                             mLast = p;
@@ -1832,6 +1878,7 @@
                     mAsyncMessageCount--;
                 }
                 p.recycleUnchecked();
+                decAndTraceMessageCount();
                 p = n;
             }
 
@@ -1850,6 +1897,7 @@
                             mAsyncMessageCount--;
                         }
                         n.recycleUnchecked();
+                        decAndTraceMessageCount();
                         p.next = nn;
                         if (p.next == null) {
                             mLast = p;
@@ -1904,6 +1952,7 @@
                     mAsyncMessageCount--;
                 }
                 p.recycleUnchecked();
+                decAndTraceMessageCount();
                 p = n;
             }
 
@@ -1921,6 +1970,7 @@
                             mAsyncMessageCount--;
                         }
                         n.recycleUnchecked();
+                        decAndTraceMessageCount();
                         p.next = nn;
                         if (p.next == null) {
                             mLast = p;
@@ -1976,6 +2026,7 @@
                     mAsyncMessageCount--;
                 }
                 p.recycleUnchecked();
+                decAndTraceMessageCount();
                 p = n;
             }
 
@@ -1993,6 +2044,7 @@
                             mAsyncMessageCount--;
                         }
                         n.recycleUnchecked();
+                        decAndTraceMessageCount();
                         p.next = nn;
                         if (p.next == null) {
                             mLast = p;
@@ -2027,6 +2079,8 @@
         mMessages = null;
         mLast = null;
         mAsyncMessageCount = 0;
+        mMessageCount.set(0);
+        traceMessageCount();
     }
 
     private void removeAllFutureMessagesLocked() {
@@ -2057,6 +2111,7 @@
                         mAsyncMessageCount--;
                     }
                     p.recycleUnchecked();
+                    decAndTraceMessageCount();
                 } while (n != null);
             }
         }
@@ -2701,6 +2756,7 @@
         MessageNode node = new MessageNode(msg, seq);
         msg.when = when;
         msg.markInUse();
+        incAndTraceMessageCount(msg, when);
 
         if (DEBUG) {
             Log.d(TAG_C, "Insert message what: " + msg.what + " when: " + msg.when + " seq: "
@@ -2828,6 +2884,7 @@
                 if (removeMatches) {
                     if (p.removeFromStack()) {
                         p.mMessage.recycleUnchecked();
+                        decAndTraceMessageCount();
                         if (mMessageCounts.incrementCancelled()) {
                             nativeWake(mPtr);
                         }
@@ -2870,6 +2927,7 @@
                     found = true;
                     if (queue.remove(msg)) {
                         msg.mMessage.recycleUnchecked();
+                        decAndTraceMessageCount();
                     }
                 } else {
                     return true;
diff --git a/core/java/android/os/ITradeInMode.aidl b/core/java/android/os/ITradeInMode.aidl
index f15954d..d05f52c 100644
--- a/core/java/android/os/ITradeInMode.aidl
+++ b/core/java/android/os/ITradeInMode.aidl
@@ -59,4 +59,37 @@
      * ENTER_TRADE_IN_MODE permission is required.
      */
     boolean enterEvaluationMode();
+
+    /**
+     * Schedules a wipe to trigger SUW for trade-in mode testing. A reboot is
+     * required. After this, startTesting() can be called.
+     *
+     * ENTER_TRADE_IN_MODE permission is required and ro.debuggable must be 1.
+     */
+    void scheduleWipeForTesting();
+
+    /**
+     * Enables testing. This only takes effect after the next reboot, and is
+     * only allowed in ro.debuggable builds. On the following boot, normal
+     * adbd will be disabled and trade-in mode adbd will be enabled instead.
+     *
+     * ENTER_TRADE_IN_MODE permission is required and ro.debuggable must be 1.
+     */
+    void startTesting();
+
+    /**
+     * Disables testing. This disables trade-in mode and removes any scheduled
+     * trade-in mode wipe.
+     *
+     * ENTER_TRADE_IN_MODE permission is required, ro.debuggable must be 1, and
+     * startTesting() must have been called.
+     */
+    void stopTesting();
+
+    /**
+     * Returns whether the device is testing trade-in mode.
+     *
+     * ENTER_TRADE_IN_MODE permission is required and ro.debuggable must be 1.
+     */
+    boolean isTesting();
 }
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 18f9b2b..59bd982 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -83,6 +83,8 @@
     long getUserCreationTime(int userId);
     int getUserSwitchability(int userId);
     boolean isUserSwitcherEnabled(boolean showEvenIfNotActionable, int mUserId);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_USERS)")
+    int getUserLogoutability(int userId);
     boolean isRestricted(int userId);
     boolean canHaveRestrictedProfile(int userId);
     boolean canAddPrivateProfile(int userId);
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index 2fe4871..d16e447 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -199,7 +199,12 @@
             return false;
         }
 
-        // This must be in a local variable, in case a UI event sets the logger
+        PerfettoTrace.begin(PerfettoTrace.MQ_CATEGORY, "message_queue_receive")
+                .addArg("sending_thread", msg.mSendingThreadName)
+                .addTerminatingFlow(msg.mEventId.get())
+                .emit();
+
+        // This must be in a local variabe, in case a UI event sets the logger
         final Printer logging = me.mLogging;
         if (logging != null) {
             logging.println(">>>>> Dispatching to " + msg.target + " "
@@ -289,6 +294,7 @@
                     + msg.callback + " what=" + msg.what);
         }
 
+        PerfettoTrace.end(PerfettoTrace.MQ_CATEGORY).emit();
         msg.recycleUnchecked();
 
         return true;
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
index 702fdc2..b22d177 100644
--- a/core/java/android/os/Message.java
+++ b/core/java/android/os/Message.java
@@ -23,6 +23,8 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 /**
  *
  * Defines a message containing a description and arbitrary data object that can be
@@ -37,6 +39,13 @@
 @android.ravenwood.annotation.RavenwoodKeepWholeClass
 public final class Message implements Parcelable {
     /**
+     * For tracing
+     *
+     * @hide Only for use within the system server.
+     */
+    public final AtomicInteger mEventId = new AtomicInteger();
+
+    /**
      * User-defined message code so that the recipient can identify
      * what this message is about. Each {@link Handler} has its own name-space
      * for message codes, so you do not need to worry about yours conflicting
@@ -101,6 +110,13 @@
      */
     public int workSourceUid = UID_NONE;
 
+    /**
+     * Sending thread
+     *
+     * @hide
+     */
+    public String mSendingThreadName;
+
     /** If set message is in use.
      * This flag is set when the message is enqueued and remains set while it
      * is delivered and afterwards when it is recycled.  The flag is only cleared
diff --git a/core/java/android/os/PerfettoTrace.java b/core/java/android/os/PerfettoTrace.java
index 68f1570..741d542 100644
--- a/core/java/android/os/PerfettoTrace.java
+++ b/core/java/android/os/PerfettoTrace.java
@@ -16,6 +16,8 @@
 
 package android.os;
 
+import com.android.internal.ravenwood.RavenwoodEnvironment;
+
 import dalvik.annotation.optimization.CriticalNative;
 import dalvik.annotation.optimization.FastNative;
 
@@ -32,6 +34,7 @@
  *
  * @hide
  */
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
 public final class PerfettoTrace {
     private static final String TAG = "PerfettoTrace";
 
@@ -48,11 +51,14 @@
      */
     private static final AtomicInteger sFlowEventId = new AtomicInteger();
 
+    public static final PerfettoTrace.Category MQ_CATEGORY = new PerfettoTrace.Category("mq");
+
     /**
      * Perfetto category a trace event belongs to.
      * Registering a category is not sufficient to capture events within the category, it must
      * also be enabled in the trace config.
      */
+    @android.ravenwood.annotation.RavenwoodKeepWholeClass
     public static final class Category implements PerfettoTrackEventExtra.PerfettoPointer {
         private static final NativeAllocationRegistry sRegistry =
                 NativeAllocationRegistry.createMalloced(
@@ -97,12 +103,16 @@
             mSeverity = severity;
             mPtr = native_init(name, tag, severity);
             mExtraPtr = native_get_extra_ptr(mPtr);
-            sRegistry.registerNativeAllocation(this, mPtr);
+            if (!RavenwoodEnvironment.getInstance().isRunningOnRavenwood()) {
+                sRegistry.registerNativeAllocation(this, mPtr);
+            }
         }
 
         @FastNative
+        @android.ravenwood.annotation.RavenwoodReplace
         private static native long native_init(String name, String tag, String severity);
         @CriticalNative
+        @android.ravenwood.annotation.RavenwoodReplace
         private static native long native_delete();
         @CriticalNative
         private static native void native_register(long ptr);
@@ -111,8 +121,24 @@
         @CriticalNative
         private static native boolean native_is_enabled(long ptr);
         @CriticalNative
+        @android.ravenwood.annotation.RavenwoodReplace
         private static native long native_get_extra_ptr(long ptr);
 
+        private static long native_init$ravenwood(String name, String tag, String severity) {
+            // Tracing currently completely disabled under Ravenwood
+            return 0;
+        }
+
+        private static long native_delete$ravenwood() {
+            // Tracing currently completely disabled under Ravenwood
+            return 0;
+        }
+
+        private static long native_get_extra_ptr$ravenwood(long ptr) {
+            // Tracing currently completely disabled under Ravenwood
+            return 0;
+        }
+
         /**
          * Register the category.
          */
@@ -134,10 +160,16 @@
         /**
          * Whether the category is enabled or not.
          */
+        @android.ravenwood.annotation.RavenwoodReplace
         public boolean isEnabled() {
             return IS_FLAG_ENABLED && native_is_enabled(mPtr);
         }
 
+        public boolean isEnabled$ravenwood() {
+            // Tracing currently completely disabled under Ravenwood
+            return false;
+        }
+
         /**
          * Whether the category is registered or not.
          */
@@ -340,4 +372,11 @@
     public static void register(boolean isBackendInProcess) {
         native_register(isBackendInProcess);
     }
+
+    /**
+     * Registers categories with Perfetto.
+     */
+    public static void registerCategories() {
+        MQ_CATEGORY.register();
+    }
 }
diff --git a/core/java/android/os/PerfettoTrackEventExtra.java b/core/java/android/os/PerfettoTrackEventExtra.java
index e034fb3..72b909e6 100644
--- a/core/java/android/os/PerfettoTrackEventExtra.java
+++ b/core/java/android/os/PerfettoTrackEventExtra.java
@@ -16,6 +16,8 @@
 
 package android.os;
 
+import com.android.internal.ravenwood.RavenwoodEnvironment;
+
 import dalvik.annotation.optimization.CriticalNative;
 import dalvik.annotation.optimization.FastNative;
 
@@ -29,6 +31,7 @@
  *
  * @hide
  */
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
 public final class PerfettoTrackEventExtra {
     private static final int DEFAULT_EXTRA_CACHE_SIZE = 5;
     private static final Builder NO_OP_BUILDER = new NoOpBuilder();
@@ -305,6 +308,7 @@
         Builder endNested();
     }
 
+    @android.ravenwood.annotation.RavenwoodKeepWholeClass
     public static final class NoOpBuilder implements Builder {
         @Override
         public void emit() {}
@@ -759,7 +763,9 @@
 
     private PerfettoTrackEventExtra() {
         mPtr = native_init();
-        sRegistry.registerNativeAllocation(this, mPtr);
+        if (!RavenwoodEnvironment.getInstance().isRunningOnRavenwood()) {
+            sRegistry.registerNativeAllocation(this, mPtr);
+        }
     }
 
     /**
@@ -1342,8 +1348,10 @@
     }
 
     @CriticalNative
+    @android.ravenwood.annotation.RavenwoodReplace
     private static native long native_init();
     @CriticalNative
+    @android.ravenwood.annotation.RavenwoodReplace
     private static native long native_delete();
     @CriticalNative
     private static native void native_add_arg(long ptr, long extraPtr);
@@ -1351,4 +1359,14 @@
     private static native void native_clear_args(long ptr);
     @FastNative
     private static native void native_emit(int type, long tag, String name, long ptr);
+
+    private static long native_init$ravenwood() {
+        // Tracing currently completely disabled under Ravenwood
+        return 0;
+    }
+
+    private static long native_delete$ravenwood() {
+        // Tracing currently completely disabled under Ravenwood
+        return 0;
+    }
 }
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index e769abe..5129af6 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -4213,6 +4213,17 @@
             else mFlags &= ~UNIMPORTANT_FOR_LOGGING;
         }
 
+        /** @hide */
+        public void updateUids(int[] uids) {
+            synchronized (mToken) {
+                try {
+                    mService.updateWakeLockUids(mToken, uids);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
+            }
+        }
+
         @Override
         public String toString() {
             synchronized (mToken) {
diff --git a/core/java/android/os/SharedMemory.java b/core/java/android/os/SharedMemory.java
index 46ae9d8..320641d 100644
--- a/core/java/android/os/SharedMemory.java
+++ b/core/java/android/os/SharedMemory.java
@@ -25,8 +25,6 @@
 
 import dalvik.system.VMRuntime;
 
-import libcore.io.IoUtils;
-
 import java.io.Closeable;
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -65,7 +63,7 @@
 
         mMemoryRegistration = new MemoryRegistration(mSize);
         mCleaner = Cleaner.create(mFileDescriptor,
-                new Closer(mFileDescriptor, mMemoryRegistration));
+                new Closer(mFileDescriptor.getInt$(), mMemoryRegistration));
     }
 
     /**
@@ -278,6 +276,7 @@
      */
     @Override
     public void close() {
+        mFileDescriptor.setInt$(-1);
         if (mCleaner != null) {
             mCleaner.clean();
             mCleaner = null;
@@ -327,20 +326,21 @@
      * Cleaner that closes the FD
      */
     private static final class Closer implements Runnable {
-        private FileDescriptor mFd;
+        private int mFd;
         private MemoryRegistration mMemoryReference;
 
-        private Closer(FileDescriptor fd, MemoryRegistration memoryReference) {
+        private Closer(int fd, MemoryRegistration memoryReference) {
             mFd = fd;
-            IoUtils.setFdOwner(mFd, this);
             mMemoryReference = memoryReference;
         }
 
         @Override
         public void run() {
-            IoUtils.closeQuietly(mFd);
-            mFd = null;
-
+            try {
+                FileDescriptor fd = new FileDescriptor();
+                fd.setInt$(mFd);
+                Os.close(fd);
+            } catch (ErrnoException e) { /* swallow error */ }
             mMemoryReference.release();
             mMemoryReference = null;
         }
diff --git a/core/java/android/os/TestLooperManager.java b/core/java/android/os/TestLooperManager.java
index ddfa379..2d9d025 100644
--- a/core/java/android/os/TestLooperManager.java
+++ b/core/java/android/os/TestLooperManager.java
@@ -18,6 +18,7 @@
 import android.annotation.Nullable;
 import android.util.ArraySet;
 
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.LinkedBlockingQueue;
 
 /**
@@ -38,10 +39,13 @@
     private final MessageQueue mQueue;
     private final Looper mLooper;
     private final LinkedBlockingQueue<MessageExecution> mExecuteQueue = new LinkedBlockingQueue<>();
+    private final boolean mLooperIsMyLooper;
+
+    // When this latch is zero, it's guaranteed that the LooperHolder Message
+    // is not in the underlying queue.
+    private final CountDownLatch mLooperHolderLatch = new CountDownLatch(1);
 
     private boolean mReleased;
-    private boolean mLooperBlocked;
-    private final boolean mLooperIsMyLooper;
 
     /**
      * @hide
@@ -59,6 +63,8 @@
         if (!mLooperIsMyLooper) {
             // Post a message that will keep the looper blocked as long as we are dispatching.
             new Handler(looper).post(new LooperHolder());
+        } else {
+            mLooperHolderLatch.countDown();
         }
     }
 
@@ -168,6 +174,7 @@
                 try {
                     execution.wait();
                 } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
                 }
                 if (execution.response != null) {
                     throw new RuntimeException(execution.response);
@@ -222,23 +229,17 @@
      * is not in the underlying queue.
      */
     private void waitForLooperHolder() {
-        while (!mLooperIsMyLooper && !mLooperBlocked) {
-            synchronized (this) {
-                try {
-                    wait();
-                } catch (InterruptedException e) {
-                }
-            }
+        try {
+            mLooperHolderLatch.await();
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
         }
     }
 
     private class LooperHolder implements Runnable {
         @Override
         public void run() {
-            synchronized (TestLooperManager.this) {
-                mLooperBlocked = true;
-                TestLooperManager.this.notify();
-            }
+            mLooperHolderLatch.countDown();
             while (!mReleased) {
                 try {
                     final MessageExecution take = mExecuteQueue.take();
@@ -246,11 +247,9 @@
                         processMessage(take);
                     }
                 } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
                 }
             }
-            synchronized (TestLooperManager.this) {
-                mLooperBlocked = false;
-            }
         }
 
         private void processMessage(MessageExecution mex) {
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index 09e6a45..bf4c4d1 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -544,5 +544,6 @@
      */
     public static void registerWithPerfetto() {
         PerfettoTrace.register(false /* isBackendInProcess */);
+        PerfettoTrace.registerCategories();
     }
 }
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index aaf6489..c00f31d 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -2261,6 +2261,45 @@
     public @interface UserSwitchabilityResult {}
 
     /**
+     * Indicates that user can logout.
+     * @hide
+     */
+    public static final int LOGOUTABILITY_STATUS_OK = 0;
+
+    /**
+     * Indicates that user cannot logout because it is the system user.
+     * @hide
+     */
+    public static final int LOGOUTABILITY_STATUS_CANNOT_LOGOUT_SYSTEM_USER = 1;
+
+    /**
+     * Indicates that user cannot logout because there is no suitable user to logout to. This is
+     * generally applicable to Headless System User Mode devices that do not have an interactive
+     * system user.
+     * @hide
+     */
+    public static final int LOGOUTABILITY_STATUS_NO_SUITABLE_USER_TO_LOGOUT_TO = 2;
+
+    /**
+     * Indicates that user cannot logout because user switch cannot happen.
+     * @hide
+     */
+    public static final int LOGOUTABILITY_STATUS_CANNOT_SWITCH = 3;
+
+    /**
+     * Result returned in {@link #getUserLogoutability()} indicating user logoutability.
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = false, prefix = { "LOGOUTABILITY_STATUS_" }, value = {
+            LOGOUTABILITY_STATUS_OK,
+            LOGOUTABILITY_STATUS_CANNOT_LOGOUT_SYSTEM_USER,
+            LOGOUTABILITY_STATUS_NO_SUITABLE_USER_TO_LOGOUT_TO,
+            LOGOUTABILITY_STATUS_CANNOT_SWITCH
+    })
+    public @interface UserLogoutability {}
+
+    /**
      * A response code from {@link #removeUserWhenPossible(UserHandle, boolean)} indicating that
      * the specified user has been successfully removed.
      *
@@ -2737,6 +2776,35 @@
     }
 
     /**
+     * Returns whether logging out is currently allowed for the context user.
+     *
+     * <p>Logging out is not allowed in the following cases:
+     * <ol>
+     * <li>the user is system user
+     * <li>there is no suitable user to logout to (if no interactive system user)
+     * <li>the user is in a phone call
+     * <li>{@link #DISALLOW_USER_SWITCH} is set
+     * <li>system user hasn't been unlocked yet
+     * </ol>
+     *
+     * @return A {@link UserLogoutability} flag indicating if the user can logout,
+     * one of {@link #LOGOUTABILITY_STATUS_OK},
+     * {@link #LOGOUTABILITY_STATUS_CANNOT_LOGOUT_SYSTEM_USER},
+     * {@link #LOGOUTABILITY_STATUS_NO_SUITABLE_USER_TO_LOGOUT_TO},
+     * {@link #LOGOUTABILITY_STATUS_CANNOT_SWITCH}.
+     * @hide
+     */
+    @UserHandleAware
+    @RequiresPermission(Manifest.permission.MANAGE_USERS)
+    public @UserLogoutability int getUserLogoutability() {
+        try {
+            return mService.getUserLogoutability(mUserId);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Returns the userId for the context user.
      *
      * @return the userId of the context user.
@@ -5326,7 +5394,9 @@
     }
 
     /**
-     * Returns list of the profiles of userId including userId itself.
+     * Returns a list of the users that are associated with userId, including userId itself. This
+     * includes the user, its profiles, its parent, and its parent's other profiles, as applicable.
+     *
      * Note that this returns both enabled and not enabled profiles. See
      * {@link #getEnabledProfiles(int)} if you need only the enabled ones.
      * <p>Note that this includes all profile types (not including Restricted profiles).
@@ -5334,7 +5404,7 @@
      * <p>Requires {@link android.Manifest.permission#MANAGE_USERS} or
      * {@link android.Manifest.permission#CREATE_USERS} or
      * {@link android.Manifest.permission#QUERY_USERS} if userId is not the calling user.
-     * @param userId profiles of this user will be returned.
+     * @param userId profiles associated with this user (including itself) will be returned.
      * @return the list of profiles.
      * @hide
      */
@@ -5358,12 +5428,13 @@
     }
 
     /**
-     * Returns list of the profiles of the given user, including userId itself, as well as the
-     * communal profile, if there is one.
+     * Returns a list of the users that are associated with userId, including userId itself,
+     * as well as the communal profile, if there is one.
      *
      * <p>Note that this returns both enabled and not enabled profiles.
      * <p>Note that this includes all profile types (not including Restricted profiles).
      *
+     * @see #getProfiles(int)
      * @hide
      */
     @FlaggedApi(android.multiuser.Flags.FLAG_SUPPORT_COMMUNAL_PROFILE)
@@ -5419,7 +5490,10 @@
     }
 
     /**
-     * Returns list of the profiles of userId including userId itself.
+     * Returns a list of the enabled users that are associated with userId, including userId itself.
+     * This includes the user, its profiles, its parent, and its parent's other profiles, as
+     * applicable.
+     *
      * Note that this returns only {@link UserInfo#isEnabled() enabled} profiles.
      * <p>Note that this includes all profile types (not including Restricted profiles).
      *
@@ -5447,8 +5521,10 @@
     }
 
     /**
-     * Returns a list of UserHandles for profiles associated with the context user, including the
-     * user itself.
+     * Returns a list of the users that are associated with the context user, including the user
+     * itself. This includes the user, its profiles, its parent, and its parent's other profiles,
+     * as applicable.
+     *
      * <p>Note that this includes all profile types (not including Restricted profiles).
      *
      * @return A non-empty list of UserHandles associated with the context user.
@@ -5465,8 +5541,10 @@
     }
 
     /**
-     * Returns a list of ids for enabled profiles associated with the context user including the
-     * user itself.
+     * Returns a list of the enabled users that are associated with the context user, including the
+     * user itself. This includes the user, its profiles, its parent, and its parent's other
+     * profiles, as applicable.
+     *
      * <p>Note that this includes all profile types (not including Restricted profiles).
      *
      * @return A non-empty list of UserHandles associated with the context user.
@@ -5483,8 +5561,10 @@
     }
 
     /**
-     * Returns a list of ids for all profiles associated with the context user including the user
-     * itself.
+     * Returns a list of all users that are associated with the context user, including the user
+     * itself. This includes the user, its profiles, its parent, and its parent's other profiles,
+     * as applicable.
+     *
      * <p>Note that this includes all profile types (not including Restricted profiles).
      *
      * @return A non-empty list of UserHandles associated with the context user.
@@ -5501,8 +5581,10 @@
     }
 
     /**
-     * Returns a list of ids for profiles associated with the context user including the user
-     * itself.
+     * Returns a list of the users that are associated with the context user, including the user
+     * itself. This includes the user, its profiles, its parent, and its parent's other profiles, as
+     * applicable.
+     *
      * <p>Note that this includes all profile types (not including Restricted profiles).
      *
      * @param enabledOnly whether to return only {@link UserInfo#isEnabled() enabled} profiles
@@ -5528,8 +5610,10 @@
     }
 
     /**
-     * Returns a list of ids for profiles associated with the specified user including the user
-     * itself.
+     * Returns a list of the users that are associated with the specified user, including the user
+     * itself. This includes the user, its profiles, its parent, and its parent's other profiles,
+     * as applicable.
+     *
      * <p>Note that this includes all profile types (not including Restricted profiles).
      *
      * @param userId      id of the user to return profiles for
diff --git a/core/java/android/service/chooser/flags.aconfig b/core/java/android/service/chooser/flags.aconfig
index 2b75493..ae0b56e 100644
--- a/core/java/android/service/chooser/flags.aconfig
+++ b/core/java/android/service/chooser/flags.aconfig
@@ -2,6 +2,16 @@
 container: "system"
 
 flag {
+  name: "announce_shortcuts_and_suggested_apps_legacy"
+  namespace: "intentresolver"
+  description: "Enable talkback announcement for the app shortcuts and the suggested apps target groups in the legacy sharesheet codebase."
+  bug: "380211084"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
   name: "chooser_album_text"
   is_exported: true
   namespace: "intentresolver"
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 311fbee..e361ac7 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -594,6 +594,7 @@
 
         private final Runnable mFreeNativeResources;
         private boolean mRemoved = false;
+        private OnJankDataListener mListener;
 
         private OnJankDataListenerRegistration() {
             mNativeObject = 0;
@@ -604,6 +605,8 @@
             mNativeObject = nativeCreateJankDataListenerWrapper(surface.mNativeObject, listener);
             mFreeNativeResources = (mNativeObject == 0) ? () -> {} :
                     sRegistry.registerNativeAllocation(this, mNativeObject);
+            // Make sure the listener doesn't get GCed as long as the registration is alive.
+            mListener = listener;
         }
 
         /**
@@ -643,6 +646,7 @@
             if (!mRemoved) {
                 removeAfter(0);
             }
+            mListener = null;
             mFreeNativeResources.run();
         }
     }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index bf34069..900f22d 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -123,6 +123,7 @@
 import static android.view.flags.Flags.toolkitFrameRateTypingReadOnly;
 import static android.view.flags.Flags.toolkitFrameRateVelocityMappingReadOnly;
 import static android.view.flags.Flags.toolkitFrameRateViewEnablingReadOnly;
+import static android.view.flags.Flags.toolkitInitialTouchBoost;
 import static android.view.flags.Flags.toolkitMetricsForFrameRateDecision;
 import static android.view.flags.Flags.toolkitSetFrameRateReadOnly;
 import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_FOCUS_CONTROLLER;
@@ -149,6 +150,8 @@
 import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.ResourcesManager;
+import android.app.UiModeManager;
+import android.app.UiModeManager.ForceInvertStateChangeListener;
 import android.app.WindowConfiguration;
 import android.app.compat.CompatChanges;
 import android.app.servertransaction.WindowStateTransactionItem;
@@ -164,7 +167,6 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
-import android.database.ContentObserver;
 import android.graphics.BLASTBufferQueue;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -210,7 +212,6 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.Vibrator;
-import android.provider.Settings;
 import android.sysprop.DisplayProperties;
 import android.sysprop.ViewProperties;
 import android.text.TextUtils;
@@ -463,10 +464,8 @@
     private CompatOnBackInvokedCallback mCompatOnBackInvokedCallback;
 
     @Nullable
-    private ContentObserver mForceInvertObserver;
+    private ForceInvertStateChangeListener mForceInvertStateChangeListener;
 
-    private static final int INVALID_VALUE = Integer.MIN_VALUE;
-    private int mForceInvertEnabled = INVALID_VALUE;
     /**
      * Callback for notifying about global configuration changes.
      */
@@ -543,6 +542,8 @@
     @UiContext
     public final Context mContext;
 
+    private UiModeManager mUiModeManager;
+
     @UnsupportedAppUsage
     final IWindowSession mWindowSession;
     @NonNull Display mDisplay;
@@ -1113,9 +1114,13 @@
     private boolean mIsFrameRateConflicted = false;
     // Used to check whether SurfaceControl has been replaced.
     private boolean mSurfaceReplaced = false;
+    // Indicates whether a draw operation occurred during this frame while a touch event was active.
+    private boolean mTouchAndDrawn = false;
     // Used to set frame rate compatibility.
     @Surface.FrameRateCompatibility int mFrameRateCompatibility =
             FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
+    // time for initial touch boost period.
+    private static final int FRAME_RATE_INITIAL_TOUCH_BOOST_TIME = 30;
     // time for touch boost period.
     private static final int FRAME_RATE_TOUCH_BOOST_TIME = 3000;
     // Timeout for the other frame rate boosts other than touch boost.
@@ -1213,6 +1218,7 @@
     private static boolean sSurfaceFlingerBugfixFlagValue =
             com.android.graphics.surfaceflinger.flags.Flags.vrrBugfix24q4();
     private static final boolean sEnableVrr = ViewProperties.vrr_enabled().orElse(true);
+    private static final boolean sToolkitInitialTouchBoostFlagValue = toolkitInitialTouchBoost();
 
     static {
         sToolkitSetFrameRateReadOnlyFlagValue = toolkitSetFrameRateReadOnly();
@@ -1238,6 +1244,7 @@
     public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session,
             WindowLayout windowLayout) {
         mContext = context;
+        mUiModeManager = context.getSystemService(UiModeManager.class);
         mWindowSession = session;
         mWindowLayout = windowLayout;
         mDisplay = display;
@@ -1781,23 +1788,6 @@
         }
     }
 
-    private boolean isForceInvertEnabled() {
-        if (mForceInvertEnabled == INVALID_VALUE) {
-            reloadForceInvertEnabled();
-        }
-        return mForceInvertEnabled == 1;
-    }
-
-    private void reloadForceInvertEnabled() {
-        if (forceInvertColor()) {
-            mForceInvertEnabled = Settings.Secure.getIntForUser(
-                    mContext.getContentResolver(),
-                    Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED,
-                    /* def= */ 0,
-                    UserHandle.myUserId());
-        }
-    }
-
     /**
      * Register any kind of listeners if setView was success.
      */
@@ -1829,21 +1819,11 @@
                         mBasePackageName);
 
         if (forceInvertColor()) {
-            if (mForceInvertObserver == null) {
-                mForceInvertObserver = new ContentObserver(mHandler) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        reloadForceInvertEnabled();
-                        updateForceDarkMode();
-                    }
-                };
-                mContext.getContentResolver().registerContentObserver(
-                        Settings.Secure.getUriFor(
-                                Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED
-                        ),
-                        false,
-                        mForceInvertObserver,
-                        UserHandle.myUserId());
+            if (mForceInvertStateChangeListener == null) {
+                mForceInvertStateChangeListener =
+                        forceInvertState -> updateForceDarkMode();
+                mUiModeManager.addForceInvertStateChangeListener(mExecutor,
+                        mForceInvertStateChangeListener);
             }
         }
     }
@@ -1861,9 +1841,10 @@
                 .unregisterDisplayListener(mDisplayListener);
 
         if (forceInvertColor()) {
-            if (mForceInvertObserver != null) {
-                mContext.getContentResolver().unregisterContentObserver(mForceInvertObserver);
-                mForceInvertObserver = null;
+            if (mForceInvertStateChangeListener != null) {
+                mUiModeManager.removeForceInvertStateChangeListener(
+                        mForceInvertStateChangeListener);
+                mForceInvertStateChangeListener = null;
             }
         }
 
@@ -2050,21 +2031,25 @@
         return getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
     }
 
-    /** Returns true if force dark should be enabled according to various settings */
+    /**
+     * Determines the type of force dark to apply, considering force inversion, system night mode,
+     * and app-specific settings (including developer opt-outs).
+     *
+     * @return A {@link ForceDarkType.ForceDarkTypeDef} constant indicating the force dark type.
+     */
     @VisibleForTesting
     public @ForceDarkType.ForceDarkTypeDef int determineForceDarkType() {
         if (forceInvertColor()) {
             // Force invert ignores all developer opt-outs.
             // We also ignore dark theme, since the app developer can override the user's preference
-            // for dark mode in configuration.uiMode. Instead, we assume that the force invert
-            // setting will be enabled at the same time dark theme is in the Settings app.
-            if (isForceInvertEnabled()) {
+            // for dark mode in configuration.uiMode. Instead, we assume that both force invert and
+            // the system's dark theme are enabled.
+            if (mUiModeManager.getForceInvertState() == UiModeManager.FORCE_INVERT_TYPE_DARK) {
                 return ForceDarkType.FORCE_INVERT_COLOR_DARK;
             }
         }
 
         boolean useAutoDark = getNightMode() == Configuration.UI_MODE_NIGHT_YES;
-
         if (useAutoDark) {
             boolean forceDarkAllowedDefault =
                     SystemProperties.getBoolean(ThreadedRenderer.DEBUG_FORCE_DARK, false);
@@ -4456,6 +4441,10 @@
         // We set the preferred frame rate and frame rate category at the end of performTraversals
         // when the values are applicable.
         if (mDrawnThisFrame) {
+            if (sToolkitInitialTouchBoostFlagValue && mIsTouchBoosting) {
+                mTouchAndDrawn = true;
+            }
+
             mDrawnThisFrame = false;
             if (!mInvalidationIdleMessagePosted && sSurfaceFlingerBugfixFlagValue) {
                 mInvalidationIdleMessagePosted = true;
@@ -6739,6 +6728,7 @@
     private static final int MSG_REFRESH_POINTER_ICON = 41;
     private static final int MSG_FRAME_RATE_SETTING = 42;
     private static final int MSG_SURFACE_REPLACED_TIMEOUT = 43;
+    private static final int MSG_INITIAL_TOUCH_BOOST_TIMEOUT = 44;
 
     final class ViewRootHandler extends Handler {
         @Override
@@ -6812,6 +6802,8 @@
                     return "MSG_FRAME_RATE_SETTING";
                 case MSG_SURFACE_REPLACED_TIMEOUT:
                     return "MSG_SURFACE_REPLACED_TIMEOUT";
+                case MSG_INITIAL_TOUCH_BOOST_TIMEOUT:
+                    return "MSG_INITIAL_TOUCH_BOOST_TIMEOUT";
             }
             return super.getMessageName(message);
         }
@@ -7087,6 +7079,17 @@
                         setPreferredFrameRateCategory(FRAME_RATE_CATEGORY_NO_PREFERENCE);
                     }
                     break;
+                case MSG_INITIAL_TOUCH_BOOST_TIMEOUT:
+                    if (mTouchAndDrawn) {
+                        mHandler.removeMessages(MSG_TOUCH_BOOST_TIMEOUT);
+                        mHandler.sendEmptyMessageDelayed(MSG_TOUCH_BOOST_TIMEOUT,
+                                FRAME_RATE_TOUCH_BOOST_TIME);
+                    } else {
+                        mIsTouchBoosting = false;
+                        setPreferredFrameRateCategory(FRAME_RATE_CATEGORY_NO_PREFERENCE);
+                    }
+                    mTouchAndDrawn = false;
+                    break;
                 case MSG_REFRESH_POINTER_ICON:
                     if (mPointerIconEvent == null) {
                         break;
@@ -8151,9 +8154,16 @@
              */
             if (mIsTouchBoosting && (action == MotionEvent.ACTION_UP
                     || action == MotionEvent.ACTION_CANCEL)) {
-                mHandler.removeMessages(MSG_TOUCH_BOOST_TIMEOUT);
-                mHandler.sendEmptyMessageDelayed(MSG_TOUCH_BOOST_TIMEOUT,
-                        FRAME_RATE_TOUCH_BOOST_TIME);
+
+                if (sToolkitInitialTouchBoostFlagValue) {
+                    mHandler.removeMessages(MSG_INITIAL_TOUCH_BOOST_TIMEOUT);
+                    mHandler.sendEmptyMessageDelayed(MSG_INITIAL_TOUCH_BOOST_TIMEOUT,
+                            FRAME_RATE_INITIAL_TOUCH_BOOST_TIME);
+                } else {
+                    mHandler.removeMessages(MSG_TOUCH_BOOST_TIMEOUT);
+                    mHandler.sendEmptyMessageDelayed(MSG_TOUCH_BOOST_TIMEOUT,
+                            FRAME_RATE_TOUCH_BOOST_TIME);
+                }
             }
             return handled ? FINISH_HANDLED : FORWARD;
         }
@@ -9339,6 +9349,16 @@
         return mVibrator;
     }
 
+    /**
+     * Clears the system vibrator.
+     *
+     * <p>This method releases the reference to the system vibrator. It's crucial to call this
+     * method when the vibrator is no longer needed to prevent any potential memory leaks.
+     */
+    public void clearSystemVibrator() {
+        mVibrator = null;
+    }
+
     private @Nullable AutofillManager getAutofillManager() {
         if (mView instanceof ViewGroup) {
             ViewGroup decorView = (ViewGroup) mView;
diff --git a/core/java/android/view/flags/refresh_rate_flags.aconfig b/core/java/android/view/flags/refresh_rate_flags.aconfig
index 675e5a1..3bc2205 100644
--- a/core/java/android/view/flags/refresh_rate_flags.aconfig
+++ b/core/java/android/view/flags/refresh_rate_flags.aconfig
@@ -136,4 +136,11 @@
     description: "Feature flag to not suppress touch boost for specific windowTypes in VRR V QPR2"
     bug: "335874198"
     is_exported: true
+}
+
+flag {
+    name: "toolkit_initial_touch_boost"
+    namespace: "toolkit"
+    description: "Feature flag to update initial touch boost logic"
+    bug: "393004744"
 }
\ No newline at end of file
diff --git a/core/java/android/view/inputmethod/ImeTracker.java b/core/java/android/view/inputmethod/ImeTracker.java
index 4d354e0..aa0111a 100644
--- a/core/java/android/view/inputmethod/ImeTracker.java
+++ b/core/java/android/view/inputmethod/ImeTracker.java
@@ -134,6 +134,7 @@
             ORIGIN_CLIENT,
             ORIGIN_SERVER,
             ORIGIN_IME,
+            ORIGIN_WM_SHELL,
     })
     @Retention(RetentionPolicy.SOURCE)
     @interface Origin {}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index ec0d915..0f5476f 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -10082,6 +10082,7 @@
         if (mApplication != null) {
             // mApplication may be null if this was created with DrawInstructions constructor.
             out.write(RemoteViewsProto.PACKAGE_NAME, mApplication.packageName);
+            out.write(RemoteViewsProto.UID, mApplication.uid);
         }
         Resources appResources = getContextForResourcesEnsuringCorrectCachedApkPaths(
                 context).getResources();
@@ -10163,6 +10164,7 @@
             int mApplyFlags = 0;
             long mProviderInstanceId = -1;
             String mPackageName = null;
+            Integer mUid = null;
             SizeF mIdealSize = null;
             String mLayoutResName = null;
             String mLightBackgroundResName = null;
@@ -10185,6 +10187,9 @@
                     case (int) RemoteViewsProto.PACKAGE_NAME:
                         ref.mPackageName = in.readString(RemoteViewsProto.PACKAGE_NAME);
                         break;
+                    case (int) RemoteViewsProto.UID:
+                        ref.mUid = in.readInt(RemoteViewsProto.UID);
+                        break;
                     case (int) RemoteViewsProto.IDEAL_SIZE:
                         final long idealSizeToken = in.start(RemoteViewsProto.IDEAL_SIZE);
                         ref.mIdealSize = createSizeFFromProto(in);
@@ -10286,8 +10291,9 @@
             Resources appResources = null;
             if (!ref.mHasDrawInstructions) {
                 checkProtoResultNotNull(ref.mPackageName, "No application info");
-                rv.mApplication = context.getPackageManager().getApplicationInfo(ref.mPackageName,
-                        /* flags= */ 0);
+                checkProtoResultNotNull(ref.mUid, "No uid");
+                rv.mApplication = context.getPackageManager().getApplicationInfoAsUser(
+                        ref.mPackageName, /* flags= */ 0, UserHandle.getUserId(ref.mUid));
                 appContext = rv.getContextForResourcesEnsuringCorrectCachedApkPaths(context);
                 appResources = appContext.getResources();
 
diff --git a/core/java/android/window/DesktopExperienceFlags.java b/core/java/android/window/DesktopExperienceFlags.java
index 7758dea..e0c48b0 100644
--- a/core/java/android/window/DesktopExperienceFlags.java
+++ b/core/java/android/window/DesktopExperienceFlags.java
@@ -40,9 +40,7 @@
  * @hide
  */
 public enum DesktopExperienceFlags {
-    ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT(
-            com.android.server.display.feature.flags.Flags::enableDisplayContentModeManagement,
-            true),
+    // go/keep-sorted start
     ACTIVITY_EMBEDDING_SUPPORT_FOR_CONNECTED_DISPLAYS(
             Flags::activityEmbeddingSupportForConnectedDisplays, false),
     BASE_DENSITY_FOR_EXTERNAL_DISPLAYS(
@@ -53,6 +51,9 @@
     ENABLE_CONNECTED_DISPLAYS_DND(Flags::enableConnectedDisplaysDnd, false),
     ENABLE_CONNECTED_DISPLAYS_PIP(Flags::enableConnectedDisplaysPip, false),
     ENABLE_CONNECTED_DISPLAYS_WINDOW_DRAG(Flags::enableConnectedDisplaysWindowDrag, false),
+    ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT(
+            com.android.server.display.feature.flags.Flags::enableDisplayContentModeManagement,
+            true),
     ENABLE_DISPLAY_FOCUS_IN_SHELL_TRANSITIONS(Flags::enableDisplayFocusInShellTransitions, false),
     ENABLE_DISPLAY_WINDOWING_MODE_SWITCHING(Flags::enableDisplayWindowingModeSwitching, false),
     ENABLE_DRAG_TO_MAXIMIZE(Flags::enableDragToMaximize, true),
@@ -63,9 +64,12 @@
             false),
     ENABLE_PER_DISPLAY_PACKAGE_CONTEXT_CACHE_IN_STATUSBAR_NOTIF(
             Flags::enablePerDisplayPackageContextCacheInStatusbarNotif, false),
+    ENABLE_TASKBAR_CONNECTED_DISPLAYS(Flags::enableTaskbarConnectedDisplays, false),
     ENTER_DESKTOP_BY_DEFAULT_ON_FREEFORM_DISPLAYS(Flags::enterDesktopByDefaultOnFreeformDisplays,
             false),
-    REPARENT_WINDOW_TOKEN_API(Flags::reparentWindowTokenApi, true);
+    REPARENT_WINDOW_TOKEN_API(Flags::reparentWindowTokenApi, true)
+    // go/keep-sorted end
+    ;
 
     /**
      * Flag class, to be used in case the enum cannot be used because the flag is not accessible.
diff --git a/core/java/android/window/DesktopModeFlags.java b/core/java/android/window/DesktopModeFlags.java
index 9468301..fa29f08 100644
--- a/core/java/android/window/DesktopModeFlags.java
+++ b/core/java/android/window/DesktopModeFlags.java
@@ -42,62 +42,73 @@
  */
 public enum DesktopModeFlags {
     // All desktop mode related flags to be overridden by developer option toggle will be added here
-    ENABLE_DESKTOP_WINDOWING_MODE(
-            Flags::enableDesktopWindowingMode, /* shouldOverrideByDevOption= */ true),
-    ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS(Flags::enableWindowingDynamicInitialBounds, true),
-    ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION(
-            Flags::enableCaptionCompatInsetForceConsumption, true),
+    // go/keep-sorted start
+    DISABLE_NON_RESIZABLE_APP_SNAP_RESIZE(Flags::disableNonResizableAppSnapResizing, true),
+    ENABLE_ACCESSIBLE_CUSTOM_HEADERS(Flags::enableAccessibleCustomHeaders, true),
+    ENABLE_APP_HEADER_WITH_TASK_DENSITY(Flags::enableAppHeaderWithTaskDensity, true),
+    ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION(Flags::enableCaptionCompatInsetForceConsumption,
+            true),
     ENABLE_CAPTION_COMPAT_INSET_FORCE_CONSUMPTION_ALWAYS(
             Flags::enableCaptionCompatInsetForceConsumptionAlways, true),
     ENABLE_CASCADING_WINDOWS(Flags::enableCascadingWindows, true),
-    ENABLE_TILE_RESIZING(Flags::enableTileResizing, true),
-    ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY(
-            Flags::enableDesktopWindowingWallpaperActivity, true),
-    ENABLE_DESKTOP_WINDOWING_MODALS_POLICY(Flags::enableDesktopWindowingModalsPolicy, true),
-    ENABLE_THEMED_APP_HEADERS(Flags::enableThemedAppHeaders, true),
-    ENABLE_HOLD_TO_DRAG_APP_HANDLE(Flags::enableHoldToDragAppHandle, true),
-    ENABLE_DESKTOP_WINDOWING_QUICK_SWITCH(Flags::enableDesktopWindowingQuickSwitch, true),
-    ENABLE_APP_HEADER_WITH_TASK_DENSITY(Flags::enableAppHeaderWithTaskDensity, true),
-    ENABLE_TASK_STACK_OBSERVER_IN_SHELL(Flags::enableTaskStackObserverInShell, true),
-    ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS(Flags::enableDesktopWindowingSizeConstraints, true),
-    DISABLE_NON_RESIZABLE_APP_SNAP_RESIZE(Flags::disableNonResizableAppSnapResizing, true),
-    ENABLE_WINDOWING_SCALED_RESIZING(Flags::enableWindowingScaledResizing, true),
-    ENABLE_DESKTOP_WINDOWING_TASK_LIMIT(Flags::enableDesktopWindowingTaskLimit, true),
-    ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION(Flags::enableDesktopWindowingBackNavigation, true),
-    ENABLE_WINDOWING_EDGE_DRAG_RESIZE(Flags::enableWindowingEdgeDragResize, true),
-    ENABLE_DESKTOP_WINDOWING_TASKBAR_RUNNING_APPS(
-            Flags::enableDesktopWindowingTaskbarRunningApps, true),
-    ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS(
-            Flags::enableWindowingTransitionHandlersObservers, false),
-    ENABLE_DESKTOP_WINDOWING_PERSISTENCE(Flags::enableDesktopWindowingPersistence, false),
-    ENABLE_HANDLE_INPUT_FIX(Flags::enableHandleInputFix, true),
-    ENABLE_DESKTOP_WINDOWING_ENTER_TRANSITIONS_BUGFIX(
-            Flags::enableDesktopWindowingEnterTransitionBugfix, true),
-    ENABLE_DESKTOP_WINDOWING_EXIT_TRANSITIONS_BUGFIX(
-            Flags::enableDesktopWindowingExitTransitionsBugfix, true),
     ENABLE_DESKTOP_APP_LAUNCH_ALTTAB_TRANSITIONS_BUGFIX(
             Flags::enableDesktopAppLaunchAlttabTransitionsBugfix, true),
-    ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS_BUGFIX(
-            Flags::enableDesktopAppLaunchTransitionsBugfix, true),
-    ENABLE_DESKTOP_COMPAT_UI_VISIBILITY_STATUS(
-            Flags::enableCompatUiVisibilityStatus, true),
-    ENABLE_DESKTOP_SKIP_COMPAT_UI_EDUCATION_IN_DESKTOP_MODE_BUGFIX(
-            Flags::skipCompatUiEducationInDesktopMode, true),
-    INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC(
-            Flags::includeTopTransparentFullscreenTaskInDesktopHeuristic, true),
-    ENABLE_DESKTOP_WINDOWING_HSUM(Flags::enableDesktopWindowingHsum, true),
-    ENABLE_MINIMIZE_BUTTON(Flags::enableMinimizeButton, true),
-    ENABLE_RESIZING_METRICS(Flags::enableResizingMetrics, true),
-    ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS(Flags::enableTaskResizingKeyboardShortcuts, true),
-    ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER(
-        Flags::enableDesktopWallpaperActivityForSystemUser, true),
-    ENABLE_TOP_VISIBLE_ROOT_TASK_PER_USER_TRACKING(
-        Flags::enableTopVisibleRootTaskPerUserTracking, true),
+    ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS_BUGFIX(Flags::enableDesktopAppLaunchTransitionsBugfix,
+            true),
+    ENABLE_DESKTOP_COMPAT_UI_VISIBILITY_STATUS(Flags::enableCompatUiVisibilityStatus, true),
     ENABLE_DESKTOP_RECENTS_TRANSITIONS_CORNERS_BUGFIX(
             Flags::enableDesktopRecentsTransitionsCornersBugfix, false),
+    ENABLE_DESKTOP_SKIP_COMPAT_UI_EDUCATION_IN_DESKTOP_MODE_BUGFIX(
+            Flags::skipCompatUiEducationInDesktopMode, true),
     ENABLE_DESKTOP_SYSTEM_DIALOGS_TRANSITIONS(Flags::enableDesktopSystemDialogsTransitions, true),
+    ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER(
+            Flags::enableDesktopWallpaperActivityForSystemUser, true),
+    ENABLE_DESKTOP_WINDOWING_APP_TO_WEB(Flags::enableDesktopWindowingAppToWeb, true),
+    ENABLE_DESKTOP_WINDOWING_APP_TO_WEB_EDUCATION(Flags::enableDesktopWindowingAppToWebEducation,
+            true),
+    ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION(Flags::enableDesktopWindowingBackNavigation, true),
+    ENABLE_DESKTOP_WINDOWING_ENTER_TRANSITIONS_BUGFIX(
+            Flags::enableDesktopWindowingEnterTransitionBugfix, true),
+    ENABLE_DESKTOP_WINDOWING_EXIT_BY_MINIMIZE_TRANSITION_BUGFIX(
+            Flags::enableDesktopWindowingExitByMinimizeTransitionBugfix, false),
+    ENABLE_DESKTOP_WINDOWING_EXIT_TRANSITIONS_BUGFIX(
+            Flags::enableDesktopWindowingExitTransitionsBugfix, true),
+    ENABLE_DESKTOP_WINDOWING_HSUM(Flags::enableDesktopWindowingHsum, true),
+    ENABLE_DESKTOP_WINDOWING_MODALS_POLICY(Flags::enableDesktopWindowingModalsPolicy, true),
+    ENABLE_DESKTOP_WINDOWING_MODE(Flags::enableDesktopWindowingMode, true),
     ENABLE_DESKTOP_WINDOWING_MULTI_INSTANCE_FEATURES(
-        Flags::enableDesktopWindowingMultiInstanceFeatures, true);
+            Flags::enableDesktopWindowingMultiInstanceFeatures, true),
+    ENABLE_DESKTOP_WINDOWING_PERSISTENCE(Flags::enableDesktopWindowingPersistence, true),
+    ENABLE_DESKTOP_WINDOWING_QUICK_SWITCH(Flags::enableDesktopWindowingQuickSwitch, true),
+    ENABLE_DESKTOP_WINDOWING_SCVH_CACHE(Flags::enableDesktopWindowingScvhCacheBugFix, true),
+    ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS(Flags::enableDesktopWindowingSizeConstraints, true),
+    ENABLE_DESKTOP_WINDOWING_TASKBAR_RUNNING_APPS(Flags::enableDesktopWindowingTaskbarRunningApps,
+            true),
+    ENABLE_DESKTOP_WINDOWING_TASK_LIMIT(Flags::enableDesktopWindowingTaskLimit, true),
+    ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY(Flags::enableDesktopWindowingWallpaperActivity,
+            true),
+    ENABLE_FULLY_IMMERSIVE_IN_DESKTOP(Flags::enableFullyImmersiveInDesktop, true),
+    ENABLE_HANDLE_INPUT_FIX(Flags::enableHandleInputFix, true),
+    ENABLE_HOLD_TO_DRAG_APP_HANDLE(Flags::enableHoldToDragAppHandle, true),
+    ENABLE_MINIMIZE_BUTTON(Flags::enableMinimizeButton, true),
+    ENABLE_RESIZING_METRICS(Flags::enableResizingMetrics, true),
+    ENABLE_RESTORE_TO_PREVIOUS_SIZE_FROM_DESKTOP_IMMERSIVE(
+            Flags::enableRestoreToPreviousSizeFromDesktopImmersive, true),
+    ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS(Flags::enableTaskResizingKeyboardShortcuts, true),
+    ENABLE_TASK_STACK_OBSERVER_IN_SHELL(Flags::enableTaskStackObserverInShell, true),
+    ENABLE_THEMED_APP_HEADERS(Flags::enableThemedAppHeaders, true),
+    ENABLE_TILE_RESIZING(Flags::enableTileResizing, true),
+    ENABLE_TOP_VISIBLE_ROOT_TASK_PER_USER_TRACKING(Flags::enableTopVisibleRootTaskPerUserTracking,
+            true),
+    ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS(Flags::enableWindowingDynamicInitialBounds, true),
+    ENABLE_WINDOWING_EDGE_DRAG_RESIZE(Flags::enableWindowingEdgeDragResize, true),
+    ENABLE_WINDOWING_SCALED_RESIZING(Flags::enableWindowingScaledResizing, true),
+    ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS(
+            Flags::enableWindowingTransitionHandlersObservers, false),
+    INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC(
+            Flags::includeTopTransparentFullscreenTaskInDesktopHeuristic, true)
+    // go/keep-sorted end
+    ;
 
     /**
      * Flag class, to be used in case the enum cannot be used because the flag is not accessible.
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index 68b5a26..1156503 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -1130,6 +1130,19 @@
     }
 
     /**
+     * Adds a hierarchy op for app compat reachability.
+     *
+     * @param container The token for the container Task
+     * @param taskId    The id of the current task
+     * @hide
+     */
+    public WindowContainerTransaction setReachabilityOffset(
+            @NonNull WindowContainerToken container, int taskId, int x, int y) {
+        mHierarchyOps.add(HierarchyOp.createForReachability(container.asBinder(), taskId, x, y));
+        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
@@ -1590,6 +1603,7 @@
         public static final int HIERARCHY_OP_TYPE_SET_KEYGUARD_STATE = 22;
         public static final int HIERARCHY_OP_TYPE_SET_DISABLE_LAUNCH_ADJACENT = 23;
         public static final int HIERARCHY_OP_TYPE_REMOVE_ROOT_TASK = 24;
+        public static final int HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY = 25;
 
         @IntDef(prefix = {"HIERARCHY_OP_TYPE_"}, value = {
                 HIERARCHY_OP_TYPE_REPARENT,
@@ -1617,6 +1631,7 @@
                 HIERARCHY_OP_TYPE_SET_KEYGUARD_STATE,
                 HIERARCHY_OP_TYPE_SET_DISABLE_LAUNCH_ADJACENT,
                 HIERARCHY_OP_TYPE_REMOVE_ROOT_TASK,
+                HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY,
         })
         @Retention(RetentionPolicy.SOURCE)
         public @interface HierarchyOpType {
@@ -1630,6 +1645,10 @@
         public static final String LAUNCH_KEY_SHORTCUT_CALLING_PACKAGE =
                 "android:transaction.hop.shortcut_calling_package";
 
+        // The following keys are used to define the reachability direction after a double tap.
+        public static final String REACHABILITY_EVENT_X = "android:transaction.reachability_x";
+        public static final String REACHABILITY_EVENT_Y = "android:transaction.reachability_y";
+
         @HierarchyOpType
         private final int mType;
 
@@ -1665,6 +1684,9 @@
         private Bundle mLaunchOptions;
 
         @Nullable
+        private Bundle mAppCompatOptions;
+
+        @Nullable
         private Intent mActivityIntent;
 
         /** Used as options for {@link #addTaskFragmentOperation}. */
@@ -1833,7 +1855,21 @@
                     .build();
         }
 
-        /** Creates a hierarchy op for setting a task non-trimmable by recents. */
+        /** Create a hierarchy op for app compat reachability. */
+        @NonNull
+        public static HierarchyOp createForReachability(IBinder container, int taskId, int x,
+                int y) {
+            final Bundle appCompatOptions = new Bundle();
+            appCompatOptions.putInt(LAUNCH_KEY_TASK_ID, taskId);
+            appCompatOptions.putInt(REACHABILITY_EVENT_X, x);
+            appCompatOptions.putInt(REACHABILITY_EVENT_Y, y);
+            return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY)
+                    .setAppCompatOptions(appCompatOptions)
+                    .setContainer(container)
+                    .build();
+        }
+
+        /** Create a hierarchy op for setting a task non-trimmable by recents. */
         @NonNull
         @FlaggedApi(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
         public static HierarchyOp createForSetTaskTrimmableFromRecents(@NonNull IBinder container,
@@ -1863,6 +1899,7 @@
             mWindowingModes = copy.mWindowingModes;
             mActivityTypes = copy.mActivityTypes;
             mLaunchOptions = copy.mLaunchOptions;
+            mAppCompatOptions = copy.mAppCompatOptions;
             mActivityIntent = copy.mActivityIntent;
             mTaskFragmentOperation = copy.mTaskFragmentOperation;
             mKeyguardState = copy.mKeyguardState;
@@ -1889,6 +1926,7 @@
             mWindowingModes = in.createIntArray();
             mActivityTypes = in.createIntArray();
             mLaunchOptions = in.readBundle();
+            mAppCompatOptions = in.readBundle(getClass().getClassLoader());
             mActivityIntent = in.readTypedObject(Intent.CREATOR);
             mTaskFragmentOperation = in.readTypedObject(TaskFragmentOperation.CREATOR);
             mKeyguardState = in.readTypedObject(KeyguardState.CREATOR);
@@ -1966,6 +2004,11 @@
         }
 
         @Nullable
+        public Bundle getAppCompatOptions() {
+            return mAppCompatOptions;
+        }
+
+        @Nullable
         public Intent getActivityIntent() {
             return mActivityIntent;
         }
@@ -2100,6 +2143,9 @@
                 case HIERARCHY_OP_TYPE_LAUNCH_TASK:
                     sb.append(mLaunchOptions);
                     break;
+                case HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY:
+                    sb.append(mAppCompatOptions);
+                    break;
                 case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT:
                     sb.append("container=").append(mContainer).append(" clearRoot=").append(mToTop);
                     break;
@@ -2182,6 +2228,7 @@
             dest.writeIntArray(mWindowingModes);
             dest.writeIntArray(mActivityTypes);
             dest.writeBundle(mLaunchOptions);
+            dest.writeBundle(mAppCompatOptions);
             dest.writeTypedObject(mActivityIntent, flags);
             dest.writeTypedObject(mTaskFragmentOperation, flags);
             dest.writeTypedObject(mKeyguardState, flags);
@@ -2245,6 +2292,9 @@
             private Bundle mLaunchOptions;
 
             @Nullable
+            private Bundle mAppCompatOptions;
+
+            @Nullable
             private Intent mActivityIntent;
 
             @Nullable
@@ -2328,6 +2378,11 @@
                 return this;
             }
 
+            Builder setAppCompatOptions(@Nullable Bundle appCompatOptions) {
+                mAppCompatOptions = appCompatOptions;
+                return this;
+            }
+
             Builder setActivityIntent(@Nullable Intent activityIntent) {
                 mActivityIntent = activityIntent;
                 return this;
@@ -2407,6 +2462,7 @@
                 hierarchyOp.mToTop = mToTop;
                 hierarchyOp.mReparentTopOnly = mReparentTopOnly;
                 hierarchyOp.mLaunchOptions = mLaunchOptions;
+                hierarchyOp.mAppCompatOptions = mAppCompatOptions;
                 hierarchyOp.mActivityIntent = mActivityIntent;
                 hierarchyOp.mPendingIntent = mPendingIntent;
                 hierarchyOp.mAlwaysOnTop = mAlwaysOnTop;
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index d20b067..ef0e94f 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -513,6 +513,13 @@
 }
 
 flag {
+    name: "enable_taskbar_connected_displays"
+    namespace: "lse_desktop_experience"
+    description: "Enables connected displays in taskbar."
+    bug: "393398093"
+}
+
+flag {
     name: "enable_bug_fixes_for_secondary_display"
     namespace: "lse_desktop_experience"
     description: "Bugfixes / papercuts to bring Desktop Windowing to secondary displays."
@@ -558,6 +565,13 @@
 }
 
 flag {
+    name: "enable_display_disconnect_interaction"
+    namespace: "lse_desktop_experience"
+    description: "Enables new interaction that occurs when a display is disconnected."
+    bug: "391652399"
+}
+
+flag {
     name: "show_desktop_experience_dev_option"
     namespace: "lse_desktop_experience"
     description: "Replace the freeform windowing dev options with a desktop experience one."
@@ -610,3 +624,27 @@
        purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "enable_desktop_taskbar_on_freeform_displays"
+    namespace: "lse_desktop_experience"
+    description: "Forces pinned taskbar with desktop tasks on freeform displays"
+    bug: "390665752"
+}
+
+flag {
+    name: "enable_presentation_for_connected_displays"
+    namespace: "lse_desktop_experience"
+    description: "Enables full support of presentation API for connected displays."
+    bug: "378503083"
+}
+
+flag {
+    name: "enable_full_screen_window_on_removing_split_screen_stage_bugfix"
+    namespace: "lse_desktop_experience"
+    description: "Enables clearing the windowing mode of a freeform window when removing the task from the split screen stage."
+    bug: "372791604"
+    metadata {
+       purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 9f6ea42..25dc672 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -460,4 +460,15 @@
     metadata {
         purpose: PURPOSE_BUGFIX
     }
+}
+
+flag {
+    name: "clear_system_vibrator"
+    namespace: "windowing_frontend"
+    description: "Clears the system vibrator before attaching new window, to avoid leaks."
+    bug: "393190314"
+    is_fixed_read_only: true
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
 }
\ No newline at end of file
diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig
index 1b946af..6f8852d 100644
--- a/core/java/android/window/flags/windowing_sdk.aconfig
+++ b/core/java/android/window/flags/windowing_sdk.aconfig
@@ -185,3 +185,14 @@
     description: "Enables letterboxing for a safe region"
     bug: "380132497"
 }
+
+flag {
+    namespace: "windowing_sdk"
+    name: "fix_layout_existing_task"
+    description: "Layout the existing task to ensure the bounds are updated."
+    bug: "390291971"
+    is_fixed_read_only: true
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/app/ChooserGridLayoutManager.java b/core/java/com/android/internal/app/ChooserGridLayoutManager.java
index c50ebd9..69d2abc 100644
--- a/core/java/com/android/internal/app/ChooserGridLayoutManager.java
+++ b/core/java/com/android/internal/app/ChooserGridLayoutManager.java
@@ -16,9 +16,20 @@
 
 package com.android.internal.app;
 
+import static android.service.chooser.Flags.announceShortcutsAndSuggestedAppsLegacy;
+
+import android.annotation.Nullable;
 import android.content.Context;
 import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
+import android.widget.GridView;
+import android.widget.TextView;
 
+import com.android.internal.R;
+import com.android.internal.app.ChooserActivity.ChooserGridAdapter;
 import com.android.internal.widget.GridLayoutManager;
 import com.android.internal.widget.RecyclerView;
 
@@ -28,6 +39,11 @@
  */
 public class ChooserGridLayoutManager extends GridLayoutManager {
 
+    private CharSequence mShortcutGroupTitle = "";
+    private CharSequence mSuggestedAppsGroupTitle = "";
+    private CharSequence mAllAppListGroupTitle = "";
+    @Nullable
+    private RecyclerView mRecyclerView;
     private boolean mVerticalScrollEnabled = true;
 
     /**
@@ -39,6 +55,9 @@
     public ChooserGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+        if (announceShortcutsAndSuggestedAppsLegacy()) {
+            readGroupTitles(context);
+        }
     }
 
     /**
@@ -49,6 +68,9 @@
      */
     public ChooserGridLayoutManager(Context context, int spanCount) {
         super(context, spanCount);
+        if (announceShortcutsAndSuggestedAppsLegacy()) {
+            readGroupTitles(context);
+        }
     }
 
     /**
@@ -61,6 +83,27 @@
     public ChooserGridLayoutManager(Context context, int spanCount, int orientation,
             boolean reverseLayout) {
         super(context, spanCount, orientation, reverseLayout);
+        if (announceShortcutsAndSuggestedAppsLegacy()) {
+            readGroupTitles(context);
+        }
+    }
+
+    private void readGroupTitles(Context context) {
+        mShortcutGroupTitle = context.getString(R.string.shortcut_group_a11y_title);
+        mSuggestedAppsGroupTitle = context.getString(R.string.suggested_apps_group_a11y_title);
+        mAllAppListGroupTitle = context.getString(R.string.all_apps_group_a11y_title);
+    }
+
+    @Override
+    public void onAttachedToWindow(RecyclerView view) {
+        super.onAttachedToWindow(view);
+        mRecyclerView = view;
+    }
+
+    @Override
+    public void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycler) {
+        super.onDetachedFromWindow(view, recycler);
+        mRecyclerView = null;
     }
 
     @Override
@@ -78,4 +121,89 @@
     public boolean canScrollVertically() {
         return mVerticalScrollEnabled && super.canScrollVertically();
     }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfoForItem(
+            RecyclerView.Recycler recycler,
+            RecyclerView.State state,
+            View host,
+            AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfoForItem(recycler, state, host, info);
+        if (announceShortcutsAndSuggestedAppsLegacy() && host instanceof ViewGroup) {
+            if (host.getId() == R.id.shortcuts_container) {
+                info.setClassName(GridView.class.getName());
+                info.setContainerTitle(mShortcutGroupTitle);
+                info.setCollectionInfo(createShortcutsA11yCollectionInfo((ViewGroup) host));
+            } else if (host.getId() == R.id.chooser_row) {
+                RecyclerView.Adapter adapter =
+                        mRecyclerView == null ? null : mRecyclerView.getAdapter();
+                ChooserListAdapter gridAdapter = adapter instanceof ChooserGridAdapter
+                        ? ((ChooserGridAdapter) adapter).getListAdapter()
+                        : null;
+                info.setClassName(GridView.class.getName());
+                info.setCollectionInfo(createSuggestedAppsA11yCollectionInfo((ViewGroup) host));
+                if (gridAdapter == null || gridAdapter.getAlphaTargetCount() > 0) {
+                    info.setContainerTitle(mSuggestedAppsGroupTitle);
+                } else {
+                    // if all applications fit into one row, they will be put into the suggested
+                    // applications group.
+                    info.setContainerTitle(mAllAppListGroupTitle);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(RecyclerView.Recycler recycler,
+            RecyclerView.State state, AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(recycler, state, info);
+        if (announceShortcutsAndSuggestedAppsLegacy()) {
+            info.setContainerTitle(mAllAppListGroupTitle);
+        }
+    }
+
+    @Override
+    public boolean isLayoutHierarchical(RecyclerView.Recycler recycler, RecyclerView.State state) {
+        return announceShortcutsAndSuggestedAppsLegacy()
+                || super.isLayoutHierarchical(recycler, state);
+    }
+
+    private CollectionInfo createShortcutsA11yCollectionInfo(ViewGroup container) {
+        int rowCount = 0;
+        int columnCount = 0;
+        for (int i = 0; i < container.getChildCount(); i++) {
+            View row = container.getChildAt(i);
+            int rowColumnCount = 0;
+            if (row instanceof ViewGroup rowGroup && row.getVisibility() == View.VISIBLE) {
+                for (int j = 0; j < rowGroup.getChildCount(); j++) {
+                    View v = rowGroup.getChildAt(j);
+                    if (v != null && v.getVisibility() == View.VISIBLE) {
+                        rowColumnCount++;
+                        if (v instanceof TextView) {
+                            // A special case of the no-targets message that also contains an
+                            // off-screen item (which looks like a bug).
+                            rowColumnCount = 1;
+                            break;
+                        }
+                    }
+                }
+            }
+            if (rowColumnCount > 0) {
+                rowCount++;
+                columnCount = Math.max(columnCount, rowColumnCount);
+            }
+        }
+        return CollectionInfo.obtain(rowCount, columnCount, false);
+    }
+
+    private CollectionInfo createSuggestedAppsA11yCollectionInfo(ViewGroup container) {
+        int columnCount = 0;
+        for (int i = 0; i < container.getChildCount(); i++) {
+            View v = container.getChildAt(i);
+            if (v.getVisibility() == View.VISIBLE) {
+                columnCount++;
+            }
+        }
+        return CollectionInfo.obtain(1, columnCount, false);
+    }
 }
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index e170d66..8c64750b 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -85,6 +85,8 @@
         final boolean extractNativeLibs;
         final boolean debuggable;
 
+        final boolean pageSizeCompatDisabled;
+
         public static Handle create(File packageFile) throws IOException {
             final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
             final ParseResult<PackageLite> ret = ApkLiteParseUtils.parsePackageLite(input.reset(),
@@ -97,12 +99,15 @@
         }
 
         public static Handle create(PackageLite lite) throws IOException {
+            boolean isPageSizeCompatDisabled = lite.getPageSizeCompat()
+                    == ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_MANIFEST_OVERRIDE_DISABLED;
             return create(lite.getAllApkPaths(), lite.isMultiArch(), lite.isExtractNativeLibs(),
-                    lite.isDebuggable());
+                    lite.isDebuggable(), isPageSizeCompatDisabled);
         }
 
         public static Handle create(List<String> codePaths, boolean multiArch,
-                boolean extractNativeLibs, boolean debuggable) throws IOException {
+                boolean extractNativeLibs, boolean debuggable, boolean isPageSizeCompatDisabled)
+                throws IOException {
             final int size = codePaths.size();
             final String[] apkPaths = new String[size];
             final long[] apkHandles = new long[size];
@@ -119,7 +124,8 @@
                 }
             }
 
-            return new Handle(apkPaths, apkHandles, multiArch, extractNativeLibs, debuggable);
+            return new Handle(apkPaths, apkHandles, multiArch, extractNativeLibs, debuggable,
+                    isPageSizeCompatDisabled);
         }
 
         public static Handle createFd(PackageLite lite, FileDescriptor fd) throws IOException {
@@ -130,17 +136,21 @@
                 throw new IOException("Unable to open APK " + path + " from fd " + fd);
             }
 
+            boolean isPageSizeCompatDisabled = lite.getPageSizeCompat()
+                    == ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_MANIFEST_OVERRIDE_DISABLED;
+
             return new Handle(new String[]{path}, apkHandles, lite.isMultiArch(),
-                    lite.isExtractNativeLibs(), lite.isDebuggable());
+                    lite.isExtractNativeLibs(), lite.isDebuggable(), isPageSizeCompatDisabled);
         }
 
         Handle(String[] apkPaths, long[] apkHandles, boolean multiArch,
-                boolean extractNativeLibs, boolean debuggable) {
+                boolean extractNativeLibs, boolean debuggable, boolean isPageSizeCompatDisabled) {
             this.apkPaths = apkPaths;
             this.apkHandles = apkHandles;
             this.multiArch = multiArch;
             this.extractNativeLibs = extractNativeLibs;
             this.debuggable = debuggable;
+            this.pageSizeCompatDisabled = isPageSizeCompatDisabled;
             mGuard.open("close");
         }
 
@@ -175,7 +185,8 @@
     private static native long nativeSumNativeBinaries(long handle, String cpuAbi);
 
     private native static int nativeCopyNativeBinaries(long handle, String sharedLibraryPath,
-            String abiToCopy, boolean extractNativeLibs, boolean debuggable);
+            String abiToCopy, boolean extractNativeLibs, boolean debuggable,
+            boolean pageSizeCompatDisabled);
 
     private static native int nativeCheckAlignment(
             long handle,
@@ -203,7 +214,7 @@
     public static int copyNativeBinaries(Handle handle, File sharedLibraryDir, String abi) {
         for (long apkHandle : handle.apkHandles) {
             int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi,
-                    handle.extractNativeLibs, handle.debuggable);
+                    handle.extractNativeLibs, handle.debuggable, handle.pageSizeCompatDisabled);
             if (res != INSTALL_SUCCEEDED) {
                 return res;
             }
diff --git a/core/java/com/android/internal/notification/NotificationChannelGroupsHelper.java b/core/java/com/android/internal/notification/NotificationChannelGroupsHelper.java
new file mode 100644
index 0000000..2bfb19f
--- /dev/null
+++ b/core/java/com/android/internal/notification/NotificationChannelGroupsHelper.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.notification;
+
+import static android.app.NotificationChannel.SYSTEM_RESERVED_IDS;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.INotificationManager;
+import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
+import android.service.notification.Flags;
+import android.util.ArrayMap;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * NotificationChannelGroupHelper contains helper methods for associating channels with the groups
+ * they belong to, matching by ID.
+ */
+public class NotificationChannelGroupsHelper {
+    /**
+     * Set of parameters passed into
+     * {@link NotificationChannelGroupsHelper#getGroupsWithChannels(Collection, Map, Params)}.
+     *
+     * @param includeDeleted Whether to include deleted channels.
+     * @param includeNonGrouped Whether to include channels that are not associated with a group.
+     * @param includeEmpty Whether to include groups containing no channels.
+     * @param includeAllBlockedWithFilter Whether to include channels that are blocked from
+     *                                    sending notifications along with channels specified by
+     *                                    the filter. This setting only takes effect when
+     *                                    channelFilter is not {@code null}, and if true will
+     *                                    include all blocked channels in the output (regardless
+     *                                    of whether they are included in the filter).
+     * @param channelFilter If non-null, a specific set of channels to include. If a channel
+     *                      matching this filter is blocked, it will still be included even
+     *                      if includeAllBlockedWithFilter=false.
+     */
+    public record Params(
+            boolean includeDeleted,
+            boolean includeNonGrouped,
+            boolean includeEmpty,
+            boolean includeAllBlockedWithFilter,
+            Set<String> channelFilter
+    ) {
+        /**
+         * Default set of parameters used to specify the behavior of
+         * {@link INotificationManager#getNotificationChannelGroups(String)}. This will include
+         * output for all groups, including those without channels, but not any ungrouped channels.
+         */
+        public static Params forAllGroups() {
+            return new Params(
+                    /* includeDeleted= */ false,
+                    /* includeNonGrouped= */ false,
+                    /* includeEmpty= */ true,
+                    /* includeAllBlockedWithFilter= */ true,
+                    /* channelFilter= */ null);
+        }
+
+        /**
+         * Parameters to get groups for all channels, including those not associated with any groups
+         * and optionally including deleted channels as well. Channels not associated with a group
+         * are returned inside a group with id {@code null}.
+         *
+         * @param includeDeleted Whether to include deleted channels.
+         */
+        public static Params forAllChannels(boolean includeDeleted) {
+            return new Params(
+                    includeDeleted,
+                    /* includeNonGrouped= */ true,
+                    /* includeEmpty= */ false,
+                    /* includeAllBlockedWithFilter= */ true,
+                    /* channelFilter= */ null);
+        }
+
+        /**
+         * Parameters to collect groups only for channels specified by the channel filter, as well
+         * as any blocked channels (independent of whether they exist in the filter).
+         * @param channelFilter Specific set of channels to return.
+         */
+        public static Params onlySpecifiedOrBlockedChannels(Set<String> channelFilter) {
+            return new Params(
+                    /* includeDeleted= */ false,
+                    /* includeNonGrouped= */ true,
+                    /* includeEmpty= */ false,
+                    /* includeAllBlockedWithFilter= */ true,
+                    channelFilter);
+        }
+    }
+
+    /**
+     * Retrieve the {@link NotificationChannelGroup} object specified by the given groupId, if it
+     * exists, with the list of channels filled in from the provided available channels.
+     *
+     * @param groupId The ID of the group to return.
+     * @param allChannels A list of all channels associated with the package.
+     * @param allGroups A map of group ID -> NotificationChannelGroup objects.
+     */
+    public static @Nullable NotificationChannelGroup getGroupWithChannels(@NonNull String groupId,
+            @NonNull Collection<NotificationChannel> allChannels,
+            @NonNull Map<String, NotificationChannelGroup> allGroups,
+            boolean includeDeleted) {
+        NotificationChannelGroup group = null;
+        if (allGroups.containsKey(groupId)) {
+            group = allGroups.get(groupId).clone();
+            group.setChannels(new ArrayList<>());
+            for (NotificationChannel nc : allChannels) {
+                if (includeDeleted || !nc.isDeleted()) {
+                    if (groupId.equals(nc.getGroup())) {
+                        group.addChannel(nc);
+                    }
+                }
+            }
+        }
+        return group;
+    }
+
+    /**
+     * Returns a list of groups with their associated channels filled in.
+     *
+     * @param allChannels All available channels that may be associated with these groups.
+     * @param allGroups Map of group ID -> {@link NotificationChannelGroup} objects.
+     * @param params Params indicating which channels and which groups to include.
+     */
+    public static @NonNull List<NotificationChannelGroup> getGroupsWithChannels(
+            @NonNull Collection<NotificationChannel> allChannels,
+            @NonNull Map<String, NotificationChannelGroup> allGroups,
+            Params params) {
+        Map<String, NotificationChannelGroup> outputGroups = new ArrayMap<>();
+        NotificationChannelGroup nonGrouped = new NotificationChannelGroup(null, null);
+        for (NotificationChannel nc : allChannels) {
+            boolean includeChannel = (params.includeDeleted || !nc.isDeleted())
+                    && (params.channelFilter == null
+                            || (params.includeAllBlockedWithFilter
+                                    && nc.getImportance() == IMPORTANCE_NONE)
+                            || params.channelFilter.contains(nc.getId()))
+                    && (!Flags.notificationClassification()
+                            || !SYSTEM_RESERVED_IDS.contains(nc.getId()));
+            if (includeChannel) {
+                if (nc.getGroup() != null) {
+                    if (allGroups.get(nc.getGroup()) != null) {
+                        NotificationChannelGroup ncg = outputGroups.get(nc.getGroup());
+                        if (ncg == null) {
+                            ncg = allGroups.get(nc.getGroup()).clone();
+                            ncg.setChannels(new ArrayList<>());
+                            outputGroups.put(nc.getGroup(), ncg);
+                        }
+                        ncg.addChannel(nc);
+                    }
+                } else {
+                    nonGrouped.addChannel(nc);
+                }
+            }
+        }
+        if (params.includeNonGrouped && nonGrouped.getChannels().size() > 0) {
+            outputGroups.put(null, nonGrouped);
+        }
+        if (params.includeEmpty) {
+            for (NotificationChannelGroup group : allGroups.values()) {
+                if (!outputGroups.containsKey(group.getId())) {
+                    outputGroups.put(group.getId(), group);
+                }
+            }
+        }
+        return new ArrayList<>(outputGroups.values());
+    }
+}
diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java
index f49c5f1..036faef 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistory.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistory.java
@@ -34,45 +34,38 @@
 import android.os.Parcel;
 import android.os.ParcelFormatException;
 import android.os.Process;
-import android.os.StatFs;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.util.ArraySet;
-import android.util.AtomicFile;
 import android.util.Slog;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.ConcurrentModificationException;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.concurrent.locks.ReentrantLock;
 
 /**
  * BatteryStatsHistory encapsulates battery history files.
  * Battery history record is appended into buffer {@link #mHistoryBuffer} and backed up into
- * {@link #mActiveFile}.
- * When {@link #mHistoryBuffer} size reaches {@link BatteryStatsImpl.Constants#MAX_HISTORY_BUFFER},
+ * {@link #mActiveFragment}.
+ * When {@link #mHistoryBuffer} size reaches {@link #mMaxHistoryBufferSize},
  * current mActiveFile is closed and a new mActiveFile is open.
  * History files are under directory /data/system/battery-history/.
- * History files have name battery-history-<num>.bin. The file number <num> starts from zero and
- * grows sequentially.
+ * History files have name &lt;num&gt;.bf. The file number &lt;num&gt; corresponds to the
+ * monotonic time when the file was started.
  * The mActiveFile is always the highest numbered history file.
  * The lowest number file is always the oldest file.
  * The highest number file is always the newest file.
- * The file number grows sequentially and we never skip number.
- * When count of history files exceeds {@link BatteryStatsImpl.Constants#MAX_HISTORY_FILES},
+ * The file number grows monotonically and we never skip number.
+ * When the total size of history files exceeds the maximum allowed value,
  * the lowest numbered file is deleted and a new file is open.
  *
  * All interfaces in BatteryStatsHistory should only be called by BatteryStatsImpl and protected by
@@ -86,10 +79,6 @@
     // Current on-disk Parcel version. Must be updated when the format of the parcelable changes
     private static final int VERSION = 212;
 
-    private static final String HISTORY_DIR = "battery-history";
-    private static final String FILE_SUFFIX = ".bh";
-    private static final int MIN_FREE_SPACE = 100 * 1024 * 1024;
-
     // Part of initial delta int that specifies the time delta.
     static final int DELTA_TIME_MASK = 0x7ffff;
     static final int DELTA_TIME_LONG = 0x7ffff;   // The delta is a following long
@@ -135,7 +124,7 @@
     // For state1, trace everything except the wakelock bit (which can race with
     // suspend) and the running bit (which isn't meaningful in traces).
     static final int STATE1_TRACE_MASK = ~(HistoryItem.STATE_WAKE_LOCK_FLAG
-                                          | HistoryItem.STATE_CPU_RUNNING_FLAG);
+            | HistoryItem.STATE_CPU_RUNNING_FLAG);
     // For state2, trace all bit changes.
     static final int STATE2_TRACE_MASK = ~0;
 
@@ -146,22 +135,132 @@
      */
     private static final int EXTRA_BUFFER_SIZE_WHEN_DIR_LOCKED = 100_000;
 
+    public abstract static class BatteryHistoryFragment
+            implements Comparable<BatteryHistoryFragment> {
+        public final long monotonicTimeMs;
+
+        public BatteryHistoryFragment(long monotonicTimeMs) {
+            this.monotonicTimeMs = monotonicTimeMs;
+        }
+
+        @Override
+        public int compareTo(BatteryHistoryFragment o) {
+            return Long.compare(monotonicTimeMs, o.monotonicTimeMs);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            return monotonicTimeMs == ((BatteryHistoryFragment) o).monotonicTimeMs;
+        }
+
+        @Override
+        public int hashCode() {
+            return Long.hashCode(monotonicTimeMs);
+        }
+    }
+
+    /**
+     * Persistent storage for battery history fragments
+     */
+    public interface BatteryHistoryStore {
+        /**
+         * Returns the table of contents, in the chronological order.
+         */
+        List<BatteryHistoryFragment> getFragments();
+
+        /**
+         * Returns the earliest available fragment
+         */
+        @Nullable
+        BatteryHistoryFragment getEarliestFragment();
+
+        /**
+         * Returns the latest available fragment
+         */
+        @Nullable
+        BatteryHistoryFragment getLatestFragment();
+
+        /**
+         * Given a fragment, returns the earliest fragment that follows it whose monotonic
+         * start time falls within the specified range. `startTimeMs` is inclusive, `endTimeMs`
+         * is exclusive.
+         */
+        @Nullable
+        BatteryHistoryFragment getNextFragment(BatteryHistoryFragment current, long startTimeMs,
+                long endTimeMs);
+
+        /**
+         * Acquires a lock on the entire store.
+         */
+        void lock();
+
+        /**
+         * Acquires a lock unless the store is already locked by a different thread. Returns true
+         * if the lock has been successfully acquired.
+         */
+        boolean tryLock();
+
+        /**
+         * Unlocks the store.
+         */
+        void unlock();
+
+        /**
+         * Returns true if the store is currently locked.
+         */
+        boolean isLocked();
+
+        /**
+         * Returns the total amount of storage occupied by history fragments, in bytes.
+         */
+        int getSize();
+
+        /**
+         * Returns true if the store contains any history fragments, excluding the currently
+         * active partial fragment.
+         */
+        boolean hasCompletedFragments();
+
+        /**
+         * Creates a new empty history fragment starting at the specified time.
+         */
+        BatteryHistoryFragment createFragment(long monotonicStartTime);
+
+        /**
+         * Writes a fragment to disk as raw bytes.
+         *
+         * @param fragmentComplete indicates if this fragment is done or still partial.
+         */
+        void writeFragment(BatteryHistoryFragment fragment, @NonNull byte[] bytes,
+                boolean fragmentComplete);
+
+        /**
+         * Reads a fragment as raw bytes.
+         */
+        @Nullable
+        byte[] readFragment(BatteryHistoryFragment fragment);
+
+        /**
+         * Removes all persistent fragments
+         */
+        void reset();
+    }
+
     private final Parcel mHistoryBuffer;
-    private final File mSystemDir;
     private final HistoryStepDetailsCalculator mStepDetailsCalculator;
     private final Clock mClock;
 
     private int mMaxHistoryBufferSize;
 
     /**
-     * The active history file that the history buffer is backed up into.
+     * The active history fragment that the history buffer is backed up into.
      */
-    private AtomicFile mActiveFile;
+    private BatteryHistoryFragment mActiveFragment;
 
     /**
-     * A list of history files with increasing timestamps.
+     * Persistent storage of history files.
      */
-    private final BatteryHistoryDirectory mHistoryDir;
+    private final BatteryHistoryStore mStore;
 
     /**
      * A list of small history parcels, used when BatteryStatsImpl object is created from
@@ -172,7 +271,7 @@
     /**
      * When iterating history files, the current file index.
      */
-    private BatteryHistoryFile mCurrentFile;
+    private BatteryHistoryFragment mCurrentFragment;
 
     /**
      * When iterating history files, the current file parcel.
@@ -221,326 +320,6 @@
     private int mIteratorCookie;
     private final BatteryStatsHistory mWritableHistory;
 
-    private static class BatteryHistoryFile implements Comparable<BatteryHistoryFile> {
-        public final long monotonicTimeMs;
-        public final AtomicFile atomicFile;
-
-        private BatteryHistoryFile(File directory, long monotonicTimeMs) {
-            this.monotonicTimeMs = monotonicTimeMs;
-            atomicFile = new AtomicFile(new File(directory, monotonicTimeMs + FILE_SUFFIX));
-        }
-
-        @Override
-        public int compareTo(BatteryHistoryFile o) {
-            return Long.compare(monotonicTimeMs, o.monotonicTimeMs);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            return monotonicTimeMs == ((BatteryHistoryFile) o).monotonicTimeMs;
-        }
-
-        @Override
-        public int hashCode() {
-            return Long.hashCode(monotonicTimeMs);
-        }
-
-        @Override
-        public String toString() {
-            return atomicFile.getBaseFile().toString();
-        }
-    }
-
-    private static class BatteryHistoryDirectory {
-        private final File mDirectory;
-        private final MonotonicClock mMonotonicClock;
-        private int mMaxHistorySize;
-        private final List<BatteryHistoryFile> mHistoryFiles = new ArrayList<>();
-        private final ReentrantLock mLock = new ReentrantLock();
-        private boolean mCleanupNeeded;
-
-        BatteryHistoryDirectory(File directory, MonotonicClock monotonicClock, int maxHistorySize) {
-            mDirectory = directory;
-            mMonotonicClock = monotonicClock;
-            mMaxHistorySize = maxHistorySize;
-            if (mMaxHistorySize == 0) {
-                Slog.w(TAG, "mMaxHistorySize should not be zero when writing history");
-            }
-        }
-
-        void setMaxHistorySize(int maxHistorySize) {
-            mMaxHistorySize = maxHistorySize;
-            cleanup();
-        }
-
-        void lock() {
-            mLock.lock();
-        }
-
-        boolean tryLock() {
-            return mLock.tryLock();
-        }
-
-        void unlock() {
-            mLock.unlock();
-            if (mCleanupNeeded) {
-                cleanup();
-            }
-        }
-
-        boolean isLocked() {
-            return mLock.isLocked();
-        }
-
-        void load() {
-            Trace.asyncTraceBegin(TRACE_TAG_SYSTEM_SERVER, "BatteryStatsHistory.load", 0);
-            mDirectory.mkdirs();
-            if (!mDirectory.exists()) {
-                Slog.wtf(TAG, "HistoryDir does not exist:" + mDirectory.getPath());
-            }
-
-            final List<File> toRemove = new ArrayList<>();
-            final Set<BatteryHistoryFile> dedup = new ArraySet<>();
-            mDirectory.listFiles((dir, name) -> {
-                final int b = name.lastIndexOf(FILE_SUFFIX);
-                if (b <= 0) {
-                    toRemove.add(new File(dir, name));
-                    return false;
-                }
-                try {
-                    long monotonicTime = Long.parseLong(name.substring(0, b));
-                    dedup.add(new BatteryHistoryFile(mDirectory, monotonicTime));
-                } catch (NumberFormatException e) {
-                    toRemove.add(new File(dir, name));
-                    return false;
-                }
-                return true;
-            });
-            if (!dedup.isEmpty()) {
-                mHistoryFiles.addAll(dedup);
-                Collections.sort(mHistoryFiles);
-            }
-            if (!toRemove.isEmpty()) {
-                // Clear out legacy history files, which did not follow the X-Y.bin naming format.
-                BackgroundThread.getHandler().post(() -> {
-                    lock();
-                    try {
-                        for (File file : toRemove) {
-                            file.delete();
-                        }
-                    } finally {
-                        unlock();
-                        Trace.asyncTraceEnd(TRACE_TAG_SYSTEM_SERVER, "BatteryStatsHistory.load", 0);
-                    }
-                });
-            } else {
-                Trace.asyncTraceEnd(TRACE_TAG_SYSTEM_SERVER, "BatteryStatsHistory.load", 0);
-            }
-        }
-
-        List<String> getFileNames() {
-            lock();
-            try {
-                List<String> names = new ArrayList<>();
-                for (BatteryHistoryFile historyFile : mHistoryFiles) {
-                    names.add(historyFile.atomicFile.getBaseFile().getName());
-                }
-                return names;
-            } finally {
-                unlock();
-            }
-        }
-
-        @Nullable
-        BatteryHistoryFile getFirstFile() {
-            lock();
-            try {
-                if (!mHistoryFiles.isEmpty()) {
-                    return mHistoryFiles.get(0);
-                }
-                return null;
-            } finally {
-                unlock();
-            }
-        }
-
-        @Nullable
-        BatteryHistoryFile getLastFile() {
-            lock();
-            try {
-                if (!mHistoryFiles.isEmpty()) {
-                    return mHistoryFiles.get(mHistoryFiles.size() - 1);
-                }
-                return null;
-            } finally {
-                unlock();
-            }
-        }
-
-        @Nullable
-        BatteryHistoryFile getNextFile(BatteryHistoryFile current, long startTimeMs,
-                long endTimeMs) {
-            if (!mLock.isHeldByCurrentThread()) {
-                throw new IllegalStateException("Iterating battery history without a lock");
-            }
-
-            int nextFileIndex = 0;
-            int firstFileIndex = 0;
-            // skip the last file because its data is in history buffer.
-            int lastFileIndex = mHistoryFiles.size() - 2;
-            for (int i = lastFileIndex; i >= 0; i--) {
-                BatteryHistoryFile file = mHistoryFiles.get(i);
-                if (current != null && file.monotonicTimeMs == current.monotonicTimeMs) {
-                    nextFileIndex = i + 1;
-                }
-                if (file.monotonicTimeMs > endTimeMs) {
-                    lastFileIndex = i - 1;
-                }
-                if (file.monotonicTimeMs <= startTimeMs) {
-                    firstFileIndex = i;
-                    break;
-                }
-            }
-
-            if (nextFileIndex < firstFileIndex) {
-                nextFileIndex = firstFileIndex;
-            }
-
-            if (nextFileIndex <= lastFileIndex) {
-                return mHistoryFiles.get(nextFileIndex);
-            }
-
-            return null;
-        }
-
-        BatteryHistoryFile makeBatteryHistoryFile() {
-            BatteryHistoryFile file = new BatteryHistoryFile(mDirectory,
-                    mMonotonicClock.monotonicTime());
-            lock();
-            try {
-                mHistoryFiles.add(file);
-            } finally {
-                unlock();
-            }
-            return file;
-        }
-
-        void writeToParcel(Parcel out, boolean useBlobs,
-                long preferredEarliestIncludedTimestampMs) {
-            Trace.traceBegin(TRACE_TAG_SYSTEM_SERVER, "BatteryStatsHistory.writeToParcel");
-            lock();
-            try {
-                final long start = SystemClock.uptimeMillis();
-                for (int i = 0; i < mHistoryFiles.size() - 1; i++) {
-                    long monotonicEndTime = Long.MAX_VALUE;
-                    if (i < mHistoryFiles.size() - 1) {
-                        monotonicEndTime = mHistoryFiles.get(i + 1).monotonicTimeMs;
-                    }
-
-                    if (monotonicEndTime < preferredEarliestIncludedTimestampMs) {
-                        continue;
-                    }
-
-                    AtomicFile file = mHistoryFiles.get(i).atomicFile;
-                    byte[] raw = new byte[0];
-                    try {
-                        raw = file.readFully();
-                    } catch (Exception e) {
-                        Slog.e(TAG, "Error reading file " + file.getBaseFile().getPath(), e);
-                    }
-
-                    out.writeBoolean(true);
-                    if (useBlobs) {
-                        out.writeBlob(raw);
-                    } else {
-                        // Avoiding blobs in the check-in file for compatibility
-                        out.writeByteArray(raw);
-                    }
-                }
-                out.writeBoolean(false);
-                if (DEBUG) {
-                    Slog.d(TAG,
-                            "writeToParcel duration ms:" + (SystemClock.uptimeMillis() - start));
-                }
-            } finally {
-                unlock();
-                Trace.traceEnd(TRACE_TAG_SYSTEM_SERVER);
-            }
-        }
-
-        int getFileCount() {
-            lock();
-            try {
-                return mHistoryFiles.size();
-            } finally {
-                unlock();
-            }
-        }
-
-        int getSize() {
-            lock();
-            try {
-                int ret = 0;
-                for (int i = 0; i < mHistoryFiles.size() - 1; i++) {
-                    ret += (int) mHistoryFiles.get(i).atomicFile.getBaseFile().length();
-                }
-                return ret;
-            } finally {
-                unlock();
-            }
-        }
-
-        void reset() {
-            lock();
-            try {
-                if (DEBUG) Slog.i(TAG, "********** CLEARING HISTORY!");
-                for (BatteryHistoryFile file : mHistoryFiles) {
-                    file.atomicFile.delete();
-                }
-                mHistoryFiles.clear();
-            } finally {
-                unlock();
-            }
-        }
-
-        private void cleanup() {
-            Trace.traceBegin(TRACE_TAG_SYSTEM_SERVER, "BatteryStatsHistory.cleanup");
-            try {
-                if (mDirectory == null) {
-                    return;
-                }
-
-                if (!tryLock()) {
-                    mCleanupNeeded = true;
-                    return;
-                }
-
-                mCleanupNeeded = false;
-                try {
-                    // if free disk space is less than 100MB, delete oldest history file.
-                    if (!hasFreeDiskSpace(mDirectory)) {
-                        BatteryHistoryFile oldest = mHistoryFiles.remove(0);
-                        oldest.atomicFile.delete();
-                    }
-
-                    // if there is more history stored than allowed, delete oldest history files.
-                    int size = getSize();
-                    while (size > mMaxHistorySize) {
-                        BatteryHistoryFile oldest = mHistoryFiles.get(0);
-                        int length = (int) oldest.atomicFile.getBaseFile().length();
-                        oldest.atomicFile.delete();
-                        mHistoryFiles.remove(0);
-                        size -= length;
-                    }
-                } finally {
-                    unlock();
-                }
-            } finally {
-                Trace.traceEnd(TRACE_TAG_SYSTEM_SERVER);
-            }
-        }
-    }
-
     /**
      * A delegate responsible for computing additional details for a step in battery history.
      */
@@ -621,24 +400,22 @@
     /**
      * Constructor
      *
-     * @param systemDir            typically /data/system
-     * @param maxHistorySize       the largest amount of battery history to keep on disk
      * @param maxHistoryBufferSize the most amount of RAM to used for buffering of history steps
      */
-    public BatteryStatsHistory(Parcel historyBuffer, File systemDir,
-            int maxHistorySize, int maxHistoryBufferSize,
-            HistoryStepDetailsCalculator stepDetailsCalculator, Clock clock,
-            MonotonicClock monotonicClock, TraceDelegate tracer, EventLogger eventLogger) {
-        this(historyBuffer, systemDir, maxHistorySize, maxHistoryBufferSize, stepDetailsCalculator,
+    public BatteryStatsHistory(Parcel historyBuffer, int maxHistoryBufferSize,
+            @Nullable BatteryHistoryStore store, HistoryStepDetailsCalculator stepDetailsCalculator,
+            Clock clock, MonotonicClock monotonicClock, TraceDelegate tracer,
+            EventLogger eventLogger) {
+        this(historyBuffer, maxHistoryBufferSize, store,
+                stepDetailsCalculator,
                 clock, monotonicClock, tracer, eventLogger, null);
     }
 
-    private BatteryStatsHistory(@Nullable Parcel historyBuffer, @Nullable File systemDir,
-            int maxHistorySize, int maxHistoryBufferSize,
+    private BatteryStatsHistory(@Nullable Parcel historyBuffer, int maxHistoryBufferSize,
+            @Nullable BatteryHistoryStore store,
             @NonNull HistoryStepDetailsCalculator stepDetailsCalculator, @NonNull Clock clock,
             @NonNull MonotonicClock monotonicClock, @NonNull TraceDelegate tracer,
             @NonNull EventLogger eventLogger, @Nullable BatteryStatsHistory writableHistory) {
-        mSystemDir = systemDir;
         mMaxHistoryBufferSize = maxHistoryBufferSize;
         mStepDetailsCalculator = stepDetailsCalculator;
         mTracer = tracer;
@@ -659,18 +436,16 @@
         }
 
         if (writableHistory != null) {
-            mHistoryDir = writableHistory.mHistoryDir;
-        } else if (systemDir != null) {
-            mHistoryDir = new BatteryHistoryDirectory(new File(systemDir, HISTORY_DIR),
-                    monotonicClock, maxHistorySize);
-            mHistoryDir.load();
-            BatteryHistoryFile activeFile = mHistoryDir.getLastFile();
-            if (activeFile == null) {
-                activeFile = mHistoryDir.makeBatteryHistoryFile();
-            }
-            setActiveFile(activeFile);
+            mStore = writableHistory.mStore;
         } else {
-            mHistoryDir = null;
+            mStore = store;
+            if (mStore != null) {
+                BatteryHistoryFragment activeFile = mStore.getLatestFragment();
+                if (activeFile == null) {
+                    activeFile = mStore.createFragment(mMonotonicClock.monotonicTime());
+                }
+                setActiveFragment(activeFile);
+            }
         }
     }
 
@@ -681,8 +456,7 @@
     private BatteryStatsHistory(Parcel parcel) {
         mClock = Clock.SYSTEM_CLOCK;
         mTracer = null;
-        mSystemDir = null;
-        mHistoryDir = null;
+        mStore = null;
         mStepDetailsCalculator = null;
         mEventLogger = new EventLogger();
         mWritableHistory = null;
@@ -718,15 +492,6 @@
     }
 
     /**
-     * Changes the maximum amount of history to be kept on disk.
-     */
-    public void setMaxHistorySize(int maxHistorySize) {
-        if (mHistoryDir != null) {
-            mHistoryDir.setMaxHistorySize(maxHistorySize);
-        }
-    }
-
-    /**
      * Changes the maximum size of the history buffer, in bytes.
      */
     public void setMaxHistoryBufferSize(int maxHistoryBufferSize) {
@@ -745,8 +510,8 @@
                 Parcel historyBufferCopy = Parcel.obtain();
                 historyBufferCopy.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
 
-                return new BatteryStatsHistory(historyBufferCopy, mSystemDir, 0, 0, null, null,
-                        null, null, mEventLogger, this);
+                return new BatteryStatsHistory(historyBufferCopy, 0, mStore, null,
+                        null, null, null, mEventLogger, this);
             }
         } finally {
             Trace.traceEnd(TRACE_TAG_SYSTEM_SERVER);
@@ -757,45 +522,40 @@
      * Returns true if this instance only supports reading history.
      */
     public boolean isReadOnly() {
-        return !mMutable || mActiveFile == null/* || mHistoryDir == null*/;
+        return !mMutable || mActiveFragment == null || mStore == null;
     }
 
     /**
      * Set the active file that mHistoryBuffer is backed up into.
      */
-    private void setActiveFile(BatteryHistoryFile file) {
-        mActiveFile = file.atomicFile;
+    private void setActiveFragment(BatteryHistoryFragment file) {
+        mActiveFragment = file;
         if (DEBUG) {
-            Slog.d(TAG, "activeHistoryFile:" + mActiveFile.getBaseFile().getPath());
+            Slog.d(TAG, "activeHistoryFile:" + mActiveFragment);
         }
     }
 
     /**
-     * When {@link #mHistoryBuffer} reaches {@link BatteryStatsImpl.Constants#MAX_HISTORY_BUFFER},
-     * create next history file.
+     * When {@link #mHistoryBuffer} reaches {@link #mMaxHistoryBufferSize},
+     * create next history fragment.
      */
-    public void startNextFile(long elapsedRealtimeMs) {
+    public void startNextFragment(long elapsedRealtimeMs) {
         synchronized (this) {
-            startNextFileLocked(elapsedRealtimeMs);
+            startNextFragmentLocked(elapsedRealtimeMs);
         }
     }
 
     @GuardedBy("this")
-    private void startNextFileLocked(long elapsedRealtimeMs) {
+    private void startNextFragmentLocked(long elapsedRealtimeMs) {
         final long start = SystemClock.uptimeMillis();
-        writeHistory();
+        writeHistory(true /* fragmentComplete */);
         if (DEBUG) {
             Slog.d(TAG, "writeHistory took ms:" + (SystemClock.uptimeMillis() - start));
         }
 
-        setActiveFile(mHistoryDir.makeBatteryHistoryFile());
-        try {
-            mActiveFile.getBaseFile().createNewFile();
-        } catch (IOException e) {
-            Slog.e(TAG, "Could not create history file: " + mActiveFile.getBaseFile());
-        }
-
-        mHistoryBufferStartTime = mMonotonicClock.monotonicTime(elapsedRealtimeMs);
+        long monotonicStartTime = mMonotonicClock.monotonicTime(elapsedRealtimeMs);
+        setActiveFragment(mStore.createFragment(monotonicStartTime));
+        mHistoryBufferStartTime = monotonicStartTime;
         mHistoryBuffer.setDataSize(0);
         mHistoryBuffer.setDataPosition(0);
         mHistoryBuffer.setDataCapacity(mMaxHistoryBufferSize / 2);
@@ -810,7 +570,6 @@
         }
 
         mWrittenPowerStatsDescriptors.clear();
-        mHistoryDir.cleanup();
     }
 
     /**
@@ -818,7 +577,7 @@
      * currently being read.
      */
     public boolean isResetEnabled() {
-        return mHistoryDir == null || !mHistoryDir.isLocked();
+        return mStore == null || !mStore.isLocked();
     }
 
     /**
@@ -827,11 +586,11 @@
      */
     public void reset() {
         synchronized (this) {
-            if (mHistoryDir != null) {
-                mHistoryDir.reset();
-                setActiveFile(mHistoryDir.makeBatteryHistoryFile());
-            }
             initHistoryBuffer();
+            if (mStore != null) {
+                mStore.reset();
+                setActiveFragment(mStore.createFragment(mHistoryBufferStartTime));
+            }
         }
     }
 
@@ -840,9 +599,9 @@
      */
     public long getStartTime() {
         synchronized (this) {
-            BatteryHistoryFile file = mHistoryDir.getFirstFile();
-            if (file != null) {
-                return file.monotonicTimeMs;
+            BatteryHistoryFragment firstFragment = mStore.getEarliestFragment();
+            if (firstFragment != null) {
+                return firstFragment.monotonicTimeMs;
             } else {
                 return mHistoryBufferStartTime;
             }
@@ -863,10 +622,10 @@
             return copy().iterate(startTimeMs, endTimeMs);
         }
 
-        if (mHistoryDir != null) {
-            mHistoryDir.lock();
+        if (mStore != null) {
+            mStore.lock();
         }
-        mCurrentFile = null;
+        mCurrentFragment = null;
         mCurrentParcel = null;
         mCurrentParcelEnd = 0;
         mParcelIndex = 0;
@@ -883,8 +642,8 @@
      */
     void iteratorFinished() {
         mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
-        if (mHistoryDir != null) {
-            mHistoryDir.unlock();
+        if (mStore != null) {
+            mStore.unlock();
         }
         Trace.asyncTraceEnd(TRACE_TAG_SYSTEM_SERVER, "BatteryStatsHistory.iterate",
                 mIteratorCookie);
@@ -918,27 +677,26 @@
             }
         }
 
-        if (mHistoryDir != null) {
-            BatteryHistoryFile nextFile = mHistoryDir.getNextFile(mCurrentFile, startTimeMs,
+        if (mStore != null) {
+            BatteryHistoryFragment next = mStore.getNextFragment(mCurrentFragment, startTimeMs,
                     endTimeMs);
-            while (nextFile != null) {
+            while (next != null) {
                 mCurrentParcel = null;
                 mCurrentParcelEnd = 0;
                 final Parcel p = Parcel.obtain();
-                AtomicFile file = nextFile.atomicFile;
-                if (readFileToParcel(p, file)) {
+                if (readFragmentToParcel(p, next)) {
                     int bufSize = p.readInt();
                     int curPos = p.dataPosition();
                     mCurrentParcelEnd = curPos + bufSize;
                     mCurrentParcel = p;
                     if (curPos < mCurrentParcelEnd) {
-                        mCurrentFile = nextFile;
+                        mCurrentFragment = next;
                         return mCurrentParcel;
                     }
                 } else {
                     p.recycle();
                 }
-                nextFile = mHistoryDir.getNextFile(nextFile, startTimeMs, endTimeMs);
+                next = mStore.getNextFragment(next, startTimeMs, endTimeMs);
             }
         }
 
@@ -988,39 +746,26 @@
      * Read history file into a parcel.
      *
      * @param out  the Parcel read into.
-     * @param file the File to read from.
+     * @param fragment the fragment to read from.
      * @return true if success, false otherwise.
      */
-    public boolean readFileToParcel(Parcel out, AtomicFile file) {
-        Trace.traceBegin(TRACE_TAG_SYSTEM_SERVER, "BatteryStatsHistory.read");
-        try {
-            byte[] raw = null;
-            try {
-                final long start = SystemClock.uptimeMillis();
-                raw = file.readFully();
-                if (DEBUG) {
-                    Slog.d(TAG, "readFileToParcel:" + file.getBaseFile().getPath()
-                            + " duration ms:" + (SystemClock.uptimeMillis() - start));
-                }
-            } catch (Exception e) {
-                Slog.e(TAG, "Error reading file " + file.getBaseFile().getPath(), e);
-                return false;
-            }
-            out.unmarshall(raw, 0, raw.length);
-            out.setDataPosition(0);
-            if (!verifyVersion(out)) {
-                return false;
-            }
-            // skip monotonic time field.
-            out.readLong();
-            // skip monotonic end time field
-            out.readLong();
-            // skip monotonic size field
-            out.readLong();
-            return true;
-        } finally {
-            Trace.traceEnd(TRACE_TAG_SYSTEM_SERVER);
+    public boolean readFragmentToParcel(Parcel out, BatteryHistoryFragment fragment) {
+        byte[] data = mStore.readFragment(fragment);
+        if (data == null) {
+            return false;
         }
+        out.unmarshall(data, 0, data.length);
+        out.setDataPosition(0);
+        if (!verifyVersion(out)) {
+            return false;
+        }
+        // skip monotonic time field.
+        out.readLong();
+        // skip monotonic end time field
+        out.readLong();
+        // skip monotonic size field
+        out.readLong();
+        return true;
     }
 
     /**
@@ -1106,9 +851,8 @@
     public void writeToParcel(Parcel out) {
         synchronized (this) {
             writeHistoryBuffer(out);
-            /* useBlobs */
-            if (mHistoryDir != null) {
-                mHistoryDir.writeToParcel(out, false /* useBlobs */, 0);
+            if (mStore != null) {
+                writeToParcel(out, false /* useBlobs */, 0);
             }
         }
     }
@@ -1122,13 +866,54 @@
     public void writeToBatteryUsageStatsParcel(Parcel out, long preferredHistoryDurationMs) {
         synchronized (this) {
             out.writeBlob(mHistoryBuffer.marshall());
-            if (mHistoryDir != null) {
-                mHistoryDir.writeToParcel(out, true /* useBlobs */,
+            if (mStore != null) {
+                writeToParcel(out, true /* useBlobs */,
                         mHistoryMonotonicEndTime - preferredHistoryDurationMs);
             }
         }
     }
 
+    private void writeToParcel(Parcel out, boolean useBlobs,
+            long preferredEarliestIncludedTimestampMs) {
+        Trace.traceBegin(TRACE_TAG_SYSTEM_SERVER, "BatteryStatsHistory.writeToParcel");
+        mStore.lock();
+        try {
+            final long start = SystemClock.uptimeMillis();
+            List<BatteryHistoryFragment> fragments = mStore.getFragments();
+            for (int i = 0; i < fragments.size() - 1; i++) {
+                long monotonicEndTime = Long.MAX_VALUE;
+                if (i < fragments.size() - 1) {
+                    monotonicEndTime = fragments.get(i + 1).monotonicTimeMs;
+                }
+
+                if (monotonicEndTime < preferredEarliestIncludedTimestampMs) {
+                    continue;
+                }
+
+                byte[] data = mStore.readFragment(fragments.get(i));
+                if (data == null) {
+                    Slog.e(TAG, "Error reading history fragment " + fragments.get(i));
+                    continue;
+                }
+
+                out.writeBoolean(true);
+                if (useBlobs) {
+                    out.writeBlob(data, 0, data.length);
+                } else {
+                    // Avoiding blobs in the check-in file for compatibility
+                    out.writeByteArray(data, 0, data.length);
+                }
+            }
+            out.writeBoolean(false);
+            if (DEBUG) {
+                Slog.d(TAG, "writeToParcel duration ms:" + (SystemClock.uptimeMillis() - start));
+            }
+        } finally {
+            mStore.unlock();
+            Trace.traceEnd(TRACE_TAG_SYSTEM_SERVER);
+        }
+    }
+
     /**
      * Reads a BatteryStatsHistory from a parcel written with
      * the {@link #writeToBatteryUsageStatsParcel} method.
@@ -1141,28 +926,21 @@
      * Read history from a check-in file.
      */
     public boolean readSummary() {
-        if (mActiveFile == null) {
+        if (mActiveFragment == null) {
             Slog.w(TAG, "readSummary: no history file associated with this instance");
             return false;
         }
 
         Parcel parcel = Parcel.obtain();
         try {
-            final long start = SystemClock.uptimeMillis();
-            if (mActiveFile.exists()) {
-                byte[] raw = mActiveFile.readFully();
-                if (raw.length > 0) {
-                    parcel.unmarshall(raw, 0, raw.length);
-                    parcel.setDataPosition(0);
-                    readHistoryBuffer(parcel);
-                }
-                if (DEBUG) {
-                    Slog.d(TAG, "read history file::"
-                            + mActiveFile.getBaseFile().getPath()
-                            + " bytes:" + raw.length + " took ms:" + (SystemClock.uptimeMillis()
-                            - start));
-                }
+            byte[] data = mStore.readFragment(mActiveFragment);
+            if (data == null) {
+                return false;
             }
+
+            parcel.unmarshall(data, 0, data.length);
+            parcel.setDataPosition(0);
+            readHistoryBuffer(parcel);
         } catch (Exception e) {
             Slog.e(TAG, "Error reading battery history", e);
             reset();
@@ -1201,41 +979,21 @@
         }
     }
 
-    /**
-     * @return true if there is more than 100MB free disk space left.
-     */
-    @android.ravenwood.annotation.RavenwoodReplace
-    private static boolean hasFreeDiskSpace(File systemDir) {
-        final StatFs stats = new StatFs(systemDir.getAbsolutePath());
-        return stats.getAvailableBytes() > MIN_FREE_SPACE;
-    }
-
-    private static boolean hasFreeDiskSpace$ravenwood(File systemDir) {
-        return true;
+    @VisibleForTesting
+    public BatteryHistoryStore getBatteryHistoryStore() {
+        return mStore;
     }
 
     @VisibleForTesting
-    public List<String> getFilesNames() {
-        return mHistoryDir.getFileNames();
-    }
-
-    @VisibleForTesting
-    public AtomicFile getActiveFile() {
-        return mActiveFile;
-    }
-
-    /**
-     * Returns the maximum storage size allocated to battery history.
-     */
-    public int getMaxHistorySize() {
-        return mHistoryDir.mMaxHistorySize;
+    public BatteryHistoryFragment getActiveFragment() {
+        return mActiveFragment;
     }
 
     /**
      * @return the total size of all history files and history buffer.
      */
     public int getHistoryUsedSize() {
-        int ret = mHistoryDir.getSize();
+        int ret = mStore.getSize();
         ret += mHistoryBuffer.dataSize();
         if (mHistoryParcels != null) {
             for (int i = 0; i < mHistoryParcels.size(); i++) {
@@ -1293,7 +1051,7 @@
      */
     public void continueRecordingHistory() {
         synchronized (this) {
-            if (mHistoryBuffer.dataPosition() <= 0 && mHistoryDir.getFileCount() <= 1) {
+            if (mHistoryBuffer.dataPosition() <= 0 && !mStore.hasCompletedFragments()) {
                 return;
             }
 
@@ -1852,7 +1610,7 @@
         }
 
         final long timeDiffMs = mMonotonicClock.monotonicTime(elapsedRealtimeMs)
-                                - mHistoryLastWritten.time;
+                - mHistoryLastWritten.time;
         final int diffStates = mHistoryLastWritten.states ^ cur.states;
         final int diffStates2 = mHistoryLastWritten.states2 ^ cur.states2;
         final int lastDiffStates = mHistoryLastWritten.states ^ mHistoryLastLastWritten.states;
@@ -1953,7 +1711,7 @@
             mMaxHistoryBufferSize = 1024;
         }
 
-        boolean successfullyLocked = mHistoryDir.tryLock();
+        boolean successfullyLocked = mStore.tryLock();
         if (!successfullyLocked) {      // Already locked by another thread
             // If the buffer size is below the allowed overflow limit, just keep going
             if (dataSize < mMaxHistoryBufferSize + EXTRA_BUFFER_SIZE_WHEN_DIR_LOCKED) {
@@ -1971,10 +1729,10 @@
         copy.setTo(cur);
 
         try {
-            startNextFile(elapsedRealtimeMs);
+            startNextFragment(elapsedRealtimeMs);
         } finally {
             if (successfullyLocked) {
-                mHistoryDir.unlock();
+                mStore.unlock();
             }
         }
 
@@ -2095,6 +1853,7 @@
         Battery charge int: if F in the first token is set, an int representing the battery charge
         in coulombs follows.
      */
+
     /**
      * Writes the delta between the previous and current history items into history buffer.
      */
@@ -2376,9 +2135,13 @@
     }
 
     /**
-     * Saves the accumulated history buffer in the active file, see {@link #getActiveFile()} .
+     * Saves the accumulated history buffer in the active file, see {@link #getActiveFragment()} .
      */
     public void writeHistory() {
+        writeHistory(false /* fragmentComplete */);
+    }
+
+    private void writeHistory(boolean fragmentComplete) {
         synchronized (this) {
             if (isReadOnly()) {
                 Slog.w(TAG, "writeHistory: this instance instance is read-only");
@@ -2397,7 +2160,7 @@
                     Slog.d(TAG, "writeHistoryBuffer duration ms:"
                             + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize());
                 }
-                writeParcelToFileLocked(p, mActiveFile);
+                writeParcelLocked(p, mActiveFragment, fragmentComplete);
             } finally {
                 p.recycle();
             }
@@ -2457,30 +2220,18 @@
     }
 
     @GuardedBy("this")
-    private void writeParcelToFileLocked(Parcel p, AtomicFile file) {
-        FileOutputStream fos = null;
+    private void writeParcelLocked(Parcel p, BatteryHistoryFragment fragment,
+            boolean fragmentComplete) {
         mWriteLock.lock();
         try {
             final long startTimeMs = SystemClock.uptimeMillis();
-            fos = file.startWrite();
-            fos.write(p.marshall());
-            fos.flush();
-            file.finishWrite(fos);
-            if (DEBUG) {
-                Slog.d(TAG, "writeParcelToFileLocked file:" + file.getBaseFile().getPath()
-                        + " duration ms:" + (SystemClock.uptimeMillis() - startTimeMs)
-                        + " bytes:" + p.dataSize());
-            }
+            mStore.writeFragment(fragment, p.marshall(), fragmentComplete);
             mEventLogger.writeCommitSysConfigFile(startTimeMs);
-        } catch (IOException e) {
-            Slog.w(TAG, "Error writing battery statistics", e);
-            file.failWrite(fos);
         } finally {
             mWriteLock.unlock();
         }
     }
 
-
     /**
      * Returns the total number of history tags in the tag pool.
      */
diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
index 5c08dc6..db60e12 100644
--- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
@@ -29,7 +29,6 @@
 import static android.os.Build.VERSION_CODES.DONUT;
 import static android.os.Build.VERSION_CODES.O;
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
-import static android.sdk.Flags.majorMinorVersioningScheme;
 
 import static com.android.internal.pm.pkg.parsing.ParsingUtils.parseKnownActivityEmbeddingCerts;
 
@@ -1690,21 +1689,6 @@
                     targetCode = minCode;
                 }
 
-                if (majorMinorVersioningScheme()) {
-                    val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_minSdkVersionFull);
-                    if (val != null) {
-                        if (val.type == TypedValue.TYPE_STRING && val.string != null) {
-                            String minSdkVersionFullString = val.string.toString();
-                            ParseResult<Void> minSdkVersionFullResult =
-                                    FrameworkParsingPackageUtils.verifyMinSdkVersionFull(
-                                        minSdkVersionFullString, Build.VERSION.SDK_INT_FULL, input);
-                            if (minSdkVersionFullResult.isError()) {
-                                return input.error(minSdkVersionFullResult);
-                            }
-                        }
-                    }
-                }
-
                 if (isApkInApex) {
                     val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_maxSdkVersion);
                     if (val != null) {
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 6c00921..d73e2d4 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -436,6 +436,9 @@
             if (viewRoot != null) {
                 // Clear the old callbacks and attach to the new window.
                 viewRoot.getOnBackInvokedDispatcher().clear();
+                if (Flags.clearSystemVibrator()) {
+                    viewRoot.clearSystemVibrator();
+                }
                 onViewRootImplSet(viewRoot);
             }
         }
@@ -478,8 +481,6 @@
     public static boolean isOptingOutEdgeToEdgeEnforcement(ApplicationInfo info, boolean local,
             TypedArray windowStyle) {
         final boolean disabled = Flags.disableOptOutEdgeToEdge()
-                // TODO (b/377864165): Don't exclude system apps after they are ready.
-                && !info.isSystemApp()
                 && (local
                         // Calling this doesn't require a permission.
                         ? CompatChanges.isChangeEnabled(DISABLE_OPT_OUT_EDGE_TO_EDGE)
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 04ce9bc..9a5849a 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -86,8 +86,6 @@
     public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
     public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
     public static final Interpolator OVERSHOOT = new PathInterpolator(0.4f, 0f, 0.2f, 1.4f);
-    public static final OnLayoutChangeListener MESSAGING_PROPERTY_ANIMATOR
-            = new MessagingPropertyAnimator();
     public static final int IMPORTANCE_ANIM_GROW_DURATION = 250;
     public static final int IMPORTANCE_ANIM_SHRINK_DURATION = 200;
     public static final int IMPORTANCE_ANIM_SHRINK_DELAY = 25;
@@ -96,13 +94,13 @@
     private List<MessagingMessage> mHistoricMessages = new ArrayList<>();
     private MessagingLinearLayout mMessagingLinearLayout;
     private boolean mShowHistoricMessages;
-    private ArrayList<MessagingGroup> mGroups = new ArrayList<>();
+    private final ArrayList<MessagingGroup> mGroups = new ArrayList<>();
     private int mLayoutColor;
     private int mSenderTextColor;
     private int mMessageTextColor;
     private Icon mAvatarReplacement;
     private boolean mIsOneToOne;
-    private ArrayList<MessagingGroup> mAddedGroups = new ArrayList<>();
+    private final ArrayList<MessagingGroup> mAddedGroups = new ArrayList<>();
     private Person mUser;
     private CharSequence mNameReplacement;
     private CharSequence mSummarizedContent;
@@ -163,8 +161,8 @@
     private Icon mConversationIcon;
     private Icon mShortcutIcon;
     private View mAppNameDivider;
-    private TouchDelegateComposite mTouchDelegate = new TouchDelegateComposite(this);
-    private ArrayList<MessagingLinearLayout.MessagingChild> mToRecycle = new ArrayList<>();
+    private final TouchDelegateComposite mTouchDelegate = new TouchDelegateComposite(this);
+    private final ArrayList<MessagingLinearLayout.MessagingChild> mToRecycle = new ArrayList<>();
     private boolean mPrecomputedTextEnabled = false;
     @Nullable
     private ConversationHeaderData mConversationHeaderData;
@@ -440,9 +438,8 @@
         // mUser now set (would be nice to avoid the side effect but WHATEVER)
         final Person user = extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON, Person.class);
         // Append remote input history to newMessages (again, side effect is lame but WHATEVS)
-        RemoteInputHistoryItem[] history = (RemoteInputHistoryItem[])
-                extras.getParcelableArray(Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS,
-                        RemoteInputHistoryItem.class);
+        RemoteInputHistoryItem[] history = extras.getParcelableArray(
+                Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, RemoteInputHistoryItem.class);
         addRemoteInputHistoryToMessages(newMessages, history);
 
         boolean showSpinner =
@@ -547,7 +544,7 @@
         for (int i = remoteInputHistory.length - 1; i >= 0; i--) {
             RemoteInputHistoryItem historyMessage = remoteInputHistory[i];
             Notification.MessagingStyle.Message message = new Notification.MessagingStyle.Message(
-                    historyMessage.getText(), 0, (Person) null, true /* remoteHistory */);
+                    historyMessage.getText(), 0, null, true /* remoteHistory */);
             if (historyMessage.getUri() != null) {
                 message.setData(historyMessage.getMimeType(), historyMessage.getUri());
             }
@@ -718,11 +715,11 @@
 
     private void updateImageMessages() {
         View newMessage = null;
-        if (mIsCollapsed && mGroups.size() > 0) {
+        if (mIsCollapsed && !mGroups.isEmpty()) {
 
             // When collapsed, we're displaying the image message in a dedicated container
             // on the right of the layout instead of inline. Let's add the isolated image there
-            MessagingGroup messagingGroup = mGroups.get(mGroups.size() - 1);
+            MessagingGroup messagingGroup = mGroups.getLast();
             MessagingImageMessage isolatedMessage = messagingGroup.getIsolatedMessage();
             if (isolatedMessage != null) {
                 newMessage = isolatedMessage.getView();
@@ -1234,7 +1231,7 @@
                 final Person sender = message.getSenderPerson();
                 final CharSequence senderKey = getKey(sender);
                 if ((sender != null && senderKey != userKey) || i == 0) {
-                    if (conversationText == null || conversationText.length() == 0) {
+                    if (conversationText == null || conversationText.isEmpty()) {
                         conversationText = sender != null ? sender.getName() : "";
                     }
                     if (conversationIcon == null) {
diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java
index d000596..5d19070 100644
--- a/core/java/com/android/internal/widget/MessagingLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLayout.java
@@ -46,7 +46,6 @@
 import android.widget.RemoteViews;
 
 import com.android.internal.R;
-import com.android.internal.util.ContrastColorUtil;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -60,7 +59,6 @@
 public class MessagingLayout extends FrameLayout
         implements ImageMessageConsumer, IMessagingLayout {
 
-    private static final float COLOR_SHIFT_AMOUNT = 60;
     public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f);
     public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
     public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
@@ -71,7 +69,7 @@
     private List<MessagingMessage> mHistoricMessages = new ArrayList<>();
     private MessagingLinearLayout mMessagingLinearLayout;
     private boolean mShowHistoricMessages;
-    private ArrayList<MessagingGroup> mGroups = new ArrayList<>();
+    private final ArrayList<MessagingGroup> mGroups = new ArrayList<>();
     private MessagingLinearLayout mImageMessageContainer;
     private ImageView mRightIconView;
     private Rect mMessagingClipRect;
@@ -80,14 +78,15 @@
     private int mMessageTextColor;
     private Icon mAvatarReplacement;
     private boolean mIsOneToOne;
-    private ArrayList<MessagingGroup> mAddedGroups = new ArrayList<>();
+    private final ArrayList<MessagingGroup> mAddedGroups = new ArrayList<>();
     private Person mUser;
     private CharSequence mNameReplacement;
     private boolean mIsCollapsed;
     private ImageResolver mImageResolver;
     private CharSequence mConversationTitle;
-    private ArrayList<MessagingLinearLayout.MessagingChild> mToRecycle = new ArrayList<>();
+    private final ArrayList<MessagingLinearLayout.MessagingChild> mToRecycle = new ArrayList<>();
     private boolean mPrecomputedTextEnabled = false;
+
     public MessagingLayout(@NonNull Context context) {
         super(context);
     }
@@ -175,10 +174,8 @@
                 Notification.MessagingStyle.Message.getMessagesFromBundleArray(histMessages);
         setUser(extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON,
                 Person.class));
-        RemoteInputHistoryItem[] history =
-                (RemoteInputHistoryItem[]) extras.getParcelableArray(
-                        Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS,
-                        RemoteInputHistoryItem.class);
+        RemoteInputHistoryItem[] history = extras.getParcelableArray(
+                Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, RemoteInputHistoryItem.class);
         addRemoteInputHistoryToMessages(newMessages, history);
 
         final Person user = extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON, Person.class);
@@ -251,7 +248,7 @@
         for (int i = remoteInputHistory.length - 1; i >= 0; i--) {
             RemoteInputHistoryItem historyMessage = remoteInputHistory[i];
             Notification.MessagingStyle.Message message = new Notification.MessagingStyle.Message(
-                    historyMessage.getText(), 0, (Person) null, true /* remoteHistory */);
+                    historyMessage.getText(), 0, null, true /* remoteHistory */);
             if (historyMessage.getUri() != null) {
                 message.setData(historyMessage.getMimeType(), historyMessage.getUri());
             }
@@ -302,7 +299,7 @@
         if (mIsCollapsed && !mGroups.isEmpty()) {
             // When collapsed, we're displaying the image message in a dedicated container
             // on the right of the layout instead of inline. Let's add the isolated image there
-            MessagingGroup messagingGroup = mGroups.get(mGroups.size() - 1);
+            MessagingGroup messagingGroup = mGroups.getLast();
             MessagingImageMessage isolatedMessage = messagingGroup.getIsolatedMessage();
             if (isolatedMessage != null) {
                 newMessage = isolatedMessage.getView();
@@ -398,26 +395,6 @@
         return mPeopleHelper.createAvatarSymbol(senderName, symbol, layoutColor);
     }
 
-    private int findColor(CharSequence senderName, int layoutColor) {
-        double luminance = ContrastColorUtil.calculateLuminance(layoutColor);
-        float shift = Math.abs(senderName.hashCode()) % 5 / 4.0f - 0.5f;
-
-        // we need to offset the range if the luminance is too close to the borders
-        shift += Math.max(COLOR_SHIFT_AMOUNT / 2.0f / 100 - luminance, 0);
-        shift -= Math.max(COLOR_SHIFT_AMOUNT / 2.0f / 100 - (1.0f - luminance), 0);
-        return ContrastColorUtil.getShiftedColor(layoutColor,
-                (int) (shift * COLOR_SHIFT_AMOUNT));
-    }
-
-    private String findNameSplit(String existingName) {
-        String[] split = existingName.split(" ");
-        if (split.length > 1) {
-            return Character.toString(split[0].charAt(0))
-                    + Character.toString(split[1].charAt(0));
-        }
-        return existingName.substring(0, 1);
-    }
-
     @RemotableViewMethod
     public void setLayoutColor(int color) {
         mLayoutColor = color;
diff --git a/core/jni/android_view_SurfaceControlActivePictureListener.cpp b/core/jni/android_view_SurfaceControlActivePictureListener.cpp
index 15132db..ee8efe1 100644
--- a/core/jni/android_view_SurfaceControlActivePictureListener.cpp
+++ b/core/jni/android_view_SurfaceControlActivePictureListener.cpp
@@ -106,11 +106,13 @@
     }
 
     status_t startListening() {
-        return SurfaceComposerClient::addActivePictureListener(this);
+        return SurfaceComposerClient::addActivePictureListener(
+                sp<SurfaceControlActivePictureListener>::fromExisting(this));
     }
 
     status_t stopListening() {
-        return SurfaceComposerClient::removeActivePictureListener(this);
+        return SurfaceComposerClient::removeActivePictureListener(
+                sp<SurfaceControlActivePictureListener>::fromExisting(this));
     }
 
 protected:
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index e78c524..06fd80e 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -273,6 +273,7 @@
     jboolean extractNativeLibs = *(jboolean*)args[1];
     jboolean debuggable = *(jboolean*)args[2];
     jboolean app_compat_16kb = *(jboolean*)args[3];
+    jboolean pageSizeCompatDisabled = *(jboolean*)args[4];
     install_status_t ret = INSTALL_SUCCEEDED;
 
     ScopedUtfChars nativeLibPath(env, *javaNativeLibPath);
@@ -304,6 +305,16 @@
         }
 
         if (offset % kPageSize != 0) {
+            // If page size app compat was disabled explicitly in manifest, don't extract libs on
+            // 16 KB page size device.
+            if (kPageSize == 0x4000 && pageSizeCompatDisabled) {
+                ALOGE("pageSizeCompat=disabled library '%s' is not PAGE(%zu)-"
+                      "aligned within apk (APK alignment, not ELF alignment) -"
+                      "and will not be extracted.\n",
+                      fileName, kPageSize);
+                return INSTALL_FAILED_INVALID_APK;
+            }
+
             // If the library is zip-aligned correctly for 4kb devices and app compat is
             // enabled, on 16kb devices fallback to extraction
             if (offset % 0x1000 == 0 && app_compat_16kb) {
@@ -537,13 +548,12 @@
     return !android::base::GetBoolProperty("pm.16kb.app_compat.disabled", false);
 }
 
-static jint
-com_android_internal_content_NativeLibraryHelper_copyNativeBinaries(JNIEnv *env, jclass clazz,
-        jlong apkHandle, jstring javaNativeLibPath, jstring javaCpuAbi,
-        jboolean extractNativeLibs, jboolean debuggable)
-{
+static jint com_android_internal_content_NativeLibraryHelper_copyNativeBinaries(
+        JNIEnv* env, jclass clazz, jlong apkHandle, jstring javaNativeLibPath, jstring javaCpuAbi,
+        jboolean extractNativeLibs, jboolean debuggable, jboolean pageSizeCompatDisabled) {
     jboolean app_compat_16kb = app_compat_16kb_enabled();
-    void* args[] = { &javaNativeLibPath, &extractNativeLibs, &debuggable, &app_compat_16kb };
+    void* args[] = {&javaNativeLibPath, &extractNativeLibs, &debuggable, &app_compat_16kb,
+                    &pageSizeCompatDisabled};
     return (jint) iterateOverNativeFiles(env, apkHandle, javaCpuAbi,
             copyFileIfChanged, reinterpret_cast<void*>(args));
 }
@@ -804,7 +814,7 @@
         {"nativeOpenApkFd", "(Ljava/io/FileDescriptor;Ljava/lang/String;)J",
          (void*)com_android_internal_content_NativeLibraryHelper_openApkFd},
         {"nativeClose", "(J)V", (void*)com_android_internal_content_NativeLibraryHelper_close},
-        {"nativeCopyNativeBinaries", "(JLjava/lang/String;Ljava/lang/String;ZZ)I",
+        {"nativeCopyNativeBinaries", "(JLjava/lang/String;Ljava/lang/String;ZZZ)I",
          (void*)com_android_internal_content_NativeLibraryHelper_copyNativeBinaries},
         {"nativeSumNativeBinaries", "(JLjava/lang/String;)J",
          (void*)com_android_internal_content_NativeLibraryHelper_sumNativeBinaries},
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 407790c..a673ad7 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -399,6 +399,7 @@
     optional bool should_override_force_resize_app = 44;
     optional bool should_enable_user_aspect_ratio_settings = 45;
     optional bool is_user_fullscreen_override_enabled = 46;
+    optional int64 request_open_in_browser_education_timestamp = 47;
 }
 
 /* represents WindowToken */
diff --git a/core/proto/android/widget/remoteviews.proto b/core/proto/android/widget/remoteviews.proto
index 6a987a4..91dbf7b 100644
--- a/core/proto/android/widget/remoteviews.proto
+++ b/core/proto/android/widget/remoteviews.proto
@@ -57,6 +57,7 @@
     repeated bytes bitmap_cache = 14;
     optional RemoteCollectionCache remote_collection_cache = 15;
     repeated Action actions = 16;
+    optional int32 uid = 17;
 
     message RemoteCollectionCache {
         message Entry {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 005c14d..c9f4cdc 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -8446,6 +8446,14 @@
                 android:protectionLevel="signature"
                 android:featureFlag="com.android.hardware.input.manage_key_gestures" />
 
+    <!-- Allows applications to register listeners for key activeness through
+         InputManagerService.
+         <p>Protection level: signature
+         @hide -->
+    <permission android:name="android.permission.LISTEN_FOR_KEY_ACTIVITY"
+                android:protectionLevel="signature"
+                android:featureFlag="com.android.hardware.input.key_event_activity_detection" />
+
     <uses-permission android:name="android.permission.HANDLE_QUERY_PACKAGE_RESTART" />
 
     <!-- Allows financed device kiosk apps to perform actions on the Device Lock service
@@ -9239,7 +9247,7 @@
                 android:permission="android.permission.BIND_JOB_SERVICE" >
         </service>
 
-        <service android:name="com.android.server.ZramMaintenance"
+        <service android:name="com.android.server.memory.ZramMaintenance"
                  android:exported="false"
                  android:permission="android.permission.BIND_JOB_SERVICE" >
         </service>
diff --git a/core/res/res/drawable/accessibility_autoclick_button_rounded_background.xml b/core/res/res/drawable/accessibility_autoclick_button_rounded_background.xml
new file mode 100644
index 0000000..6d0c265
--- /dev/null
+++ b/core/res/res/drawable/accessibility_autoclick_button_rounded_background.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2025 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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">
+    <solid android:color="@color/materialColorSurfaceContainer" />
+    <corners android:radius="24dp" />
+</shape>
diff --git a/core/res/res/drawable/accessibility_autoclick_left_click.xml b/core/res/res/drawable/accessibility_autoclick_left_click.xml
new file mode 100644
index 0000000..64c8efb
--- /dev/null
+++ b/core/res/res/drawable/accessibility_autoclick_left_click.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2025 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="18dp"
+    android:height="18dp"
+    android:viewportWidth="18"
+    android:viewportHeight="18">
+    <path
+        android:pathData="M5.7 12C4.1 11.9167 2.75 11.3 1.65 10.15C0.55 9 0 7.61667 0 6C0 4.33333 0.583333 2.91667 1.75 1.75C2.91667 0.583332 4.33333 -0.00000143051 6 -0.00000143051C7.61667 -0.00000143051 9 0.549999 10.15 1.65C11.3 2.75 11.9167 4.1 12 5.7L9.9 5.075C9.68333 4.175 9.21667 3.44167 8.5 2.875C7.78333 2.29167 6.95 2 6 2C4.9 2 3.95833 2.39167 3.175 3.175C2.39167 3.95833 2 4.9 2 6C2 6.95 2.28333 7.78333 2.85 8.5C3.43333 9.21667 4.175 9.68333 5.075 9.9L5.7 12ZM14.525 16.5L10.25 12.225L9 16L6 6L16 9L12.225 10.25L16.5 14.525L14.525 16.5Z"
+        android:fillColor="@color/materialColorPrimary" />
+</vector>
diff --git a/core/res/res/drawable/accessibility_autoclick_pause.xml b/core/res/res/drawable/accessibility_autoclick_pause.xml
new file mode 100644
index 0000000..5251b2a
--- /dev/null
+++ b/core/res/res/drawable/accessibility_autoclick_pause.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2025 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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:fillColor="@color/materialColorPrimary"
+        android:pathData="M6,19h4V5H6v14zm8,-14v14h4V5h-4z" />
+</vector>
diff --git a/core/res/res/drawable/accessibility_autoclick_position.xml b/core/res/res/drawable/accessibility_autoclick_position.xml
new file mode 100644
index 0000000..8c98235
--- /dev/null
+++ b/core/res/res/drawable/accessibility_autoclick_position.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2025 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="21dp"
+    android:height="17dp"
+    android:viewportWidth="21"
+    android:viewportHeight="17">
+    <path
+        android:pathData="M0.400024 2.99961C0.400024 1.67413 1.47454 0.599609 2.80002 0.599609H17.2C18.5255 0.599609 19.6 1.67413 19.6 2.99961V14.9996C19.6 16.3251 18.5255 17.3996 17.2 17.3996H2.80002C1.47454 17.3996 0.400024 16.3251 0.400024 14.9996V2.99961ZM2.80002 2.99961H17.2V14.9996H2.80002V2.99961ZM10.6 10.1996C9.60591 10.1996 8.80002 11.0055 8.80002 11.9996C8.80002 12.9937 9.60591 13.7996 10.6 13.7996H14.2C15.1941 13.7996 16 12.9937 16 11.9996C16 11.0055 15.1941 10.1996 14.2 10.1996H10.6Z"
+        android:fillType="evenOdd"
+        android:fillColor="@color/materialColorPrimary" />
+</vector>
diff --git a/core/res/res/drawable/accessibility_autoclick_type_panel_rounded_background.xml b/core/res/res/drawable/accessibility_autoclick_type_panel_rounded_background.xml
new file mode 100644
index 0000000..e367ba5
--- /dev/null
+++ b/core/res/res/drawable/accessibility_autoclick_type_panel_rounded_background.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2025 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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">
+    <solid android:color="@color/materialColorSurface" />
+    <corners android:radius="40dp" />
+</shape>
diff --git a/core/res/res/layout/accessibility_autoclick_type_panel.xml b/core/res/res/layout/accessibility_autoclick_type_panel.xml
new file mode 100644
index 0000000..9aa47cc
--- /dev/null
+++ b/core/res/res/layout/accessibility_autoclick_type_panel.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2025, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT 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/accessibility_autoclick_type_panel"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center_horizontal"
+    android:background="@drawable/accessibility_autoclick_type_panel_rounded_background"
+    android:orientation="vertical"
+    android:padding="16dp">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:orientation="horizontal">
+
+        <LinearLayout
+            android:id="@+id/accessibility_autoclick_left_click_layout"
+            style="@style/AccessibilityAutoclickPanelButtonLayoutStyle"
+            android:layout_marginEnd="@dimen/accessibility_autoclick_type_panel_button_spacing">
+
+            <ImageButton
+                android:id="@+id/accessibility_autoclick_left_click_button"
+                style="@style/AccessibilityAutoclickPanelImageButtonStyle"
+                android:contentDescription="@string/accessibility_autoclick_left_click"
+                android:src="@drawable/accessibility_autoclick_left_click" />
+        </LinearLayout>
+
+        <View
+            android:layout_width="@dimen/accessibility_autoclick_type_panel_divider_width"
+            android:layout_height="@dimen/accessibility_autoclick_type_panel_divider_height"
+            android:layout_marginEnd="@dimen/accessibility_autoclick_type_panel_button_spacing"
+            android:background="@color/materialColorSurfaceContainer" />
+
+        <LinearLayout
+            android:id="@+id/accessibility_autoclick_pause_layout"
+            style="@style/AccessibilityAutoclickPanelButtonLayoutStyle"
+            android:layout_marginEnd="@dimen/accessibility_autoclick_type_panel_button_spacing">
+
+            <ImageButton
+                android:id="@+id/accessibility_autoclick_pause_button"
+                style="@style/AccessibilityAutoclickPanelImageButtonStyle"
+                android:contentDescription="@string/accessibility_autoclick_pause"
+                android:src="@drawable/accessibility_autoclick_pause" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/accessibility_autoclick_position_layout"
+            style="@style/AccessibilityAutoclickPanelButtonLayoutStyle">
+
+            <ImageButton
+                android:id="@+id/accessibility_autoclick_position_button"
+                style="@style/AccessibilityAutoclickPanelImageButtonStyle"
+                android:contentDescription="@string/accessibility_autoclick_position"
+                android:src="@drawable/accessibility_autoclick_position" />
+        </LinearLayout>
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/core/res/res/layout/chooser_row.xml b/core/res/res/layout/chooser_row.xml
index f5814c3..8463bf4 100644
--- a/core/res/res/layout/chooser_row.xml
+++ b/core/res/res/layout/chooser_row.xml
@@ -17,6 +17,7 @@
 */
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/chooser_row"
               android:orientation="horizontal"
               android:layout_width="match_parent"
               android:layout_height="100dp"
diff --git a/core/res/res/layout/chooser_row_direct_share.xml b/core/res/res/layout/chooser_row_direct_share.xml
index d7e36ee..53e666a 100644
--- a/core/res/res/layout/chooser_row_direct_share.xml
+++ b/core/res/res/layout/chooser_row_direct_share.xml
@@ -17,6 +17,7 @@
 */
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:id="@+id/shortcuts_container"
                 android:orientation="vertical"
                 android:layout_width="match_parent"
                 android:layout_height="200dp">
diff --git a/core/res/res/layout/notification_2025_template_compact_heads_up_base.xml b/core/res/res/layout/notification_2025_template_compact_heads_up_base.xml
new file mode 100644
index 0000000..11fc486
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_compact_heads_up_base.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/status_bar_latest_event_content"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/notification_header_height"
+    android:clipChildren="false"
+    android:tag="compactHUN"
+    android:gravity="center_vertical"
+    android:theme="@style/Theme.DeviceDefault.Notification"
+    android:importantForAccessibility="no">
+    <com.android.internal.widget.NotificationRowIconView
+        android:id="@+id/icon"
+        android:layout_width="@dimen/notification_icon_circle_size"
+        android:layout_height="@dimen/notification_icon_circle_size"
+        android:layout_gravity="center_vertical|start"
+        android:layout_marginStart="@dimen/notification_icon_circle_start"
+        android:background="@drawable/notification_icon_circle"
+        android:padding="@dimen/notification_icon_circle_padding"
+        android:maxDrawableWidth="@dimen/notification_icon_circle_size"
+        android:maxDrawableHeight="@dimen/notification_icon_circle_size"
+        />
+    <FrameLayout
+        android:id="@+id/alternate_expand_target"
+        android:layout_width="@dimen/notification_content_margin_start"
+        android:layout_height="match_parent"
+        android:layout_gravity="start"
+        android:importantForAccessibility="no"
+        android:focusable="false"
+        />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginStart="@dimen/notification_content_margin_start"
+        android:orientation="horizontal"
+        >
+        <NotificationTopLineView
+            android:id="@+id/notification_top_line"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_centerVertical="true"
+            android:layout_weight="1"
+            android:clipChildren="false"
+            android:gravity="center_vertical"
+            android:theme="@style/Theme.DeviceDefault.Notification"
+            >
+            <TextView
+                android:id="@+id/title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginEnd="@dimen/notification_header_separating_margin"
+                android:ellipsize="end"
+                android:fadingEdge="horizontal"
+                android:singleLine="true"
+                android:textAlignment="viewStart"
+                android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
+                android:textSize="@dimen/notification_2025_title_text_size"
+                />
+            <include layout="@layout/notification_2025_top_line_views" />
+        </NotificationTopLineView>
+        <FrameLayout
+            android:id="@+id/expand_button_touch_container"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:minWidth="@dimen/notification_content_margin_end"
+            >
+            <include layout="@layout/notification_2025_expand_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical|end"
+                />
+        </FrameLayout>
+    </LinearLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/notification_2025_template_compact_heads_up_messaging.xml b/core/res/res/layout/notification_2025_template_compact_heads_up_messaging.xml
new file mode 100644
index 0000000..bf70a5e
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_compact_heads_up_messaging.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT 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.CompactMessagingLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/status_bar_latest_event_content"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/notification_header_height"
+    android:clipChildren="false"
+    android:tag="compactMessagingHUN"
+    android:gravity="center_vertical"
+    android:theme="@style/Theme.DeviceDefault.Notification"
+    android:importantForAccessibility="no">
+    <com.android.internal.widget.NotificationRowIconView
+        android:id="@+id/icon"
+        android:layout_width="@dimen/notification_icon_circle_size"
+        android:layout_height="@dimen/notification_icon_circle_size"
+        android:layout_gravity="center_vertical|start"
+        android:layout_marginStart="@dimen/notification_icon_circle_start"
+        android:background="@drawable/notification_icon_circle"
+        android:padding="@dimen/notification_icon_circle_padding"
+        android:maxDrawableWidth="@dimen/notification_icon_circle_size"
+        android:maxDrawableHeight="@dimen/notification_icon_circle_size"
+        />
+    <com.android.internal.widget.CachingIconView
+        android:id="@+id/conversation_icon"
+        android:layout_width="@dimen/notification_icon_circle_size"
+        android:layout_height="@dimen/notification_icon_circle_size"
+        android:layout_gravity="center_vertical|start"
+        android:layout_marginStart="@dimen/notification_icon_circle_start"
+        android:background="@drawable/notification_icon_circle"
+        android:clipToOutline="true"
+        android:maxDrawableWidth="@dimen/notification_icon_circle_size"
+        android:maxDrawableHeight="@dimen/notification_icon_circle_size"
+        android:scaleType="centerCrop"
+        android:importantForAccessibility="no"
+        />
+    <ViewStub
+        android:layout="@layout/notification_2025_conversation_face_pile_layout"
+        android:layout_gravity="center_vertical|start"
+        android:layout_width="@dimen/conversation_compact_face_pile_size"
+        android:layout_height="@dimen/conversation_compact_face_pile_size"
+        android:layout_marginStart="@dimen/notification_icon_circle_start"
+        android:id="@+id/conversation_face_pile"
+        />
+    <FrameLayout
+        android:id="@+id/alternate_expand_target"
+        android:layout_width="@dimen/notification_content_margin_start"
+        android:layout_height="match_parent"
+        android:layout_gravity="start"
+        android:importantForAccessibility="no"
+        android:focusable="false"
+        />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginStart="@dimen/notification_content_margin_start"
+        android:orientation="horizontal"
+        >
+        <NotificationTopLineView
+            android:id="@+id/notification_top_line"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_centerVertical="true"
+            android:layout_weight="1"
+            android:clipChildren="false"
+            android:gravity="center_vertical"
+            android:theme="@style/Theme.DeviceDefault.Notification"
+            >
+            <TextView
+                android:id="@+id/title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginEnd="@dimen/notification_header_separating_margin"
+                android:ellipsize="end"
+                android:fadingEdge="horizontal"
+                android:singleLine="true"
+                android:textAlignment="viewStart"
+                android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
+                android:textSize="@dimen/notification_2025_title_text_size"
+                />
+            <include layout="@layout/notification_2025_top_line_views" />
+        </NotificationTopLineView>
+        <FrameLayout
+            android:id="@+id/reply_action_container"
+            android:layout_width="wrap_content"
+            android:layout_height="@dimen/notification_action_list_height"
+            android:gravity="center_vertical"
+            android:orientation="horizontal" />
+        <FrameLayout
+            android:id="@+id/expand_button_touch_container"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:minWidth="@dimen/notification_content_margin_end"
+            >
+            <include layout="@layout/notification_2025_expand_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical|end"
+                />
+        </FrameLayout>
+    </LinearLayout>
+</com.android.internal.widget.CompactMessagingLayout>
diff --git a/core/res/res/layout/notification_2025_template_expanded_messaging.xml b/core/res/res/layout/notification_2025_template_expanded_messaging.xml
index 7f5a36b..177706c 100644
--- a/core/res/res/layout/notification_2025_template_expanded_messaging.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_messaging.xml
@@ -36,14 +36,13 @@
             android:clipChildren="false"
             android:orientation="vertical">
 
-        <!-- Note: the top margin is being set in code based on the estimated space needed for
-        the header text. -->
         <com.android.internal.widget.RemeasuringLinearLayout
             android:id="@+id/notification_main_column"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="top"
             android:layout_weight="1"
+            android:layout_marginTop="@dimen/notification_2025_header_height"
             android:layout_marginEnd="@dimen/notification_content_margin_end"
             android:orientation="vertical"
             android:clipChildren="false"
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 9f62847..bba775f 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1794,8 +1794,8 @@
     <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Aukeratu eginbide bat"</string>
     <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Aukeratu eginbide bat"</string>
     <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_gesture_instructional_text" msgid="4133877896011098550">"Lasterbidea erabiltzen duzun hurrengoan irekiko da eginbidea. Pasatu 2 hatz pantailaren behealdetik gora 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 gora eta askatu bizkor."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Lupa"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Telefonoaren mikrofonora aldatu nahi duzu?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Audifonoaren mikrofonora aldatu nahi duzu?"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index f4d6099..75ce468 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -67,10 +67,10 @@
     <string name="RuacMmi" msgid="1876047385848991110">"અનિચ્છિત પજવણીકારક કૉલ્સનો અસ્વીકાર"</string>
     <string name="CndMmi" msgid="185136449405618437">"કૉલિંગ નંબર વિતરણ"</string>
     <string name="DndMmi" msgid="8797375819689129800">"ખલેલ પાડશો નહીં"</string>
-    <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"કૉલર ID પ્રતિબંધિત પર ડિફોલ્ટ છે. આગલો કૉલ: પ્રતિબંધિત છે"</string>
-    <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"કૉલર ID પ્રતિબંધિત પર ડિફોલ્ટ છે. આગલો કૉલ: પ્રતિબંધિત નહીં"</string>
-    <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"કૉલર ID પ્રતિબંધિત નહીં પર ડિફોલ્ટ છે. આગલો કૉલ: પ્રતિબંધિત"</string>
-    <string name="CLIRDefaultOffNextCallOff" msgid="2491576172356463443">"કૉલર ID પ્રતિબંધિત નહીં પર ડિફોલ્ટ છે. આગલો કૉલ: પ્રતિબંધિત નહીં"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"કૉલર ID ડિફૉલ્ટ તરીકે પ્રતિબંધિત છે. આગળનો કૉલ: પ્રતિબંધિત છે"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"કૉલર ID ડિફૉલ્ટ તરીકે પ્રતિબંધિત છે. આગળનો કૉલ: પ્રતિબંધિત નથી"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"કૉલર ID ડિફૉલ્ટ તરીકે પ્રતિબંધિત નથી. આગળનો કૉલ: પ્રતિબંધિત છે"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2491576172356463443">"કૉલર ID ડિફૉલ્ટ તરીકે પ્રતિબંધિત નથી. આગળનો કૉલ: પ્રતિબંધિત નથી"</string>
     <string name="page_size_compat_apk_warning" msgid="2982396798449041224">"આ ઍપ 16 KB સુસંગત નથી. APK સંરેખણની તપાસ નિષ્ફળ રહી. આ ઍપ પેજના કદ સાથે સુસંગત મોડનો ઉપયોગ કરીને ચાલશે. શ્રેષ્ઠ સુસંગતતા માટે, કૃપા કરીને 16 KB સપોર્ટવાળી ઍપ્લિકેશન ફરીથી સંકલિત કરો. વધુ માહિતી માટે, &lt;a href=\"https://developer.android.com/16kb-page-size\"&gt;https://developer.android.com/16kb-page-size&lt;/a&gt; જુઓ"</string>
     <string name="page_size_compat_elf_warning" msgid="6753874059564812651">"આ ઍપ 16 KB સુસંગત નથી. ELF સંરેખણની તપાસ નિષ્ફળ રહી. આ ઍપ પેજના કદ સાથે સુસંગત મોડનો ઉપયોગ કરીને ચાલશે. શ્રેષ્ઠ સુસંગતતા માટે, કૃપા કરીને 16 KB સપોર્ટવાળી ઍપ્લિકેશન ફરીથી સંકલિત કરો. વધુ માહિતી માટે, &lt;a href=\"https://developer.android.com/16kb-page-size\"&gt;https://developer.android.com/16kb-page-size&lt;/a&gt; જુઓ"</string>
     <string name="page_size_compat_apk_and_elf_warning" msgid="7628675779500605390">"આ ઍપ 16 KB સુસંગત નથી. APK અને ELF સંરેખણની તપાસ નિષ્ફળ રહી. આ ઍપ પેજના કદ સાથે સુસંગત મોડનો ઉપયોગ કરીને ચાલશે. શ્રેષ્ઠ સુસંગતતા માટે, કૃપા કરીને 16 KB સપોર્ટવાળી ઍપ્લિકેશન ફરીથી સંકલિત કરો. વધુ માહિતી માટે, &lt;a href=\"https://developer.android.com/16kb-page-size\"&gt;https://developer.android.com/16kb-page-size&lt;/a&gt; જુઓ"</string>
@@ -1039,12 +1039,12 @@
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક પૅટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> વખત અસફળ પ્રયાસ પછી, તમને તમારા Google સાઇન ઇનનો ઉપયોગ કરીને તમારા ટૅબ્લેટને અનલૉક કરવા માટે કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરી પ્રયાસ કરો."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક પૅટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> વખત અસફળ પ્રયાસ પછી, તમને તમારા Google સાઇન ઇનનો ઉપયોગ કરીને તમારા Android TV ડિવાઇસને અનલૉક કરવા માટે કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરી પ્રયાસ કરો."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક પૅટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> વખત અસફળ પ્રયાસ પછી, તમને તમારા Google સાઇન ઇનનો ઉપયોગ કરીને તમારા ફોનને અનલૉક કરવા માટે કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરી પ્રયાસ કરો."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"તમે ટેબ્લેટને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસ પછી, ટેબ્લેટને ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે અને તેનો તમામ ડેટા કાઢી નાખવામાં આવશે."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="7914445759242151426">"તમે ટૅબ્લેટને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%1$d</xliff:g> વાર ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસ પછી, ટૅબ્લેટને ફેક્ટરી ડિફૉલ્ટ પર રીસેટ કરવામાં આવશે અને તેનો તમામ ડેટા ગુમાવવામાં આવશે."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="4275591249631864248">"તમે તમારા Android TV ડિવાઇસને <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસ પછી, તમારા Android TV ડિવાઇસને ફેક્ટરી ડિફૉલ્ટ પર રીસેટ કરવામાં આવશે અને બધો વપરાશકર્તા ડેટા ગુમ થઈ જશે."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"તમે ફોનને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસો પછી, ફોનને ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે અને તેનો તમામ ડેટા કાઢી નાખવામાં આવશે."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"તમે <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે ટેબ્લેટને અનલૉક કરવાનો પ્રયાસ કર્યો. ટેબ્લેટ હવે ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="1166532464798446579">"તમે ફોનને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%1$d</xliff:g> વાર ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસો પછી, ફોનને ફેક્ટરી ડિફૉલ્ટ પર રીસેટ કરવામાં આવશે અને તેનો તમામ ડેટા ગુમાવવામાં આવશે."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="8682445539263683414">"તમે <xliff:g id="NUMBER">%d</xliff:g> વાર ખોટી રીતે ટૅબ્લેટને અનલૉક કરવાનો પ્રયાસ કર્યો. ટૅબ્લેટ હવે ફેક્ટરી ડિફૉલ્ટ પર રીસેટ કરવામાં આવશે."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="2205435033340091883">"તમે તમારા Android TV ડિવાઇસને <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. તમારા Android TV ડિવાઇસને હવે ફેક્ટરી ડિફૉલ્ટ પર રીસેટ કરવામાં આવશે."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"તમે <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે ફોનને અનલૉક કરવાનો પ્રયાસ કર્યો. ફોન હવે ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"તમે <xliff:g id="NUMBER">%d</xliff:g> વાર ખોટી રીતે ફોનને અનલૉક કરવાનો પ્રયાસ કર્યો. ફોન હવે ફેક્ટરી ડિફૉલ્ટ પર રીસેટ કરવામાં આવશે."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"<xliff:g id="NUMBER">%d</xliff:g> સેકંડમાં ફરી પ્રયાસ કરો."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"પૅટર્ન ભૂલી ગયા છો?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"એકાઉન્ટ અનલૉક કરો"</string>
@@ -1265,7 +1265,7 @@
     <string name="whichImageCaptureApplication" msgid="2737413019463215284">"આની સાથે છબી કૅપ્ચર કરો"</string>
     <string name="whichImageCaptureApplicationNamed" msgid="8820702441847612202">"%1$s સાથે છબી કૅપ્ચર કરો"</string>
     <string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"છબી કૅપ્ચર કરો"</string>
-    <string name="alwaysUse" msgid="3153558199076112903">"આ ક્રિયા માટે ડિફોલ્ટ તરીકે ઉપયોગમાં લો."</string>
+    <string name="alwaysUse" msgid="3153558199076112903">"આ ઍક્શન માટે ડિફૉલ્ટ તરીકેનો ઉપયોગ કરો."</string>
     <string name="use_a_different_app" msgid="4987790276170972776">"અલગ એપ્લિકેશનનો ઉપયોગ કરો"</string>
     <string name="clearDefaultHintMsg" msgid="1325866337702524936">"સિસ્ટમ સેટિંગ &gt; ઍપ &gt; ડાઉનલોડ કરેલામાં ડિફૉલ્ટ સાફ કરો."</string>
     <string name="chooseActivity" msgid="8563390197659779956">"એક ક્રિયા પસંદ કરો"</string>
@@ -1351,7 +1351,7 @@
     <string name="volume_icon_description_incall" msgid="4491255105381227919">"કૉલ વૉલ્યૂમ"</string>
     <string name="volume_icon_description_media" msgid="4997633254078171233">"મીડિયા વૉલ્યૂમ"</string>
     <string name="volume_icon_description_notification" msgid="579091344110747279">"સૂચના વૉલ્યૂમ"</string>
-    <string name="ringtone_default" msgid="9118299121288174597">"ડિફોલ્ટ રિંગટોન"</string>
+    <string name="ringtone_default" msgid="9118299121288174597">"ડિફૉલ્ટ રિંગટોન"</string>
     <string name="ringtone_default_with_actual" msgid="2709686194556159773">"ડિફૉલ્ટ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
     <string name="ringtone_silent" msgid="397111123930141876">"કોઈ નહીં"</string>
     <string name="ringtone_picker_title" msgid="667342618626068253">"રિંગટોન્સ"</string>
@@ -1735,12 +1735,12 @@
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે તમારો પિન લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે તમારો પાસવર્ડ લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે તમારી અનલૉક પૅટર્ન દોરી. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"તમે ટેબ્લેટને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસ પછી, ટેબ્લેટને ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે અને તેનો તમામ ડેટા કાઢી નાખવામાં આવશે."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"તમે ટૅબ્લેટને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%1$d</xliff:g> વાર ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસ પછી, ટૅબ્લેટને ફેક્ટરી ડિફૉલ્ટ પર રીસેટ કરવામાં આવશે અને તેનો તમામ ડેટા ગુમાવવામાં આવશે."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"તમે તમારા Android TV ડિવાઇસને <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસ પછી, તમારા Android TV ડિવાઇસને ફેક્ટરી ડિફૉલ્ટ પર રીસેટ કરવામાં આવશે અને બધો વપરાશકર્તા ડેટા ગુમ થઈ જશે."</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"તમે ફોનને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસો પછી, ફોનને ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે અને તેનો તમામ ડેટા કાઢી નાખવામાં આવશે."</string>
-    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"તમે <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે ટેબ્લેટને અનલૉક કરવાનો પ્રયાસ કર્યો. ટેબ્લેટ હવે ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="5955398963754432548">"તમે ફોનને અનલૉક કરવા માટે <xliff:g id="NUMBER_0">%1$d</xliff:g> વાર ખોટી રીતે પ્રયાસ કર્યો. <xliff:g id="NUMBER_1">%2$d</xliff:g> વધુ અસફળ પ્રયાસો પછી, ફોનને ફેક્ટરી ડિફૉલ્ટ પર રીસેટ કરવામાં આવશે અને તેનો તમામ ડેટા ગુમાવવામાં આવશે."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2299099385175083308">"તમે <xliff:g id="NUMBER">%d</xliff:g> વાર ખોટી રીતે ટૅબ્લેટને અનલૉક કરવાનો પ્રયાસ કર્યો. ટૅબ્લેટ હવે ફેક્ટરી ડિફૉલ્ટ પર રીસેટ કરવામાં આવશે."</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"તમે તમારા Android TV ડિવાઇસને <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. તમારા Android TV ડિવાઇસને હવે ફેક્ટરી ડિફૉલ્ટ પર રીસેટ કરવામાં આવશે."</string>
-    <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"તમે <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે ફોનને અનલૉક કરવાનો પ્રયાસ કર્યો. ફોન હવે ફેક્ટરી ડિફોલ્ટ પર ફરીથી સેટ કરવામાં આવશે."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"તમે <xliff:g id="NUMBER">%d</xliff:g> વાર ખોટી રીતે ફોનને અનલૉક કરવાનો પ્રયાસ કર્યો. ફોન હવે ફેક્ટરી ડિફૉલ્ટ પર રીસેટ કરવામાં આવશે."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે અનલૉક પૅટર્ન દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> વખત અસફળ પ્રયાસો પછી, તમને એક ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને તમારા ટૅબ્લેટને અનલૉક કરવા માટે પૂછવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરી પ્રયાસ કરો."</string>
     <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"તમે તમારી અનલૉક પૅટર્ન <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસ પછી, તમને ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને તમારા Android TV ડિવાઇસને અનલૉક કરવાનું કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"તમે તમારી અનલૉક પૅટર્ન <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી. હજી <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસ પછી, તમને ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને ફોનને અનલૉક કરવાનું કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index b5fc19a..58de41e 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1411,7 +1411,7 @@
     <string name="carrier_app_notification_text" msgid="6567057546341958637">"Dodirnite da biste je postavili"</string>
     <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Vaša je vremenska zona promijenjena"</string>
     <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Sada ste u vremenskoj zoni <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string>
-    <string name="time_picker_dialog_title" msgid="9053376764985220821">"Postavljanje vremena"</string>
+    <string name="time_picker_dialog_title" msgid="9053376764985220821">"Postavite vrijeme"</string>
     <string name="date_picker_dialog_title" msgid="5030520449243071926">"Postavi datum"</string>
     <string name="date_time_set" msgid="4603445265164486816">"Postavi"</string>
     <string name="date_time_done" msgid="8363155889402873463">"Gotovo"</string>
@@ -2108,7 +2108,7 @@
     <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"Otklanjanje pogrešaka putem USB-a"</string>
     <string name="time_picker_hour_label" msgid="4208590187662336864">"sat"</string>
     <string name="time_picker_minute_label" msgid="8307452311269824553">"minuta"</string>
-    <string name="time_picker_header_text" msgid="9073802285051516688">"Postavljanje vremena"</string>
+    <string name="time_picker_header_text" msgid="9073802285051516688">"Postavite vrijeme"</string>
     <string name="time_picker_input_error" msgid="8386271930742451034">"Unesite važeće vrijeme"</string>
     <string name="time_picker_prompt_label" msgid="303588544656363889">"Unesite vrijeme"</string>
     <string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"Prijeđite na način unosa teksta da biste unijeli vrijeme."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 34b179f..3700620 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -2086,7 +2086,7 @@
     <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Tocca per visualizzare i file"</string>
     <string name="pin_target" msgid="8036028973110156895">"Fissa"</string>
     <string name="pin_specific_target" msgid="7824671240625957415">"Blocca <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="unpin_target" msgid="3963318576590204447">"Sblocca"</string>
+    <string name="unpin_target" msgid="3963318576590204447">"Stacca"</string>
     <string name="unpin_specific_target" msgid="3859828252160908146">"Sblocca <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="app_info" msgid="6113278084877079851">"Informazioni app"</string>
     <string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 1035fed..71ddb09 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -240,7 +240,7 @@
     <string name="turn_on_radio" msgid="2961717788170634233">"Įjungti bevielį"</string>
     <string name="turn_off_radio" msgid="7222573978109933360">"Išjungti bevielį"</string>
     <string name="screen_lock" msgid="2072642720826409809">"Ekrano užraktas"</string>
-    <string name="power_off" msgid="4111692782492232778">"Išjungiamas maitinimas"</string>
+    <string name="power_off" msgid="4111692782492232778">"Išjungti maitinimą"</string>
     <string name="silent_mode_silent" msgid="5079789070221150912">"Skambutis išjungtas"</string>
     <string name="silent_mode_vibrate" msgid="8821830448369552678">"Vibracija skambinant"</string>
     <string name="silent_mode_ring" msgid="6039011004781526678">"Skambutis įjungtas"</string>
@@ -264,7 +264,7 @@
     <string name="global_actions" product="tv" msgid="3871763739487450369">"„Android TV“ parinktys"</string>
     <string name="global_actions" product="default" msgid="6410072189971495460">"Telefono parinktys"</string>
     <string name="global_action_lock" msgid="6949357274257655383">"Ekrano užraktas"</string>
-    <string name="global_action_power_off" msgid="4404936470711393203">"Išjungiamas maitinimas"</string>
+    <string name="global_action_power_off" msgid="4404936470711393203">"Išjungti maitinimą"</string>
     <string name="global_action_power_options" msgid="1185286119330160073">"Maitinimas"</string>
     <string name="global_action_restart" msgid="4678451019561687074">"Paleisti iš naujo"</string>
     <string name="global_action_emergency" msgid="1387617624177105088">"Skubus atvejis"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 63b017a..e9dfef8 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -2182,7 +2182,7 @@
     <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_title" msgid="8436359459300146555">"वर्धित नोटिफिकेशन"</string>
     <string name="nas_upgrade_notification_content" msgid="5157550369837103337">"सुचवलेल्या कृती आणि उत्तरे आता वर्धित सूचनांद्वारे दिली जातात. Android अ‍ॅडॅप्टिव्ह सूचना यांना आता सपोर्ट नाही."</string>
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ओके"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"बंद करा"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 7608633..0a51d1e 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -2109,7 +2109,7 @@
     <string name="time_picker_minute_label" msgid="8307452311269824553">"မိ​နစ်​"</string>
     <string name="time_picker_header_text" msgid="9073802285051516688">"အချိန်သတ်မှတ်ရန်"</string>
     <string name="time_picker_input_error" msgid="8386271930742451034">"မှန်ကန်သည့် အမည်တစ်ခု ထည့်ရန်"</string>
-    <string name="time_picker_prompt_label" msgid="303588544656363889">"အချိန်ကို ထည့်ရန်"</string>
+    <string name="time_picker_prompt_label" msgid="303588544656363889">"အချိန်ရိုက်ထည့်ပါ"</string>
     <string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"အချိန်ထည့်သွင်းရန် စာသားထည့်သွင်းမှုမုဒ်သို့ ပြောင်းပါ။"</string>
     <string name="time_picker_radial_mode_description" msgid="1222342577115016953">"အချိန်ထည့်သွင်းမှုအတွက် နာရီမုဒ်သို့ ပြောင်းပါ။"</string>
     <string name="autofill_picker_accessibility_title" msgid="4425806874792196599">"အော်တိုဖြည့် ရွေးချယ်စရာများ"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 91c7adc5..79314f7 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -96,7 +96,7 @@
     <string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Status dos dados móveis"</string>
     <string name="notification_channel_sms" msgid="1243384981025535724">"Mensagens SMS"</string>
     <string name="notification_channel_voice_mail" msgid="8457433203106654172">"Mensagens do correio de voz"</string>
-    <string name="notification_channel_wfc" msgid="9048240466765169038">"Chamadas por Wi-Fi"</string>
+    <string name="notification_channel_wfc" msgid="9048240466765169038">"Ligação pelo Wi-Fi"</string>
     <string name="notification_channel_sim" msgid="5098802350325677490">"Status do chip"</string>
     <string name="notification_channel_sim_high_prio" msgid="642361929452850928">"Status de prioridade alta do chip"</string>
     <string name="peerTtyModeFull" msgid="337553730440832160">"TTD modo COMPLETO solicitado"</string>
@@ -148,7 +148,7 @@
     <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Ligação pelo Wi-Fi"</string>
     <string name="wifi_calling_off_summary" msgid="5626710010766902560">"Desativado"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Chamar via Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Chamar via rede móvel"</string>
+    <string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Ligar via rede móvel"</string>
     <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Somente Wi-Fi"</string>
     <!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
     <skip />
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 91c7adc5..79314f7 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -96,7 +96,7 @@
     <string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Status dos dados móveis"</string>
     <string name="notification_channel_sms" msgid="1243384981025535724">"Mensagens SMS"</string>
     <string name="notification_channel_voice_mail" msgid="8457433203106654172">"Mensagens do correio de voz"</string>
-    <string name="notification_channel_wfc" msgid="9048240466765169038">"Chamadas por Wi-Fi"</string>
+    <string name="notification_channel_wfc" msgid="9048240466765169038">"Ligação pelo Wi-Fi"</string>
     <string name="notification_channel_sim" msgid="5098802350325677490">"Status do chip"</string>
     <string name="notification_channel_sim_high_prio" msgid="642361929452850928">"Status de prioridade alta do chip"</string>
     <string name="peerTtyModeFull" msgid="337553730440832160">"TTD modo COMPLETO solicitado"</string>
@@ -148,7 +148,7 @@
     <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Ligação pelo Wi-Fi"</string>
     <string name="wifi_calling_off_summary" msgid="5626710010766902560">"Desativado"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Chamar via Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Chamar via rede móvel"</string>
+    <string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Ligar via rede móvel"</string>
     <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Somente Wi-Fi"</string>
     <!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
     <skip />
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index fbb57ca..9d7d520 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -2469,7 +2469,7 @@
     <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Zapnite Vyberať sieť automaticky"</string>
     <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Zapnite v Nastaveniach možnosť Vyberať sieť automaticky, aby telefón mohol nájsť sieť, ktorá spolupracuje so satelitom"</string>
     <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Zapnúť"</string>
-    <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Prejsť späť"</string>
+    <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Späť"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Nespracovaná…"</string>
     <string name="satellite_sos_available_notification_title" msgid="5396708154268096124">"Pomoc cez satelit je teraz k dispozícii"</string>
     <string name="satellite_sos_available_notification_summary" msgid="1727088812951848330">"Tiesňovej linke môžete poslať správu, keď nie je dostupná mobilná sieť ani sieť Wi‑Fi. Správy Google musíte mať nastavené ako predvolený komunikátor."</string>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 8c6fd1d..aaf8420 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1862,9 +1862,38 @@
        <enum name="sync" value="2" />
     </attr>
 
-    <!-- This attribute will be used to override app compatibility mode on 16 KB devices.
-         If set to enabled, Natives lib will be extracted from APK if they are not page aligned on
-         16 KB device. 4 KB natives libs will be loaded app-compat mode if they are eligible.
+    <!-- This attribute overrides the user-set or platform-set 16 KB page size
+         compatibility mode, so that page agnostic compatibility is always enabled
+         or always disabled, rather than according to the user's preference.
+
+         <p>On 4 KB systems, this attribute is ignored and apps are installed
+         normally.
+
+         <p>On 16 KB systems, if an app is built for 16 KB page sizes, this
+         attribute is ignored and apps are installed normally.
+
+         <p>This attribute only affects 16 KB systems for apps that are built
+         with 4 KB page size (old) options.
+
+         <p>When page agnostic compatibility is enabled (either through this
+         flag or via the user's preference), the system specializes the app
+         installation process in ways known to improve compatibility of 4 KB
+         built apps on 16 KB systems. That is, apps which do not have aligned
+         libraries in APK files are extracted, requiring more space on the
+         device. An additional specialization when this option is enabled is
+         that the linker loads the application in a special mode intended
+         to allow 4 KB aligned program segments to load on a 16 KB page system.
+
+         <p>Here are the situations where this attribute should be most useful:
+         <ul>
+            <li>If an app works on 16 KB mode, but is not built for it, enabling this
+            attribute forces the app to be installed in 16 KB mode without
+            the user having to set these options themself.
+            <li>If an app is fully working in 16 KB mode, you can set this
+            attribute to disabled, so that any regression causes a clear failure
+            and this compatibility mode is not used.
+         </ul>
+
          @FlaggedApi(android.content.pm.Flags.FLAG_APP_COMPAT_OPTION_16KB) -->
     <attr name="pageSizeCompat">
         <!-- value for enabled must match with
@@ -2572,10 +2601,6 @@
              against a development branch, in which case it will only work against
              the development builds. -->
         <attr name="minSdkVersion" format="integer|string" />
-        <!-- This is the minimum SDK major and minor version (e.g. "36.1") that
-             the application requires. Verified independently of minSdkVersion.
-             @FlaggedApi(android.sdk.Flags.FLAG_MAJOR_MINOR_VERSIONING_SCHEME) -->
-        <attr name="minSdkVersionFull" format="string" />
         <!-- This is the SDK version number that the application is targeting.
              It is able to run on older versions (down to minSdkVersion), but
              was explicitly tested to work with the version specified here.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a49e034..9f731fe 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -5958,6 +5958,9 @@
         <!-- <item>com.google</item> -->
     </string-array>
 
+    <!-- Whether to restrict the accounts that raw contacts can be created in. -->
+    <bool name = "config_rawContactsAccountRestrictionEnabled">true</bool>
+
     <!-- Whether or not to use assistant stream volume separately from music volume -->
     <bool name="config_useAssistantVolume">false</bool>
 
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 5644cf9..484e8ef 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -714,6 +714,18 @@
     <!-- The minimum window size of the accessibility window magnifier -->
     <dimen name="accessibility_window_magnifier_min_size">122dp</dimen>
 
+    <!-- The accessibility autoclick panel button spacing -->
+    <dimen name="accessibility_autoclick_type_panel_button_spacing">12dp</dimen>
+
+    <!-- The accessibility autoclick panel button width and height -->
+    <dimen name="accessibility_autoclick_type_panel_button_size">36dp</dimen>
+
+    <!-- The accessibility autoclick panel divider width -->
+    <dimen name="accessibility_autoclick_type_panel_divider_width">1dp</dimen>
+
+    <!-- The accessibility autoclick panel divider height -->
+    <dimen name="accessibility_autoclick_type_panel_divider_height">24dp</dimen>
+
     <!-- Margin around the various security views -->
     <dimen name="keyguard_muliuser_selector_margin">8dp</dimen>
 
diff --git a/core/res/res/values/public-final.xml b/core/res/res/values/public-final.xml
index d8e8931..af1e5123 100644
--- a/core/res/res/values/public-final.xml
+++ b/core/res/res/values/public-final.xml
@@ -3953,8 +3953,7 @@
     <public name="pageSizeCompat" />
     <!-- @FlaggedApi(android.nfc.Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES) -->
     <public name="wantsRoleHolderPriority"/>
-    <!-- @FlaggedApi(android.sdk.Flags.FLAG_MAJOR_MINOR_VERSIONING_SCHEME) -->
-    <public name="minSdkVersionFull"/>
+    <public name="removed_"/>
     <public name="removed_" />
     <public name="removed_" />
     <public name="removed_" />
@@ -3980,8 +3979,6 @@
   <public type="attr" name="pageSizeCompat" id="0x010106ab" />
   <!-- @FlaggedApi(android.nfc.Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES) -->
   <public type="attr" name="wantsRoleHolderPriority" id="0x010106ac" />
-  <!-- @FlaggedApi(android.sdk.Flags.FLAG_MAJOR_MINOR_VERSIONING_SCHEME) -->
-  <public type="attr" name="minSdkVersionFull" id="0x010106ad" />
 
   <staging-public-group-final type="string" first-id="0x01b40000">
     <!-- @FlaggedApi(android.content.pm.Flags.FLAG_SDK_DEPENDENCY_INSTALLER)
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index fa4c21d..ed86bd2 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5744,6 +5744,16 @@
     <string name="unpin_specific_target">Unpin <xliff:g id="label" example="Tweet">%1$s</xliff:g></string>
     <!-- View application info for a target. -->
     <string name="app_info">App info</string>
+    <!-- Accessibility announcement for the shortcut group (https://developer.android.com/training/sharing/direct-share-targets)
+     in the list of targets. [CHAR LIMIT=NONE]-->
+    <string name="shortcut_group_a11y_title">Direct share targets</string>
+    <!-- Accessibility announcement for the suggested application group in the list of targets.
+    [CHAR LIMIT=NONE] -->
+    <string name="suggested_apps_group_a11y_title">App suggestions</string>
+    <!-- Accessibility announcement for the all-applications group in the list of targets.
+    [CHAR LIMIT=NONE] -->
+    <string name="all_apps_group_a11y_title">App list</string>
+
 
     <!-- The representation of a time duration when negative. An example is -1:14. This can be used with a countdown timer for example.-->
     <string name="negative_duration">\u2212<xliff:g id="time" example="1:14">%1$s</xliff:g></string>
@@ -6149,6 +6159,16 @@
     <!-- Label for Dpad center action [CHAR LIMIT=NONE] -->
     <string name="accessibility_system_action_dpad_center_label">Dpad Center</string>
 
+    <!-- Accessibility autoclick related strings -->
+    <!-- Label for autoclick type settings panel [CHAR LIMIT=NONE] -->
+    <string name="accessibility_autoclick_type_settings_panel_title">Autoclick type settings panel</string>
+    <!-- Label for autoclick left click button [CHAR LIMIT=NONE] -->
+    <string name="accessibility_autoclick_left_click">Left click</string>
+    <!-- Label for autoclick pause button [CHAR LIMIT=NONE] -->
+    <string name="accessibility_autoclick_pause">Pause</string>
+    <!-- Label for autoclick position button [CHAR LIMIT=NONE] -->
+    <string name="accessibility_autoclick_position">Position</string>
+
     <!-- Text to tell the user that a package has been forced by themselves in the RESTRICTED bucket. [CHAR LIMIT=NONE] -->
     <string name="as_app_forced_to_restricted_bucket">
         <xliff:g id="package_name" example="com.android.example">%1$s</xliff:g> has been put into the RESTRICTED bucket</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 579dc91..ee1edda 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1745,6 +1745,22 @@
         <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
     </style>
 
+    <style name="AccessibilityAutoclickPanelButtonLayoutStyle">
+        <item name="android:gravity">center</item>
+        <item name="android:background">@drawable/accessibility_autoclick_button_rounded_background</item>
+        <item name="android:layout_width">@dimen/accessibility_autoclick_type_panel_button_size</item>
+        <item name="android:layout_height">@dimen/accessibility_autoclick_type_panel_button_size</item>
+    </style>
+
+    <style name="AccessibilityAutoclickPanelImageButtonStyle">
+        <item name="android:gravity">center</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:scaleType">center</item>
+        <item name="android:background">@android:color/transparent</item>
+        <item name="android:tint">@color/materialColorPrimary</item>
+    </style>
+
     <!--
         TODO(b/309578419): Make activities go edge-to-edge properly and then remove this.
     -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8bb3c99..f4b7a3f 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2412,6 +2412,8 @@
   <java-symbol type="layout" name="notification_2025_template_collapsed_base" />
   <java-symbol type="layout" name="notification_2025_template_expanded_base" />
   <java-symbol type="layout" name="notification_2025_template_heads_up_base" />
+  <java-symbol type="layout" name="notification_2025_template_compact_heads_up_base" />
+  <java-symbol type="layout" name="notification_2025_template_compact_heads_up_messaging" />
   <java-symbol type="layout" name="notification_2025_template_header" />
   <java-symbol type="layout" name="notification_2025_template_collapsed_messaging" />
   <java-symbol type="layout" name="notification_2025_template_collapsed_media" />
@@ -4615,6 +4617,7 @@
   <java-symbol type="string" name="config_rawContactsLocalAccountName" />
   <java-symbol type="string" name="config_rawContactsLocalAccountType" />
   <java-symbol type="array" name="config_rawContactsEligibleDefaultAccountTypes" />
+  <java-symbol type="bool" name="config_rawContactsAccountRestrictionEnabled" />
 
   <!-- For App Standby -->
   <java-symbol type="string" name="as_app_forced_to_restricted_bucket" />
@@ -4727,6 +4730,8 @@
   <java-symbol type="id" name="resolver_empty_state_container" />
   <java-symbol type="id" name="button_bar_container" />
   <java-symbol type="id" name="title_container" />
+  <java-symbol type="id" name="shortcuts_container" />
+  <java-symbol type="id" name="chooser_row" />
   <java-symbol type="string" name="resolver_cross_profile_blocked" />
   <java-symbol type="string" name="resolver_cant_share_with_work_apps_explanation" />
   <java-symbol type="string" name="resolver_cant_share_with_personal_apps_explanation" />
@@ -4736,6 +4741,9 @@
   <java-symbol type="string" name="resolver_no_work_apps_available" />
   <java-symbol type="string" name="resolver_no_personal_apps_available" />
   <java-symbol type="string" name="resolver_switch_on_work" />
+  <java-symbol type="string" name="shortcut_group_a11y_title" />
+  <java-symbol type="string" name="suggested_apps_group_a11y_title" />
+  <java-symbol type="string" name="all_apps_group_a11y_title" />
   <java-symbol type="drawable" name="ic_screenshot_edit" />
   <java-symbol type="dimen" name="resolver_empty_state_height" />
   <java-symbol type="dimen" name="resolver_empty_state_height_with_tabs" />
@@ -5605,6 +5613,24 @@
   <java-symbol type="bool" name="config_enable_a11y_fullscreen_magnification_overscroll_handler" />
   <java-symbol type="dimen" name="accessibility_fullscreen_magnification_gesture_edge_slop" />
 
+  <!-- Accessibility autoclick related -->
+  <java-symbol type="layout" name="accessibility_autoclick_type_panel" />
+  <java-symbol type="string" name="accessibility_autoclick_type_settings_panel_title" />
+  <java-symbol type="string" name="accessibility_autoclick_left_click" />
+  <java-symbol type="string" name="accessibility_autoclick_pause" />
+  <java-symbol type="string" name="accessibility_autoclick_position" />
+  <java-symbol type="dimen" name="accessibility_autoclick_type_panel_button_spacing" />
+  <java-symbol type="dimen" name="accessibility_autoclick_type_panel_button_size" />
+  <java-symbol type="dimen" name="accessibility_autoclick_type_panel_divider_height" />
+  <java-symbol type="dimen" name="accessibility_autoclick_type_panel_divider_width" />
+  <java-symbol type="id" name="accessibility_autoclick_type_panel" />
+  <java-symbol type="id" name="accessibility_autoclick_left_click_layout" />
+  <java-symbol type="id" name="accessibility_autoclick_left_click_button" />
+  <java-symbol type="id" name="accessibility_autoclick_pause_layout" />
+  <java-symbol type="id" name="accessibility_autoclick_pause_button" />
+  <java-symbol type="id" name="accessibility_autoclick_position_layout" />
+  <java-symbol type="id" name="accessibility_autoclick_position_button" />
+
   <!-- For HapticFeedbackConstants configurability defined at HapticFeedbackCustomization -->
   <java-symbol type="string" name="config_hapticFeedbackCustomizationFile" />
   <java-symbol type="xml" name="haptic_feedback_customization" />
diff --git a/core/tests/coretests/src/android/os/PerfettoTraceTest.java b/core/tests/coretests/src/android/os/PerfettoTraceTest.java
index 0b5a446..91efacf 100644
--- a/core/tests/coretests/src/android/os/PerfettoTraceTest.java
+++ b/core/tests/coretests/src/android/os/PerfettoTraceTest.java
@@ -59,6 +59,8 @@
 
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 /**
  * This class is used to test the native tracing support. Run this test
@@ -77,6 +79,8 @@
     private static final String BAR = "bar";
 
     private static final Category FOO_CATEGORY = new Category(FOO);
+    private static final int MESSAGE = 1234567;
+    private static final int MESSAGE_COUNT = 3;
 
     private final Set<String> mCategoryNames = new ArraySet<>();
     private final Set<String> mEventNames = new ArraySet<>();
@@ -592,6 +596,89 @@
         assertThat(mDebugAnnotationNames).doesNotContain("before");
     }
 
+    @Test
+    @RequiresFlagsEnabled(android.os.Flags.FLAG_PERFETTO_SDK_TRACING_V2)
+    public void testMessageQueue() throws Exception {
+        TraceConfig traceConfig = getTraceConfig("mq");
+
+        PerfettoTrace.MQ_CATEGORY.register();
+        final HandlerThread thread = new HandlerThread("test");
+        thread.start();
+        final Handler handler = thread.getThreadHandler();
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        PerfettoTrace.Session session = new PerfettoTrace.Session(true,
+                getTraceConfig("mq").toByteArray());
+
+        handler.sendEmptyMessage(MESSAGE);
+        handler.sendEmptyMessageDelayed(MESSAGE, 10);
+        handler.sendEmptyMessage(MESSAGE);
+        handler.postDelayed(() -> {
+            latch.countDown();
+        }, 10);
+        assertThat(latch.await(100, TimeUnit.MILLISECONDS)).isTrue();
+
+        byte[] traceBytes = session.close();
+
+        Trace trace = Trace.parseFrom(traceBytes);
+
+        boolean hasTrackEvent = false;
+        int instantCount = 0;
+        int counterCount = 0;
+        int beginCount = 0;
+        int endCount = 0;
+
+        Set<Long> flowIds = new ArraySet<>();
+        for (TracePacket packet: trace.getPacketList()) {
+            TrackEvent event;
+            if (packet.hasTrackEvent()) {
+                hasTrackEvent = true;
+                event = packet.getTrackEvent();
+            } else {
+                continue;
+            }
+
+            List<DebugAnnotation> annotations = event.getDebugAnnotationsList();
+            switch (event.getType()) {
+                case TrackEvent.Type.TYPE_INSTANT:
+                    if (annotations.get(2).getIntValue() == MESSAGE) {
+                        instantCount++;
+                        assertThat(annotations.get(0).getStringValue()).isEqualTo("test");
+                        assertThat(event.getFlowIdsCount()).isEqualTo(1);
+                        flowIds.addAll(event.getFlowIdsList());
+                    }
+                    break;
+                case TrackEvent.Type.TYPE_COUNTER:
+                    counterCount++;
+                    break;
+                case TrackEvent.Type.TYPE_SLICE_BEGIN:
+                    annotations = event.getDebugAnnotationsList();
+                    if (flowIds.containsAll(event.getTerminatingFlowIdsList())) {
+                        beginCount++;
+                        assertThat(event.getTerminatingFlowIdsCount()).isEqualTo(1);
+                    }
+                    break;
+                case TrackEvent.Type.TYPE_SLICE_END:
+                    endCount++;
+                    break;
+                default:
+                    break;
+            }
+            collectInternedData(packet);
+        }
+
+        assertThat(hasTrackEvent).isTrue();
+        assertThat(mCategoryNames).contains("mq");
+        assertThat(mEventNames).contains("message_queue_send");
+        assertThat(mEventNames).contains("message_queue_receive");
+        assertThat(mDebugAnnotationNames).contains("what");
+        assertThat(mDebugAnnotationNames).contains("delay");
+        assertThat(instantCount).isEqualTo(MESSAGE_COUNT);
+        assertThat(beginCount).isEqualTo(MESSAGE_COUNT);
+        assertThat(endCount).isAtLeast(MESSAGE_COUNT);
+        assertThat(counterCount).isAtLeast(MESSAGE_COUNT);
+    }
+
     private TrackEvent getTrackEvent(Trace trace, int idx) {
         int curIdx = 0;
         for (TracePacket packet: trace.getPacketList()) {
diff --git a/core/tests/coretests/src/android/view/ViewFrameRateTest.java b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
index 8b4f714..45f1a09 100644
--- a/core/tests/coretests/src/android/view/ViewFrameRateTest.java
+++ b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
@@ -26,6 +26,7 @@
 import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY;
 import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_TOUCH_BOOST_25Q1;
 import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY;
+import static android.view.flags.Flags.FLAG_TOOLKIT_INITIAL_TOUCH_BOOST;
 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;
@@ -34,6 +35,7 @@
 
 import static junit.framework.Assert.assertEquals;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import android.annotation.NonNull;
@@ -180,6 +182,75 @@
     }
 
     @Test
+    @RequiresFlagsEnabled(FLAG_TOOLKIT_INITIAL_TOUCH_BOOST)
+    public void initialTouchBoost() throws Throwable {
+        if (!ViewProperties.vrr_enabled().orElse(true)) {
+            return;
+        }
+
+        mActivityRule.runOnUiThread(() -> {
+            ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams();
+            layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
+            layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
+            mMovingView.setLayoutParams(layoutParams);
+            mMovingView.setOnClickListener((v) -> {});
+        });
+        waitForFrameRateCategoryToSettle();
+
+        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();
+
+        assertFalse(mViewRoot.getIsTouchBoosting());
+
+        long now = SystemClock.uptimeMillis();
+        MotionEvent down = MotionEvent.obtain(
+                now, // downTime
+                now, // eventTime
+                MotionEvent.ACTION_DOWN, // action
+                position[0], // x
+                position[1], // y
+                0 // metaState
+        );
+
+        mActivityRule.runOnUiThread(() -> {
+            mMovingView.getViewRootImpl().dispatchAppVisibility(false);
+        });
+
+        down.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+        instrumentation.sendPointerSync(down);
+        down.recycle();
+
+        Thread.sleep(100);
+        // should have touch boost
+        assertTrue(mViewRoot.getIsTouchBoosting());
+
+        MotionEvent up = MotionEvent.obtain(
+                now, // downTime
+                now, // eventTime
+                MotionEvent.ACTION_UP, // action
+                position[0], // x
+                position[1], // y
+                0 // metaState
+        );
+        up.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+        instrumentation.sendPointerSync(up);
+        up.recycle();
+
+        // Should not be boosted if nothing is drawn
+        Thread.sleep(30);
+        assertFalse(mViewRoot.getIsTouchBoosting());
+
+        mActivityRule.runOnUiThread(() -> {
+            mMovingView.getViewRootImpl().dispatchAppVisibility(true);
+        });
+    }
+
+    @Test
     @RequiresFlagsEnabled(FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY)
     public void inputMethodWithContentMoves() throws Throwable {
         if (!ViewProperties.vrr_enabled().orElse(true)) {
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
index c40137f..a289df0 100644
--- a/core/tests/coretests/src/android/view/ViewRootImplTest.java
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -16,6 +16,8 @@
 
 package android.view;
 
+import static android.app.UiModeManager.MODE_NIGHT_NO;
+import static android.app.UiModeManager.MODE_NIGHT_YES;
 import static android.util.SequenceUtils.getInitSeq;
 import static android.view.HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING;
 import static android.view.InputDevice.SOURCE_ROTARY_ENCODER;
@@ -67,8 +69,10 @@
 import android.annotation.NonNull;
 import android.app.Instrumentation;
 import android.app.UiModeManager;
+import android.app.UiModeManager.ForceInvertType;
 import android.content.Context;
 import android.graphics.ForceDarkType;
+import android.graphics.ForceDarkType.ForceDarkTypeDef;
 import android.graphics.Rect;
 import android.hardware.display.DisplayManagerGlobal;
 import android.os.Binder;
@@ -93,9 +97,12 @@
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.compatibility.common.util.ShellIdentityUtils;
+import com.android.compatibility.common.util.TestUtils;
 import com.android.cts.input.BlockingQueueEventVerifier;
 import com.android.window.flags.Flags;
 
+import com.google.common.truth.Expect;
+
 import org.hamcrest.Matcher;
 import org.junit.After;
 import org.junit.AfterClass;
@@ -124,6 +131,8 @@
 
     @Rule
     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+    @Rule
+    public final Expect mExpect = Expect.create();
 
     private ViewRootImpl mViewRootImpl;
     private View mView;
@@ -1507,49 +1516,34 @@
     }
 
     @Test
-    public void forceInvertOffDarkThemeOff_forceDarkModeDisabled() {
-        mSetFlagsRule.enableFlags(FLAG_FORCE_INVERT_COLOR);
-        ShellIdentityUtils.invokeWithShellPermissions(() -> {
-            Settings.Secure.putInt(
-                    sContext.getContentResolver(),
-                    Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED,
-                    /* value= */ 0
-            );
-            var uiModeManager = sContext.getSystemService(UiModeManager.class);
-            uiModeManager.setNightMode(UiModeManager.MODE_NIGHT_NO);
-        });
+    @RequiresFlagsEnabled(FLAG_FORCE_INVERT_COLOR)
+    public void updateConfiguration_returnsExpectedForceDarkMode() {
+        waitForSystemNightModeActivated(true);
 
-        sInstrumentation.runOnMainSync(() ->
-                mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId())
-        );
+        verifyForceDarkType(/* isAppInNightMode= */ true, /* isForceInvertEnabled= */ true,
+                UiModeManager.FORCE_INVERT_TYPE_DARK, ForceDarkType.FORCE_INVERT_COLOR_DARK);
+        verifyForceDarkType(/* isAppInNightMode= */ true, /* isForceInvertEnabled= */ false,
+                UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE);
+        verifyForceDarkType(/* isAppInNightMode= */ false, /* isForceInvertEnabled= */ true,
+                UiModeManager.FORCE_INVERT_TYPE_DARK, ForceDarkType.FORCE_INVERT_COLOR_DARK);
+        verifyForceDarkType(/* isAppInNightMode= */ false, /* isForceInvertEnabled= */ false,
+                UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE);
 
-        assertThat(mViewRootImpl.determineForceDarkType()).isEqualTo(ForceDarkType.NONE);
+        waitForSystemNightModeActivated(false);
+
+        verifyForceDarkType(/* isAppInNightMode= */ true, /* isForceInvertEnabled= */ true,
+                UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE);
+        verifyForceDarkType(/* isAppInNightMode= */ true, /* isForceInvertEnabled= */ false,
+                UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE);
+        verifyForceDarkType(/* isAppInNightMode= */ false, /* isForceInvertEnabled= */ true,
+                UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE);
+        verifyForceDarkType(/* isAppInNightMode= */ false, /* isForceInvertEnabled= */ false,
+                UiModeManager.FORCE_INVERT_TYPE_OFF, ForceDarkType.NONE);
     }
 
     @Test
-    public void forceInvertOnDarkThemeOff_forceDarkModeEnabled() {
-        mSetFlagsRule.enableFlags(FLAG_FORCE_INVERT_COLOR);
-        ShellIdentityUtils.invokeWithShellPermissions(() -> {
-            Settings.Secure.putInt(
-                    sContext.getContentResolver(),
-                    Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED,
-                    /* value= */ 1
-            );
-            var uiModeManager = sContext.getSystemService(UiModeManager.class);
-            uiModeManager.setNightMode(UiModeManager.MODE_NIGHT_NO);
-        });
-
-        sInstrumentation.runOnMainSync(() ->
-                mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId())
-        );
-
-        assertThat(mViewRootImpl.determineForceDarkType())
-                .isEqualTo(ForceDarkType.FORCE_INVERT_COLOR_DARK);
-    }
-
-    @Test
+    @EnableFlags(FLAG_FORCE_INVERT_COLOR)
     public void forceInvertOffForceDarkOff_forceDarkModeDisabled() {
-        mSetFlagsRule.enableFlags(FLAG_FORCE_INVERT_COLOR);
         ShellIdentityUtils.invokeWithShellPermissions(() -> {
             Settings.Secure.putInt(
                     sContext.getContentResolver(),
@@ -1562,15 +1556,14 @@
         });
 
         sInstrumentation.runOnMainSync(() ->
-                mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId())
-        );
+                mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId()));
 
         assertThat(mViewRootImpl.determineForceDarkType()).isEqualTo(ForceDarkType.NONE);
     }
 
     @Test
+    @EnableFlags(FLAG_FORCE_INVERT_COLOR)
     public void forceInvertOffForceDarkOn_forceDarkModeEnabled() {
-        mSetFlagsRule.enableFlags(FLAG_FORCE_INVERT_COLOR);
         ShellIdentityUtils.invokeWithShellPermissions(() -> {
             Settings.Secure.putInt(
                     sContext.getContentResolver(),
@@ -1582,8 +1575,7 @@
         });
 
         sInstrumentation.runOnMainSync(() ->
-                mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId())
-        );
+                mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId()));
 
         assertThat(mViewRootImpl.determineForceDarkType()).isEqualTo(ForceDarkType.FORCE_DARK);
     }
@@ -1790,4 +1782,39 @@
                     () -> view.getViewTreeObserver().removeOnDrawListener(listener));
         }
     }
+
+    private void waitForSystemNightModeActivated(boolean active) {
+        ShellIdentityUtils.invokeWithShellPermissions(() ->
+                sInstrumentation.runOnMainSync(() -> {
+                    var uiModeManager = sContext.getSystemService(UiModeManager.class);
+                    uiModeManager.setNightModeActivated(active);
+                }));
+        sInstrumentation.waitForIdleSync();
+    }
+
+    private void verifyForceDarkType(boolean isAppInNightMode, boolean isForceInvertEnabled,
+            @ForceInvertType int expectedForceInvertType,
+            @ForceDarkTypeDef int expectedForceDarkType) {
+        var uiModeManager = sContext.getSystemService(UiModeManager.class);
+        ShellIdentityUtils.invokeWithShellPermissions(() -> {
+            uiModeManager.setApplicationNightMode(
+                    isAppInNightMode ? MODE_NIGHT_YES : MODE_NIGHT_NO);
+            Settings.Secure.putInt(
+                    sContext.getContentResolver(),
+                    Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED,
+                    isForceInvertEnabled ? 1 : 0);
+        });
+
+        sInstrumentation.runOnMainSync(() ->
+                mViewRootImpl.updateConfiguration(sContext.getDisplayNoVerify().getDisplayId()));
+        try {
+            TestUtils.waitUntil("Waiting for force invert state changed",
+                    () -> (uiModeManager.getForceInvertState() == expectedForceInvertType));
+        } catch (Exception e) {
+            Log.e(TAG, "Unexpected error trying to apply force invert state. " + e);
+            e.printStackTrace();
+        }
+
+        mExpect.that(mViewRootImpl.determineForceDarkType()).isEqualTo(expectedForceDarkType);
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/notification/NotificationChannelGroupsHelperTest.java b/core/tests/coretests/src/com/android/internal/notification/NotificationChannelGroupsHelperTest.java
new file mode 100644
index 0000000..26e96ea
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/notification/NotificationChannelGroupsHelperTest.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+
+import static com.android.internal.notification.NotificationChannelGroupsHelper.getGroupWithChannels;
+import static com.android.internal.notification.NotificationChannelGroupsHelper.getGroupsWithChannels;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.internal.notification.NotificationChannelGroupsHelper.Params;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+public class NotificationChannelGroupsHelperTest {
+    private Collection<NotificationChannel> mChannels;
+    private Map<String, NotificationChannelGroup> mGroups;
+
+    @Before
+    public void setUp() {
+        // Test data setup.
+        // Channels and their corresponding groups:
+        //   * "regular": a channel that is not deleted or blocked. In group A.
+        //   * "blocked": blocked channel. In group A.
+        //   * "deleted": deleted channel. In group A.
+        //   * "adrift": regular channel. No group.
+        //   * "gone": deleted channel. No group.
+        //   * "alternate": regular channel. In group B.
+        //   * "another blocked": blocked channel. In group B.
+        //   * "another deleted": deleted channel. In group C.
+        //   * Additionally, there is an empty group D.
+        mChannels = List.of(makeChannel("regular", "a", false, false),
+                makeChannel("blocked", "a", true, false),
+                makeChannel("deleted", "a", false, true),
+                makeChannel("adrift", null, false, false),
+                makeChannel("gone", null, false, true),
+                makeChannel("alternate", "b", false, false),
+                makeChannel("anotherBlocked", "b", true, false),
+                makeChannel("anotherDeleted", "c", false, true));
+
+        mGroups = Map.of("a", new NotificationChannelGroup("a", "a"),
+                "b", new NotificationChannelGroup("b", "b"),
+                "c", new NotificationChannelGroup("c", "c"),
+                "d", new NotificationChannelGroup("d", "d"));
+    }
+
+    @Test
+    public void testGetGroup_noDeleted() {
+        NotificationChannelGroup res = getGroupWithChannels("a", mChannels, mGroups, false);
+        assertThat(res).isNotNull();
+        assertThat(res.getChannels()).hasSize(2);  // "regular" & "blocked"
+        assertThat(res.getChannels()).containsExactlyElementsIn(List.of(
+                makeChannel("regular", "a", false, false),
+                makeChannel("blocked", "a", true, false)));
+    }
+
+    @Test
+    public void testGetGroup_includeDeleted() {
+        NotificationChannelGroup res = getGroupWithChannels("c", mChannels, mGroups, true);
+        assertThat(res).isNotNull();
+        assertThat(res.getChannels()).hasSize(1);
+        assertThat(res.getChannels().getFirst()).isEqualTo(
+                makeChannel("anotherDeleted", "c", false, true));
+    }
+
+    @Test
+    public void testGetGroup_empty() {
+        NotificationChannelGroup res = getGroupWithChannels("d", mChannels, mGroups, true);
+        assertThat(res).isNotNull();
+        assertThat(res.getChannels()).isEmpty();
+    }
+
+    @Test
+    public void testGetGroup_emptyBecauseNoChannelMatch() {
+        NotificationChannelGroup res = getGroupWithChannels("c", mChannels, mGroups, false);
+        assertThat(res).isNotNull();
+        assertThat(res.getChannels()).isEmpty();
+    }
+
+    @Test
+    public void testGetGroup_nonexistent() {
+        NotificationChannelGroup res = getGroupWithChannels("e", mChannels, mGroups, true);
+        assertThat(res).isNull();
+    }
+
+    @Test
+    public void testGetGroups_paramsForAllGroups() {
+        // deleted=false, nongrouped=false, empty=true, blocked=true, no channel filter
+        List<NotificationChannelGroup> res = getGroupsWithChannels(mChannels, mGroups,
+                Params.forAllGroups());
+
+        NotificationChannelGroup expectedA = new NotificationChannelGroup("a", "a");
+        expectedA.setChannels(List.of(
+                makeChannel("regular", "a", false, false),
+                makeChannel("blocked", "a", true, false)));
+
+        NotificationChannelGroup expectedB = new NotificationChannelGroup("b", "b");
+        expectedB.setChannels(List.of(
+                makeChannel("alternate", "b", false, false),
+                makeChannel("anotherBlocked", "b", true, false)));
+
+        NotificationChannelGroup expectedC = new NotificationChannelGroup("c", "c");
+        expectedC.setChannels(new ArrayList<>());  // empty, no deleted
+
+        NotificationChannelGroup expectedD = new NotificationChannelGroup("d", "d");
+        expectedD.setChannels(new ArrayList<>());  // empty
+
+        assertThat(res).containsExactly(expectedA, expectedB, expectedC, expectedD);
+    }
+
+    @Test
+    public void testGetGroups_paramsForAllChannels_noDeleted() {
+        // Excluding deleted channels to means group C is not included because it's "empty"
+        List<NotificationChannelGroup> res = getGroupsWithChannels(mChannels, mGroups,
+                Params.forAllChannels(false));
+
+        NotificationChannelGroup expectedA = new NotificationChannelGroup("a", "a");
+        expectedA.setChannels(List.of(
+                makeChannel("regular", "a", false, false),
+                makeChannel("blocked", "a", true, false)));
+
+        NotificationChannelGroup expectedB = new NotificationChannelGroup("b", "b");
+        expectedB.setChannels(List.of(
+                makeChannel("alternate", "b", false, false),
+                makeChannel("anotherBlocked", "b", true, false)));
+
+        NotificationChannelGroup expectedUngrouped = new NotificationChannelGroup(null, null);
+        expectedUngrouped.setChannels(List.of(
+                makeChannel("adrift", null, false, false),
+                makeChannel("gone", null, false, true)));
+
+        assertThat(res).containsExactly(expectedA, expectedB, expectedUngrouped);
+    }
+
+    @Test
+    public void testGetGroups_paramsForAllChannels_withDeleted() {
+        // This will get everything!
+        List<NotificationChannelGroup> res = getGroupsWithChannels(mChannels, mGroups,
+                Params.forAllChannels(true));
+
+        NotificationChannelGroup expectedA = new NotificationChannelGroup("a", "a");
+        expectedA.setChannels(List.of(
+                makeChannel("regular", "a", false, false),
+                makeChannel("blocked", "a", true, false),
+                makeChannel("deleted", "a", false, true)));
+
+        NotificationChannelGroup expectedB = new NotificationChannelGroup("b", "b");
+        expectedB.setChannels(List.of(
+                makeChannel("alternate", "b", false, false),
+                makeChannel("anotherBlocked", "b", true, false)));
+
+        NotificationChannelGroup expectedC = new NotificationChannelGroup("c", "c");
+        expectedC.setChannels(List.of(makeChannel("anotherDeleted", "c", false, true)));
+
+        // no D, because D is empty
+
+        NotificationChannelGroup expectedUngrouped = new NotificationChannelGroup(null, null);
+        expectedUngrouped.setChannels(List.of(makeChannel("adrift", null, false, false)));
+
+        assertThat(res).containsExactly(expectedA, expectedB, expectedC, expectedUngrouped);
+    }
+
+    @Test
+    public void testGetGroups_onlySpecifiedOrBlocked() {
+        Set<String> filter = Set.of("regular", "blocked", "adrift", "anotherDeleted");
+
+        // also not including deleted channels to check intersection of those params
+        List<NotificationChannelGroup> res = getGroupsWithChannels(mChannels, mGroups,
+                Params.onlySpecifiedOrBlockedChannels(filter));
+
+        NotificationChannelGroup expectedA = new NotificationChannelGroup("a", "a");
+        expectedA.setChannels(List.of(
+                makeChannel("regular", "a", false, false),
+                makeChannel("blocked", "a", true, false)));
+
+        // While nothing matches the filter from group B, includeBlocked=true means all blocked
+        // channels are included even if they are not in the filter.
+        NotificationChannelGroup expectedB = new NotificationChannelGroup("b", "b");
+        expectedB.setChannels(List.of(makeChannel("anotherBlocked", "b", true, false)));
+
+        NotificationChannelGroup expectedC = new NotificationChannelGroup("c", "c");
+        expectedC.setChannels(new ArrayList<>());  // deleted channel not included
+
+        NotificationChannelGroup expectedD = new NotificationChannelGroup("d", "d");
+        expectedD.setChannels(new ArrayList<>());  // empty
+
+        NotificationChannelGroup expectedUngrouped = new NotificationChannelGroup(null, null);
+        expectedUngrouped.setChannels(List.of(makeChannel("adrift", null, false, false)));
+
+        assertThat(res).containsExactly(expectedA, expectedB, expectedC, expectedD,
+                expectedUngrouped);
+    }
+
+
+    @Test
+    public void testGetGroups_noBlockedWithFilter() {
+        Set<String> filter = Set.of("regular", "blocked", "adrift");
+
+        // The includeBlocked setting only takes effect if there is a channel filter.
+        List<NotificationChannelGroup> res = getGroupsWithChannels(mChannels, mGroups,
+                new Params(true, true, true, false, filter));
+
+        // Even though includeBlocked=false, "blocked" is included because it's explicitly specified
+        // by the channel filter.
+        NotificationChannelGroup expectedA = new NotificationChannelGroup("a", "a");
+        expectedA.setChannels(List.of(
+                makeChannel("regular", "a", false, false),
+                makeChannel("blocked", "a", true, false)));
+
+        NotificationChannelGroup expectedB = new NotificationChannelGroup("b", "b");
+        expectedB.setChannels(new ArrayList<>());  // no matches; blocked channel not in filter
+
+        NotificationChannelGroup expectedC = new NotificationChannelGroup("c", "c");
+        expectedC.setChannels(new ArrayList<>());  // no matches
+
+        NotificationChannelGroup expectedD = new NotificationChannelGroup("d", "d");
+        expectedD.setChannels(new ArrayList<>());  // empty
+
+        NotificationChannelGroup expectedUngrouped = new NotificationChannelGroup(null, null);
+        expectedUngrouped.setChannels(List.of(makeChannel("adrift", null, false, false)));
+
+        assertThat(res).containsExactly(expectedA, expectedB, expectedC, expectedD,
+                expectedUngrouped);
+    }
+
+    private NotificationChannel makeChannel(String id, String groupId, boolean blocked,
+            boolean deleted) {
+        NotificationChannel c = new NotificationChannel(id, id,
+                blocked ? IMPORTANCE_NONE : IMPORTANCE_DEFAULT);
+        if (deleted) {
+            c.setDeleted(true);
+        }
+        if (groupId != null) {
+            c.setGroup(groupId);
+        }
+        return c;
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/notification/OWNERS b/core/tests/coretests/src/com/android/internal/notification/OWNERS
new file mode 100644
index 0000000..396fd12
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/notification/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/notification/OWNERS
diff --git a/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java b/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
index 36c73e2..c42ddd3 100644
--- a/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
+++ b/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
@@ -44,8 +44,11 @@
             "com.android.server.om.hosttest.update_overlay_test";
     private static final String DEVICE_TEST_CLS = DEVICE_TEST_PKG + ".UpdateOverlayTest";
 
+    private int mCurrentUserid;
+
     @Before
     public void ensureNoOverlays() throws Exception {
+        mCurrentUserid = getDevice().getCurrentUser();
         // Make sure we're starting with a clean slate.
         for (String pkg : ALL_PACKAGES) {
             assertFalse(pkg + " should not be installed", isPackageInstalled(pkg));
@@ -62,7 +65,7 @@
     @After
     public void uninstallOverlays() throws Exception {
         for (String pkg : ALL_PACKAGES) {
-            uninstallPackage(pkg);
+            getDevice().uninstallPackageForUser(pkg, mCurrentUserid);
         }
     }
 
@@ -166,7 +169,7 @@
         installPackage("OverlayHostTests_AppOverlayV1.apk");
         assertTrue(getDevice().executeShellCommand("cat /data/system/overlays.xml")
                 .contains(APP_OVERLAY_PACKAGE_NAME));
-        uninstallPackage(APP_OVERLAY_PACKAGE_NAME);
+        getDevice().uninstallPackageForUser(APP_OVERLAY_PACKAGE_NAME, mCurrentUserid);
         delay();
         assertFalse(getDevice().executeShellCommand("cat /data/system/overlays.xml")
                 .contains(APP_OVERLAY_PACKAGE_NAME));
@@ -200,12 +203,12 @@
     }
 
     private void installPackage(String pkg) throws Exception {
-        super.installPackage(pkg);
+        super.installPackageAsUser(pkg, true /* grantPermission */, mCurrentUserid);
         delay();
     }
 
     private void installInstantPackage(String pkg) throws Exception {
-        super.installPackage(pkg, "--instant");
+        super.installPackageAsUser(pkg, true /* grantPermission */, mCurrentUserid, "--instant");
         delay();
     }
 
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 1edbffa..15f7029 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -259,6 +259,7 @@
         <permission name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
         <permission name="android.permission.ACCESS_LOWPAN_STATE"/>
         <permission name="android.permission.BACKUP"/>
+        <permission name="android.permission.ENTER_TRADE_IN_MODE"/>
         <!-- Needed for GMSCore Location API test only -->
         <permission name="android.permission.LOCATION_BYPASS"/>
         <!-- Needed for test only -->
@@ -294,6 +295,8 @@
         <permission name="android.permission.INSTALL_PACKAGE_UPDATES"/>
         <permission name="android.permission.KILL_ALL_BACKGROUND_PROCESSES"/>
         <!-- Needed for test only -->
+        <permission name="android.permission.LISTEN_FOR_KEY_ACTIVITY" />
+        <!-- Needed for test only -->
         <permission name="android.permission.ACCESS_MTP"/>
         <!-- Needed for test only -->
         <permission name="android.permission.INTERACT_ACROSS_PROFILES"/>
diff --git a/libs/WindowManager/Shell/multivalentTests/AndroidManifest.xml b/libs/WindowManager/Shell/multivalentTests/AndroidManifest.xml
index fd578a9..95cd1c7 100644
--- a/libs/WindowManager/Shell/multivalentTests/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/multivalentTests/AndroidManifest.xml
@@ -1,10 +1,19 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.wm.shell.multivalenttests">
 
+    <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS"/>
+
     <application android:debuggable="true" android:supportsRtl="true" >
         <uses-library android:name="android.test.runner" />
         <activity android:name="com.android.wm.shell.bubbles.bar.BubbleBarAnimationHelperTest$TestActivity"
             android:exported="true"/>
+
+        <activity android:name=".bubbles.TestActivity"
+            android:allowEmbedded="true"
+            android:documentLaunchMode="always"
+            android:excludeFromRecents="true"
+            android:exported="false"
+            android:resizeableActivity="true" />
     </application>
 
     <instrumentation
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt
index 09a93d5..bce6c59 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt
@@ -35,7 +35,6 @@
 import com.android.wm.shell.Flags
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.bubbles.Bubbles.SysuiProxy
-import com.android.wm.shell.bubbles.properties.ProdBubbleProperties
 import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.DisplayImeController
@@ -48,6 +47,7 @@
 import com.android.wm.shell.shared.TransactionPool
 import com.android.wm.shell.shared.bubbles.BubbleBarLocation
 import com.android.wm.shell.shared.bubbles.BubbleBarUpdate
+import com.android.wm.shell.shared.bubbles.DeviceConfig
 import com.android.wm.shell.sysui.ShellCommandHandler
 import com.android.wm.shell.sysui.ShellController
 import com.android.wm.shell.sysui.ShellInit
@@ -288,7 +288,7 @@
             mock<Transitions>(),
             SyncTransactionQueue(TransactionPool(), mainExecutor),
             mock<IWindowManager>(),
-            ProdBubbleProperties,
+            BubbleResizabilityChecker()
         )
     }
 
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerTest.kt
new file mode 100644
index 0000000..cec67f2
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerTest.kt
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.content.Context
+import android.content.Intent
+import android.content.pm.LauncherApps
+import android.content.pm.PackageManager
+import android.graphics.drawable.Icon
+import android.os.Handler
+import android.os.UserHandle
+import android.os.UserManager
+import android.view.IWindowManager
+import android.view.WindowManager
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.internal.protolog.ProtoLog
+import com.android.internal.statusbar.IStatusBarService
+import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.bubbles.Bubbles.SysuiProxy
+import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.DisplayImeController
+import com.android.wm.shell.common.DisplayInsetsController
+import com.android.wm.shell.common.FloatingContentCoordinator
+import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.common.TaskStackListenerImpl
+import com.android.wm.shell.common.TestShellExecutor
+import com.android.wm.shell.common.TestSyncExecutor
+import com.android.wm.shell.draganddrop.DragAndDropController
+import com.android.wm.shell.recents.RecentTasksController
+import com.android.wm.shell.shared.TransactionPool
+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.taskview.TaskViewRepository
+import com.android.wm.shell.taskview.TaskViewTransitions
+import com.android.wm.shell.transition.Transitions
+import com.android.wm.shell.unfold.UnfoldAnimationController
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
+import java.util.Optional
+
+/** Tests for [BubbleControllerTest] */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BubbleControllerTest {
+
+    private val context = ApplicationProvider.getApplicationContext<Context>()
+
+    private lateinit var bubbleController: BubbleController
+    private lateinit var bubblePositioner: BubblePositioner
+    private lateinit var uiEventLoggerFake: UiEventLoggerFake
+    private lateinit var bubbleLogger: BubbleLogger
+    private lateinit var mainExecutor: TestShellExecutor
+    private lateinit var bgExecutor: TestShellExecutor
+    private lateinit var bubbleData: BubbleData
+    private lateinit var eduController: BubbleEducationController
+
+    @Before
+    fun setUp() {
+        ProtoLog.REQUIRE_PROTOLOGTOOL = false
+        ProtoLog.init()
+
+        uiEventLoggerFake = UiEventLoggerFake()
+        bubbleLogger = BubbleLogger(uiEventLoggerFake)
+        eduController = BubbleEducationController(context)
+
+        mainExecutor = TestShellExecutor()
+        bgExecutor = TestShellExecutor()
+
+        // Tests don't have permission to add our window to windowManager, so we mock it :(
+        val windowManager = mock<WindowManager>()
+        val realWindowManager = context.getSystemService(WindowManager::class.java)
+        // But we do want the metrics from the real one
+        whenever(windowManager.currentWindowMetrics)
+            .thenReturn(realWindowManager.currentWindowMetrics)
+
+        bubblePositioner = BubblePositioner(context, windowManager)
+        bubblePositioner.setShowingInBubbleBar(true)
+
+        bubbleData = BubbleData(
+            context, bubbleLogger, bubblePositioner, eduController,
+            mainExecutor, bgExecutor
+        )
+
+        bubbleController =
+            createBubbleController(
+                bubbleData,
+                windowManager,
+                bubbleLogger,
+                bubblePositioner,
+                mainExecutor,
+                bgExecutor,
+            )
+        bubbleController.asBubbles().setSysuiProxy(Mockito.mock(SysuiProxy::class.java))
+        // Flush so that proxy gets set
+        mainExecutor.flushAll()
+    }
+
+    @After
+    fun tearDown() {
+        getInstrumentation().waitForIdleSync()
+    }
+
+    @Test
+    fun showOrHideNotesBubble_createsNoteBubble() {
+        val intent = Intent(context, TestActivity::class.java)
+        intent.setPackage(context.packageName)
+        val user = UserHandle.of(0)
+        val expectedKey = Bubble.getNoteBubbleKeyForApp(intent.getPackage(), user)
+
+        getInstrumentation().runOnMainSync {
+            bubbleController.showOrHideNotesBubble(intent, user, mock<Icon>())
+        }
+        getInstrumentation().waitForIdleSync()
+
+        assertThat(bubbleController.hasBubbles()).isTrue()
+        assertThat(bubbleData.getAnyBubbleWithKey(expectedKey)).isNotNull()
+        assertThat(bubbleData.getAnyBubbleWithKey(expectedKey)!!.isNoteBubble).isTrue()
+    }
+
+
+    fun createBubbleController(
+        bubbleData: BubbleData,
+        windowManager: WindowManager?,
+        bubbleLogger: BubbleLogger,
+        bubblePositioner: BubblePositioner,
+        mainExecutor: TestShellExecutor,
+        bgExecutor: TestShellExecutor,
+    ): BubbleController {
+        val shellInit = ShellInit(mainExecutor)
+        val shellCommandHandler = ShellCommandHandler()
+        val shellController =
+            ShellController(
+                context,
+                shellInit,
+                shellCommandHandler,
+                mock<DisplayInsetsController>(),
+                mainExecutor,
+            )
+        val surfaceSynchronizer = { obj: Runnable -> obj.run() }
+
+        val bubbleDataRepository =
+            BubbleDataRepository(
+                mock<LauncherApps>(),
+                mainExecutor,
+                bgExecutor,
+                BubblePersistentRepository(context),
+            )
+
+        val shellTaskOrganizer = ShellTaskOrganizer(
+            Mockito.mock<ShellInit>(ShellInit::class.java),
+            ShellCommandHandler(),
+            null,
+            Optional.empty<UnfoldAnimationController>(),
+            Optional.empty<RecentTasksController>(),
+            TestSyncExecutor()
+        )
+
+        val resizeChecker: ResizabilityChecker =
+            object : ResizabilityChecker {
+                override fun isResizableActivity(
+                    intent: Intent?,
+                    packageManager: PackageManager, key: String
+                ): Boolean {
+                    return true
+                }
+            }
+
+        val bubbleController = BubbleController(
+            context,
+            shellInit,
+            shellCommandHandler,
+            shellController,
+            bubbleData,
+            surfaceSynchronizer,
+            FloatingContentCoordinator(),
+            bubbleDataRepository,
+            mock<IStatusBarService>(),
+            windowManager,
+            mock<DisplayInsetsController>(),
+            mock<DisplayImeController>(),
+            mock<UserManager>(),
+            mock<LauncherApps>(),
+            bubbleLogger,
+            mock<TaskStackListenerImpl>(),
+            shellTaskOrganizer,
+            bubblePositioner,
+            mock<DisplayController>(),
+            Optional.empty(),
+            mock<DragAndDropController>(),
+            mainExecutor,
+            mock<Handler>(),
+            bgExecutor,
+            mock<TaskViewRepository>(),
+            mock<TaskViewTransitions>(),
+            mock<Transitions>(),
+            SyncTransactionQueue(TransactionPool(), mainExecutor),
+            mock<IWindowManager>(),
+            resizeChecker,
+        )
+        bubbleController.setInflateSynchronously(true)
+        bubbleController.onInit()
+
+        return bubbleController
+    }
+}
\ 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 1d0c505..ec1add2 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
@@ -31,6 +31,7 @@
 import com.android.wm.shell.R
 import com.android.wm.shell.bubbles.BubblePositioner.MAX_HEIGHT
 import com.android.wm.shell.shared.bubbles.BubbleBarLocation
+import com.android.wm.shell.shared.bubbles.DeviceConfig
 import com.google.common.truth.Truth.assertThat
 import com.google.common.util.concurrent.MoreExecutors.directExecutor
 import org.junit.Before
@@ -154,19 +155,19 @@
 
     /** Test that the default resting position on tablet is middle right. */
     @Test
-    fun testGetDefaultPosition_appBubble_onTablet() {
+    fun testGetDefaultPosition_noteBubble_onTablet() {
         positioner.update(defaultDeviceConfig.copy(isLargeScreen = true))
         val allowableStackRegion = positioner.getAllowableStackPositionRegion(1 /* bubbleCount */)
-        val startPosition = positioner.getDefaultStartPosition(true /* isAppBubble */)
+        val startPosition = positioner.getDefaultStartPosition(true /* isNoteBubble */)
         assertThat(startPosition.x).isEqualTo(allowableStackRegion.right)
         assertThat(startPosition.y).isEqualTo(defaultYPosition)
     }
 
     @Test
-    fun testGetRestingPosition_appBubble_onTablet_RTL() {
+    fun testGetRestingPosition_noteBubble_onTablet_RTL() {
         positioner.update(defaultDeviceConfig.copy(isLargeScreen = true, isRtl = true))
         val allowableStackRegion = positioner.getAllowableStackPositionRegion(1 /* bubbleCount */)
-        val startPosition = positioner.getDefaultStartPosition(true /* isAppBubble */)
+        val startPosition = positioner.getDefaultStartPosition(true /* isNoteBubble */)
         assertThat(startPosition.x).isEqualTo(allowableStackRegion.left)
         assertThat(startPosition.y).isEqualTo(defaultYPosition)
     }
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt
index f1ba042..77aee98 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt
@@ -35,7 +35,6 @@
 import com.android.internal.statusbar.IStatusBarService
 import com.android.launcher3.icons.BubbleIconFactory
 import com.android.wm.shell.ShellTaskOrganizer
-import com.android.wm.shell.bubbles.properties.BubbleProperties
 import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.DisplayImeController
@@ -161,7 +160,7 @@
                 mock<Transitions>(),
                 SyncTransactionQueue(TransactionPool(), mainExecutor),
                 mock<IWindowManager>(),
-                mock<BubbleProperties>()
+                BubbleResizabilityChecker()
             )
 
         // TODO: (b/371829099) - when optional overflow is no longer flagged we can enable this
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleExpandedViewManager.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleExpandedViewManager.kt
index 3c013d3..adcd835 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleExpandedViewManager.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleExpandedViewManager.kt
@@ -38,7 +38,7 @@
 
     override fun dismissBubble(bubble: Bubble, reason: Int) {}
 
-    override fun setAppBubbleTaskId(key: String, taskId: Int) {}
+    override fun setNoteBubbleTaskId(key: String, taskId: Int) {}
 
     override fun isStackExpanded(): Boolean {
         return expanded
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/TestActivity.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/TestActivity.kt
new file mode 100644
index 0000000..40e80d0
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/TestActivity.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.app.Activity
+import android.os.Bundle
+import android.widget.FrameLayout
+
+class TestActivity : Activity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(FrameLayout(getApplicationContext()))
+    }
+}
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt
index d3cfbd0..68b3d88 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt
@@ -42,10 +42,10 @@
 import com.android.wm.shell.bubbles.BubbleOverflow
 import com.android.wm.shell.bubbles.BubblePositioner
 import com.android.wm.shell.bubbles.BubbleTaskView
-import com.android.wm.shell.bubbles.DeviceConfig
 import com.android.wm.shell.bubbles.FakeBubbleExpandedViewManager
 import com.android.wm.shell.bubbles.FakeBubbleFactory
 import com.android.wm.shell.common.TestShellExecutor
+import com.android.wm.shell.shared.bubbles.DeviceConfig
 import com.android.wm.shell.taskview.TaskView
 import com.android.wm.shell.taskview.TaskViewController
 import com.android.wm.shell.taskview.TaskViewTaskController
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt
index 7f65e22..037bd22 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt
@@ -39,11 +39,11 @@
 import com.android.wm.shell.bubbles.BubblePositioner
 import com.android.wm.shell.bubbles.BubbleTaskView
 import com.android.wm.shell.bubbles.BubbleTaskViewFactory
-import com.android.wm.shell.bubbles.DeviceConfig
 import com.android.wm.shell.bubbles.FakeBubbleExpandedViewManager
 import com.android.wm.shell.bubbles.RegionSamplingProvider
 import com.android.wm.shell.bubbles.UiEventSubject.Companion.assertThat
 import com.android.wm.shell.common.TestShellExecutor
+import com.android.wm.shell.shared.bubbles.DeviceConfig
 import com.android.wm.shell.shared.handles.RegionSamplingHelper
 import com.android.wm.shell.taskview.TaskView
 import com.android.wm.shell.taskview.TaskViewController
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
index a649247..c022a29 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
@@ -43,13 +43,13 @@
 import com.android.wm.shell.bubbles.BubbleExpandedViewManager
 import com.android.wm.shell.bubbles.BubbleLogger
 import com.android.wm.shell.bubbles.BubblePositioner
+import com.android.wm.shell.bubbles.BubbleResizabilityChecker
 import com.android.wm.shell.bubbles.Bubbles.SysuiProxy
 import com.android.wm.shell.bubbles.FakeBubbleExpandedViewManager
 import com.android.wm.shell.bubbles.FakeBubbleFactory
 import com.android.wm.shell.bubbles.FakeBubbleTaskViewFactory
 import com.android.wm.shell.bubbles.UiEventSubject.Companion.assertThat
 import com.android.wm.shell.bubbles.animation.AnimatableScaleMatrix
-import com.android.wm.shell.bubbles.properties.BubbleProperties
 import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.DisplayImeController
@@ -200,7 +200,7 @@
             mock<Transitions>(),
             SyncTransactionQueue(TransactionPool(), mainExecutor),
             mock<IWindowManager>(),
-            mock<BubbleProperties>(),
+            BubbleResizabilityChecker()
         )
     }
 
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 d4cbe6e..1b0e11f 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
@@ -30,13 +30,13 @@
 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
 import com.android.wm.shell.shared.bubbles.BaseBubblePinController
 import com.android.wm.shell.shared.bubbles.BaseBubblePinController.Companion.DROP_TARGET_ALPHA_IN_DURATION
 import com.android.wm.shell.shared.bubbles.BaseBubblePinController.Companion.DROP_TARGET_ALPHA_OUT_DURATION
 import com.android.wm.shell.shared.bubbles.BubbleBarLocation
 import com.android.wm.shell.shared.bubbles.BubbleBarLocation.LEFT
 import com.android.wm.shell.shared.bubbles.BubbleBarLocation.RIGHT
+import com.android.wm.shell.shared.bubbles.DeviceConfig
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
 import org.junit.Before
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/common/TestSyncExecutor.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/common/TestSyncExecutor.kt
new file mode 100644
index 0000000..50d9f77
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/common/TestSyncExecutor.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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
+
+class TestSyncExecutor : ShellExecutor {
+    override fun execute(runnable: Runnable) {
+        runnable.run()
+    }
+
+    override fun executeDelayed(runnable: Runnable, delayMillis: Long) {
+        runnable.run()
+    }
+
+    override fun removeCallbacks(runnable: Runnable) {
+    }
+
+    override fun hasCallback(runnable: Runnable): Boolean {
+        return false
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_16.xml b/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_16.xml
new file mode 100644
index 0000000..c2a20b9
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_16.xml
@@ -0,0 +1,28 @@
+<?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
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="16dp"
+    android:height="16dp"
+    android:viewportWidth="16"
+    android:viewportHeight="16"
+    android:tint="?android:attr/textColorSecondary">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M 8 11.375 L 2 5.375 L 3.4 3.975 L 8 8.575 L 12.6 3.975 L 14 5.375 L 8 11.375 Z"
+        />
+</vector>
+
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_app_header.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_app_header.xml
index 87c520c..b898e4b 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_app_header.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_app_header.xml
@@ -64,7 +64,7 @@
             android:id="@+id/expand_menu_button"
             android:layout_width="16dp"
             android:layout_height="16dp"
-            android:src="@drawable/ic_baseline_expand_more_24"
+            android:src="@drawable/ic_baseline_expand_more_16"
             android:background="@null"
             android:scaleType="fitCenter"
             android:clickable="false"
@@ -101,7 +101,7 @@
         android:layout_width="44dp"
         android:layout_height="40dp"
         android:layout_gravity="end"
-        android:layout_marginHorizontal="8dp"
+        android:layout_marginEnd="8dp"
         android:clickable="true"
         android:focusable="true"/>
 
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index a975682..13e5f34 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Links 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Links 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Volskerm regs"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Volskerm bo"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Bo 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Bo 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Stel terug"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Spring na links"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Spring na regs"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Maak By Verstek Oop-instellings"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Kies hoe om webskakels vir hierdie app oop te maak"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In die app"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index a6921b9..14a79aa 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ግራ 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ግራ 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"የቀኝ ሙሉ ማያ ገፅ"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"የላይ ሙሉ ማያ ገፅ"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ከላይ 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ከላይ 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ወደነበረበት መልስ"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ወደ ግራ አሳድግ"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ወደ ቀኝ አሳድግ"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"በነባሪ ቅንብሮች ክፈት"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ለዚህ የድር መተግበሪያ አገናኙን እንዴት እንደሚከፍቱ ይምረጡ"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"በመተግበሪያው ውስጥ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index b72d255..206a8de 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ضبط حجم النافذة اليسرى ليكون ٥٠%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ضبط حجم النافذة اليسرى ليكون ٣٠%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"عرض النافذة اليمنى بملء الشاشة"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"عرض النافذة العلوية بملء الشاشة"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ضبط حجم النافذة العلوية ليكون ٧٠%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ضبط حجم النافذة العلوية ليكون ٥٠%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"استعادة"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"المحاذاة إلى اليسار"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"المحاذاة إلى اليمين"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"إعدادات الفتح تلقائيًا"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"اختيار طريقة فتح روابط الويب لهذا التطبيق"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"في التطبيق"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 632d126..28acb10 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"বাওঁফালৰ স্ক্ৰীনখন ৫০% কৰক"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"বাওঁফালৰ স্ক্ৰীনখন ৩০% কৰক"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"সোঁফালৰ স্ক্ৰীনখন সম্পূৰ্ণ স্ক্ৰীন কৰক"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"শীৰ্ষ স্ক্ৰীনখন সম্পূৰ্ণ স্ক্ৰীন কৰক"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"শীর্ষ স্ক্ৰীনখন ৭০% কৰক"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"শীর্ষ স্ক্ৰীনখন ৫০% কৰক"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"পুনঃস্থাপন কৰক"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"বাওঁফাললৈ স্নেপ কৰক"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"সোঁফাললৈ স্নেপ কৰক"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ডিফ’ল্ট ছেটিং খোলক"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"এই এপ্‌টোৰ বাবে কিদৰে ৱেব লিংক খুলিব পাৰি সেয়া বাছনি কৰক"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"এপ্‌টোত"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index cf9f1b2..5181930 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Sol 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Sol 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Sağ tam ekran"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Yuxarı tam ekran"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Yuxarı 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Yuxarı 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Bərpa edin"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Sola tərəf çəkin"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Sağa tərəf çəkin"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Defolt ayarlarla açın"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Bu tətbiq üçün veb-linklərin necə açılacağını seçin"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Tətbiqdə"</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 c2d4d8b..207ac27 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Levi ekran 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Levi ekran 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Režim celog ekrana za donji ekran"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Režim celog ekrana za gornji ekran"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Gornji ekran 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gornji ekran 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Vratite"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Prikačite levo"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Prikačite desno"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Podešavanje Podrazumevano otvaraj"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Odaberite način otvaranja veb-linkova za ovu aplikaciju"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"U aplikaciji"</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index dde2374..abaa834 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Левы экран – 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Левы экран – 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Правы экран – поўнаэкранны рэжым"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Верхні экран – поўнаэкранны рэжым"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Верхні экран – 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Верхні экран – 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Аднавіць"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Размясціць злева"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Размясціць справа"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Налады параметра \"Адкрываць стандартна\""</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Выберыце, як гэта праграма будзе адкрываць вэб-спасылкі"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"У праграме"</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index 7e80484..e7feb5b 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ляв екран: 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Ляв екран: 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Десен екран: Показване на цял екран"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Горен екран: Показване на цял екран"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Горен екран: 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горен екран: 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Възстановяване"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Прилепване наляво"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Прилепване надясно"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Отваряне на настройките по подразбиране"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Изберете как да се отварят уеб връзките за това приложение"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"В приложението"</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index 4c6e6c1..f4f8877 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"৫০% বাকি আছে"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"৩০% বাকি আছে"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"ডান দিকের অংশ নিয়ে পূর্ণ স্ক্রিন"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"উপর দিকের অংশ নিয়ে পূর্ণ স্ক্রিন"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"শীর্ষ ৭০%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"শীর্ষ ৫০%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ফিরিয়ে আনুন"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"বাঁদিকে স্ন্যাপ করুন"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ডানদিকে স্ন্যাপ করুন"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ডিফল্ট হিসেবে থাকা সেটিংস খুলুন"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"এই অ্যাপের জন্য কীভাবে ওয়েব লিঙ্ক খুলবেন তা বেছে নিন"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"অ্যাপের মধ্যে"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 244149b..8982d61 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Lijevo 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Lijevo 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Desno cijeli ekran"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Gore cijeli ekran"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Gore 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gore 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Vraćanje"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Pomicanje ulijevo"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Pomicanje udesno"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Otvaranje prema zadanim postavkama"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Odaberite način otvaranja web linkova za ovu aplikaciju"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"U aplikaciji"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 786ed76..1623954 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Pantalla esquerra al 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Pantalla esquerra al 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Pantalla dreta completa"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Pantalla superior completa"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Pantalla superior al 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Pantalla superior al 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaura"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ajusta a l\'esquerra"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Ajusta a la dreta"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Configuració d\'obertura predeterminada"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Tria com vols obrir els enllaços web per a aquesta aplicació"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"A l\'aplicació"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index 99e9a83..f6ac59c 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % vlevo"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30 % vlevo"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Pravá část na celou obrazovku"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Horní část na celou obrazovku"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70 % nahoře"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % nahoře"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Obnovit"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Přichytit vlevo"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Přichytit vpravo"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Otevírat podle výchozího nastavení"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Určete, jak se v této aplikaci mají otevírat webové odkazy"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"V aplikaci"</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index 6021a96..2cf725e 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Venstre 50 %"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Venstre 30 %"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Vis højre del i fuld skærm"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Vis øverste del i fuld skærm"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Øverste 70 %"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Øverste 50 %"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Gendan"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Fastgør til venstre"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Fastgør til højre"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Indstillinger for automatisk åbning"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Vælg, hvordan denne app skal åben weblinks"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"I appen"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 7b29662..d7ee8a0 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % links"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30 % links"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Vollbild rechts"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Vollbild oben"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70 % oben"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % oben"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Wiederherstellen"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Links andocken"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Rechts andocken"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Einstellungen für die Option „Standardmäßig öffnen“"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Festlegen, wie Weblinks für diese App geöffnet werden"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In der App"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 879347ad..4ba68b4 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Αριστερή 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Αριστερή 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Δεξιά πλήρης οθόνη"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Πάνω πλήρης οθόνη"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Πάνω 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Πάνω 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Επαναφορά"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Κούμπωμα αριστερά"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Κούμπωμα δεξιά"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Άνοιγμα ρυθμίσεων από προεπιλογή"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Επιλογή τρόπου ανοίγματος συνδέσμων ιστού για την εφαρμογή"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Στην εφαρμογή"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index 358e314..8b1a14f 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Left 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Right full screen"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Top full screen"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Top 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Top 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restore"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Snap left"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Snap right"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Open by default settings"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Choose how to open web links for this app"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In the app"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index 923f30b..20d141e 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -43,6 +43,7 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Left 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Right full screen"</string>
+    <string name="accessibility_action_divider_swap" msgid="7026003137401725787">"Swap Apps"</string>
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Top full screen"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Top 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Top 50%"</string>
@@ -141,6 +142,16 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restore"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Snap left"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Snap right"</string>
+    <string name="desktop_mode_a11y_action_snap_left" msgid="2932955411661734668">"Resize app window left"</string>
+    <string name="desktop_mode_a11y_action_snap_right" msgid="4577032451624261787">"Resize app window right"</string>
+    <string name="desktop_mode_a11y_action_maximize_restore" msgid="8026037983417986686">"Maximize or restore window size"</string>
+    <string name="app_handle_menu_talkback_split_screen_mode_button_text" msgid="7182959681057464802">"Enter split screen mode"</string>
+    <string name="app_handle_menu_talkback_desktop_mode_button_text" msgid="1230110046930843630">"Enter desktop windowing mode"</string>
+    <string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"Resize window to left"</string>
+    <string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"Resize window to right"</string>
+    <string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"Maximize or restore window size"</string>
+    <string name="maximize_button_talkback_action_maximize_restore_text" msgid="4122441323153198455">"Maximize or restore window size"</string>
+    <string name="minimize_button_talkback_action_maximize_restore_text" msgid="8890767445425625935">"Minimize app window"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Open by default settings"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Choose how to open web links for this app"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In the app"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index 358e314..8b1a14f 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Left 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Right full screen"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Top full screen"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Top 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Top 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restore"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Snap left"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Snap right"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Open by default settings"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Choose how to open web links for this app"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In the app"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index 358e314..8b1a14f 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Left 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Left 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Right full screen"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Top full screen"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Top 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Top 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restore"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Snap left"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Snap right"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Open by default settings"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Choose how to open web links for this app"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In the app"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 7a2e8cf..c8fa76e 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Izquierda: 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Izquierda: 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Pantalla derecha completa"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Pantalla superior completa"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Superior: 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Superior: 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restablecer"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ajustar a la izquierda"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Ajustar a la derecha"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Abrir con la configuración predeterminada"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Elige cómo abrir vínculos web para esta app"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"En la app"</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index 2a30bfb..f36135e 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Izquierda 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Izquierda 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Pantalla derecha completa"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Pantalla superior completa"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Superior 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Superior 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurar"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Acoplar a la izquierda"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Acoplar a la derecha"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Abrir con los ajustes predeterminados"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Elige cómo quieres abrir los enlaces web de esta aplicación"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"En la aplicación"</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index 9a15f90..28943a7 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vasak: 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Vasak: 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Parem täisekraan"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Ülemine täisekraan"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Ülemine: 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Ülemine: 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Taasta"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Tõmmake vasakule"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Tõmmake paremale"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Avamisviisi vaikeseaded"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Valige, kuidas avada selle rakenduse puhul veebilinke"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Rakenduses"</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index 7c03b24..b77d0eb 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ezarri ezkerraldea % 50en"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Ezarri ezkerraldea % 30en"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Ezarri eskuinaldea pantaila osoan"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Ezarri goialdea pantaila osoan"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Ezarri goialdea % 70en"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Ezarri goialdea % 50en"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Leheneratu"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ezarri ezkerrean"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Ezarri eskuinean"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Modu lehenetsian irekitzearen ezarpenak"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Aukeratu nola ireki sareko estekak aplikazio honetan"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Aplikazioan"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index f9a3c35..fba9aa2 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"٪۵۰ چپ"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"٪۳۰ چپ"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"تمام‌صفحه راست"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"تمام‌صفحه بالا"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"٪۷۰ بالا"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"٪۵۰ بالا"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"بازیابی کردن"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"کشیدن به‌چپ"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"کشیدن به‌راست"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"تنظیمات باز کردن به‌طور پیش‌فرض"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"انتخاب روش باز کردن پیوندهای وب مربوط به این برنامه"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"در برنامه"</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index d89e36a..06ff6e7 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vasen 50 %"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Vasen 30 %"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Oikea koko näytölle"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Yläosa koko näytölle"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Yläosa 70 %"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Yläosa 50 %"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Palauta"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Siirrä vasemmalle"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Siirrä oikealle"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Avaa oletusasetusten mukaan"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Valitse, miten verkkolinkit avataan tässä sovelluksessa"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Sovelluksessa"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index e2730d4..08ff1d3 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % à la gauche"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30 % à la gauche"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Plein écran à la droite"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Plein écran dans le haut"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70 % dans le haut"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % dans le haut"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurer"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Épingler à gauche"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Épingler à droite"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Ouvrir les paramètres par défaut"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Choisissez comment ouvrir les liens Web pour cette appli"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Dans l\'appli"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index a97a48cd..9ced5c7 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Écran de gauche à 50 %"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Écran de gauche à 30 %"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Écran de droite en plein écran"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Écran du haut en plein écran"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Écran du haut à 70 %"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Écran du haut à 50 %"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurer"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ancrer à gauche"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Ancrer à droite"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Ouvrir les paramètres par défaut"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Choisir comment ouvrir les liens Web pour cette appli"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Dans l\'application"</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index 445cc70..b967784 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50 % á esquerda"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30 % á esquerda"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Pantalla completa á dereita"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Pantalla completa arriba"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70 % arriba"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % arriba"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurar"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Axustar á esquerda"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Axustar á dereita"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Abrir coa configuración predeterminada"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Escoller como abrir as ligazóns web para esta aplicación"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Na aplicación"</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index 6bef1bb..d8c422f 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ડાબે 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ડાબે 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"જમણી સ્ક્રીન સ્ક્રીન"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"શીર્ષ પૂર્ણ સ્ક્રીન"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"શીર્ષ 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"શીર્ષ 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"રિસ્ટોર કરો"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ડાબે સ્નૅપ કરો"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"જમણે સ્નૅપ કરો"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"\'ડિફૉલ્ટ તરીકે ખોલો\' સેટિંગ"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"આ ઍપ માટે વેબ લિંક ખોલવાની રીત પસંદ કરો"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ઍપમાં"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 95b3fc0..f8215af 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"बाईं स्क्रीन को 50% बनाएं"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"बाईं स्क्रीन को 30% बनाएं"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"दाईं स्क्रीन को फ़ुल स्क्रीन बनाएं"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ऊपर की स्क्रीन को फ़ुल स्क्रीन बनाएं"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ऊपर की स्क्रीन को 70% बनाएं"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ऊपर की स्क्रीन को 50% बनाएं"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"पहले जैसा करें"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"बाईं ओर स्नैप करें"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"दाईं ओर स्नैप करें"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"डिफ़ॉल्ट सेटिंग के हिसाब से खोलें"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"इस ऐप्लिकेशन के लिए वेब लिंक खोलने का तरीका चुनें"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ऐप्लिकेशन में"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 28bab79..7f29c05 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Lijevi zaslon na 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Lijevi zaslon na 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Desni zaslon u cijeli zaslon"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Gornji zaslon u cijeli zaslon"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Gornji zaslon na 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gornji zaslon na 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Vrati"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Poravnaj lijevo"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Poravnaj desno"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Otvori prema zadanim postavkama"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Odaberite način otvaranja web-veza za ovu aplikaciju"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"U aplikaciji"</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index 1afb57d..76e7579 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Bal oldali 50%-ra"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Bal oldali 30%-ra"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Jobb oldali teljes képernyőre"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Felső teljes képernyőre"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Felső 70%-ra"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Felső 50%-ra"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Visszaállítás"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Balra igazítás"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Jobbra igazítás"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Alapértelmezett beállítások megnyitása"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Az app webes linkjeinek megnyitásához használt módszer"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Az alkalmazásban"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 72669424..0eb75c7 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ձախ էկրանը՝ 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Ձախ էկրանը՝ 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Աջ էկրանը՝ լիաէկրան"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Վերևի էկրանը՝ լիաէկրան"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Վերևի էկրանը՝ 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Վերևի էկրանը՝ 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Վերականգնել"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ամրացնել ձախ կողմում"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Ամրացնել աջ կողմում"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Բացել կարգավորումներն ըստ կանխադրման"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Ընտրեք՝ ինչպես բացել այս հավելվածի վեբ հղումները"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Հավելվածում"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index 1197413..813e978 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kiri 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Kiri 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Layar penuh di kanan"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Layar penuh di atas"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Atas 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Atas 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Pulihkan"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Maksimalkan ke kiri"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Maksimalkan ke kanan"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Buka dengan setelan default"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Pilih cara membuka link web untuk aplikasi ini"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Di aplikasi"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index 9646cb3..98d6809 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vinstri 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Vinstri 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Hægri á öllum skjánum"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Efri á öllum skjánum"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Efri 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Efri 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Endurheimta"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Smella til vinstri"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Smella til hægri"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Stillingar sjálfvirkrar opnunar"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Veldu hvernig veftenglar opnast í forritinu"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Í forritinu"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index c3f6b3b..4217e8d 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Schermata sinistra al 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Schermata sinistra al 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Schermata destra a schermo intero"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Schermata superiore a schermo intero"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Schermata superiore al 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Schermata superiore al 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Ripristina"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Aggancia a sinistra"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Aggancia a destra"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Apri in base alle impostazioni predefinite"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Scegli come aprire i link web per questa app"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"All\'interno dell\'app"</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index cf9c18b..1cd89a6 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"שמאלה 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"שמאלה 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"מסך ימני מלא"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"מסך עליון מלא"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"עליון 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"עליון 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"שחזור"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"הצמדה לשמאל"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"הצמדה לימין"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"הגדרות לפתיחה כברירת מחדל"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"כאן בוחרים איך לפתוח באפליקציה הזו קישורים לדפי אינטרנט"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"באפליקציה"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index c955ecb..3d169e0 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"左 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"左 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"右全画面"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"上部全画面"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"上 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"上 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"復元"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"左にスナップ"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"右にスナップ"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"デフォルトの設定で開く"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"このアプリのウェブリンクを開く方法を選択"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"アプリ内"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 2c286d2..02e0f32 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"მარცხენა ეკრანი — 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"მარცხენა ეკრანი — 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"მარჯვენა ნაწილის სრულ ეკრანზე გაშლა"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ზედა ნაწილის სრულ ეკრანზე გაშლა"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ზედა ეკრანი — 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ზედა ეკრანი — 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"აღდგენა"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"მარცხნივ გადატანა"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"მარჯვნივ გადატანა"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"პარამეტრების ნაგულისხმევად გახსნა"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ამ აპისთვის ვებ ბმულების გახსნის წესის არჩევა"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"აპში"</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index 58afb7f..61c331d 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% сол жақта"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30% сол жақта"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Оң жағын толық экранға шығару"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Жоғарғы жағын толық экранға шығару"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70% жоғарғы жақта"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% жоғарғы жақта"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Қалпына келтіру"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Солға тіркеу"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Оңға тіркеу"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Әдепкісінше ашу параметрлері"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Осы қолданбадағы веб-сілтемелерді ашу жолын таңдаңыз"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Қолданбада"</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 6abb66d..4ab4a64 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ឆ្វេង 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ឆ្វេង 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"អេក្រង់ពេញខាងស្តាំ"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"អេក្រង់ពេញខាងលើ"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ខាងលើ 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ខាងលើ 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ស្ដារ"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ផ្លាស់ទីទៅឆ្វេង"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ផ្លាស់ទីទៅស្ដាំ"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ការកំណត់បើកតាមលំនាំដើម"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ជ្រើសរើសរបៀបបើកតំណបណ្ដាញសម្រាប់កម្មវិធីនេះ"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"នៅក្នុងកម្មវិធី"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 1da093d..c4ce890 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% ಎಡಕ್ಕೆ"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30% ಎಡಕ್ಕೆ"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"ಬಲ ಫುಲ್ ಸ್ಕ್ರೀನ್"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ಮೇಲಿನ ಫುಲ್ ಸ್ಕ್ರೀನ್"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70% ಮೇಲಕ್ಕೆ"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% ಮೇಲಕ್ಕೆ"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ಮರುಸ್ಥಾಪಿಸಿ"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ಎಡಕ್ಕೆ ಸ್ನ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ಬಲಕ್ಕೆ ಸ್ನ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ಡೀಫಾಲ್ಟ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಂದ ತೆರೆಯಿರಿ"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ಈ ಆ್ಯಪ್‌ಗೆ ವೆಬ್ ಲಿಂಕ್‌ಗಳನ್ನು ಹೇಗೆ ತೆರೆಯಬೇಕು ಎಂಬುದನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ಆ್ಯಪ್‌ನಲ್ಲಿ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 22f2e06..13c7009 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"왼쪽 화면 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"왼쪽 화면 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"오른쪽 화면 전체화면"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"위쪽 화면 전체화면"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"위쪽 화면 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"위쪽 화면 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"복원"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"왼쪽으로 맞추기"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"오른쪽으로 맞추기"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"기본값으로 열기 설정"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"이 앱에서 웹 링크를 여는 방법을 선택하세요"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"앱에서"</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 86529a2..eb990f1 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Сол жактагы экранды 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Сол жактагы экранды 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Оң жактагы экранды толук экран режимине өткөрүү"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Үстүнкү экранды толук экран режимине өткөрүү"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Үстүнкү экранды 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Үстүнкү экранды 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Калыбына келтирүү"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Солго жылдыруу"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Оңго жылдыруу"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Демейки шартта ачылуучу шилтемелердин параметрлери"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Колдонмодо шилтемелер кантип ачыларын тандаңыз"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Колдонмодо"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index fab0cb2..50164c0 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ຊ້າຍ 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ຊ້າຍ 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"ເຕັມໜ້າຈໍຂວາ"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ເຕັມໜ້າຈໍເທິງສຸດ"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ເທິງສຸດ 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ເທິງສຸດ 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ກູ້ຄືນ"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ແນບຊ້າຍ"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ແນບຂວາ"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ເປີດຕາມການຕັ້ງຄ່າເລີ່ມຕົ້ນ"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ເລືອກວິທີເປີດລິ້ງເວັບສຳລັບແອັບນີ້"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ໃນແອັບ"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index d036e35..c807971 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kairysis ekranas 50 %"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Kairysis ekranas 30 %"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Dešinysis ekranas viso ekrano režimu"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Viršutinis ekranas viso ekrano režimu"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Viršutinis ekranas 70 %"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Viršutinis ekranas 50 %"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Atkurti"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Pritraukti kairėje"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Pritraukti dešinėje"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Atidaryti pagal numatytuosius nustatymus"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Pasirinkite, kaip atidaryti šios programos žiniatinklio nuorodas"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Programoje"</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index dc1f7b0..a5547b0 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Pa kreisi 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Pa kreisi 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Labā daļa pa visu ekrānu"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Augšdaļa pa visu ekrānu"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Augšdaļa 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Augšdaļa 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Atjaunot"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Piestiprināt pa kreisi"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Piestiprināt pa labi"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Atvērt pēc noklusējuma iestatījumiem"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Izvēlieties, kā atvērt šajā lietotnē norādītās saites"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Lietotnē"</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index 3da196b..01136c3 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Левиот 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Левиот 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Десниот на цел екран"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Горниот на цел екран"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Горниот 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горниот 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Врати"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Фотографирај лево"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Фотографирај десно"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Отвори според стандардните поставки"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Изберете како да се отвораат линковите за апликацијава"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Во апликацијата"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index c2e747c..c2a942d 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ഇടത് 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ഇടത് 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"വലത് പൂർണ്ണ സ്ക്രീൻ"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"മുകളിൽ പൂർണ്ണ സ്ക്രീൻ"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"മുകളിൽ 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"മുകളിൽ 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"പുനഃസ്ഥാപിക്കുക"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ഇടതുവശത്തേക്ക് സ്‌നാപ്പ് ചെയ്യുക"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"വലതുവശത്തേക്ക് സ്‌നാപ്പ് ചെയ്യുക"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ഡിഫോൾട്ട് ക്രമീകരണം ഉപയോഗിച്ച് തുറക്കുക"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ഈ ആപ്പിനായി വെബ് ലിങ്കുകൾ എങ്ങനെ തുറക്കണമെന്ന് തിരഞ്ഞെടുക്കൂ"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ആപ്പിൽ"</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 045fc21..8914e1f 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Зүүн 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Зүүн 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Баруун талын бүтэн дэлгэц"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Дээд талын бүтэн дэлгэц"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Дээд 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Дээд 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Сэргээх"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Зүүн тийш зэрэгцүүлэх"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Баруун тийш зэрэгцүүлэх"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Өгөгдмөл тохиргоогоор нээх"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Энэ аппад веб холбоосыг хэрхэн нээхийг сонгоно уу"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Аппад"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index 01398d5..8159479 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"डावी 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"डावी 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"उजवी फुल स्क्रीन"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"शीर्ष फुल स्क्रीन"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"शीर्ष 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"शीर्ष 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"रिस्टोअर करा"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"डावीकडे स्नॅप करा"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"उजवीकडे स्नॅप करा"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"बाय डीफॉल्ट सेटिंग्ज उघडा"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"या अ‍ॅपसाठीच्या वेब लिंक कशा उघडाव्यात हे निवडा"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ॲपमध्ये"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 3d687dc..56b2c2c 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kiri 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Kiri 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Skrin penuh kanan"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Skrin penuh atas"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Atas 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Atas 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Pulihkan"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Autojajar ke kiri"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Autojajar ke kanan"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Buka tetapan secara lalai"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Pilih cara membuka pautan web untuk apl ini"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Pada apl"</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 08a935f..b749b67 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ဘယ်ဘက် မျက်နှာပြင် ၅၀%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ဘယ်ဘက် မျက်နှာပြင် ၃၀%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"ညာဘက် မျက်နှာပြင်အပြည့်"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"အပေါ်ဘက် မျက်နှာပြင်အပြည့်"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"အပေါ်ဘက် မျက်နှာပြင် ၇၀%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"အပေါ်ဘက် မျက်နှာပြင် ၅၀%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ပြန်ပြောင်းရန်"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ဘယ်တွင် ချဲ့ရန်"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ညာတွင် ချဲ့ရန်"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"မူရင်းဆက်တင်ဖြင့် ဖွင့်ရန်"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ဤအက်ပ်အတွက် ဝဘ်လင့်ခ်များ မည်သို့ဖွင့်မည်ကို ရွေးပါ"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"အက်ပ်တွင်"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 1965078..86aa196 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Sett størrelsen på den venstre delen av skjermen til 50 %"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Sett størrelsen på den venstre delen av skjermen til 30 %"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Utvid den høyre delen av skjermen til hele skjermen"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Utvid den øverste delen av skjermen til hele skjermen"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Sett størrelsen på den øverste delen av skjermen til 70 %"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Sett størrelsen på den øverste delen av skjermen til 50 %"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Gjenopprett"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Fest til venstre"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Fest til høyre"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Innstillinger for åpning som standard"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Velg hvordan nettlinker skal åpnes for denne appen"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"I appen"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 10e9332..bc45b0f 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"बायाँ भाग ५०%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"बायाँ भाग ३०%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"दायाँ भाग फुल स्क्रिन"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"माथिल्लो भाग फुल स्क्रिन"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"माथिल्लो भाग ७०%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"माथिल्लो भाग ५०%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"रिस्टोर गर्नुहोस्"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"बायाँतिर स्न्याप गर्नुहोस्"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"दायाँतिर स्न्याप गर्नुहोस्"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"डिफल्ट सेटिङअनुसार खोल्नुहोस्"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"यो एपका वेब लिंकहरू खोल्ने तरिका छनौट गर्नुहोस्"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"एपमा"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index fc84515..80c588f 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Linkerscherm 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Linkerscherm 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Rechterscherm op volledig scherm"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Bovenste scherm op volledig scherm"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Bovenste scherm 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Bovenste scherm 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Herstellen"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Links uitlijnen"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Rechts uitlijnen"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Instellingen voor Standaard openen"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Kies hoe je weblinks voor deze app wilt openen"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"In de app"</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index be01593..b16092e 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ବାମ ପଟକୁ 50% କରନ୍ତୁ"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ବାମ ପଟେ 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"ଡାହାଣ ପଟକୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍‍ କରନ୍ତୁ"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ଉପର ଆଡ଼କୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍‍ କରନ୍ତୁ"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ଉପର ଆଡ଼କୁ 70% କରନ୍ତୁ"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ଉପର ଆଡ଼କୁ 50% କରନ୍ତୁ"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ରିଷ୍ଟୋର କରନ୍ତୁ"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ବାମରେ ସ୍ନାପ କରନ୍ତୁ"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ଡାହାଣରେ ସ୍ନାପ କରନ୍ତୁ"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ଡିଫଲ୍ଟ ସେଟିଂସକୁ ଖୋଲନ୍ତୁ"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ଏହି ଆପ ପାଇଁ ୱେବ ଲିଙ୍କଗୁଡ଼ିକୁ କିପରି ଖୋଲିବେ, ତାହା ବାଛନ୍ତୁ"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ଆପରେ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index fb4c83e..6015e93d 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ਖੱਬੇ 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ਖੱਬੇ 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"ਸੱਜੇ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ਉੱਪਰ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ਉੱਪਰ 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ਉੱਪਰ 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ਮੁੜ-ਬਹਾਲ ਕਰੋ"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ਖੱਬੇ ਪਾਸੇ ਸਨੈਪ ਕਰੋ"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"ਸੱਜੇ ਪਾਸੇ ਸਨੈਪ ਕਰੋ"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਸੈਟਿੰਗਾਂ ਮੁਤਾਬਕ ਖੋਲ੍ਹੋ"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ਇਸ ਐਪ ਲਈ ਵੈੱਬ ਲਿੰਕਾਂ ਨੂੰ ਖੋਲ੍ਹਣ ਦਾ ਤਰੀਕਾ ਚੁਣੋ"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ਐਪ ਵਿੱਚ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index fa0e7c3..d06603f 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% lewej części ekranu"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30% lewej części ekranu"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Prawa część ekranu na pełnym ekranie"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Górna część ekranu na pełnym ekranie"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70% górnej części ekranu"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% górnej części ekranu"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Przywróć"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Przyciągnij do lewej"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Przyciągnij do prawej"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Ustawienia domyślnego otwierania"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Wybierz, gdzie chcesz otwierać linki z tej aplikacji"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"W aplikacji"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index d9e5f8c..d881abab 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Esquerda a 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Esquerda a 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Lado direito em tela cheia"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Parte superior em tela cheia"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Parte superior a 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Parte superior a 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurar"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ajustar à esquerda"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Ajustar à direita"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Configurações \"Abrir por padrão\""</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Escolha como abrir links da Web para este app"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"No app"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 28dc7b0..dcbec86 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"50% no ecrã esquerdo"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"30% no ecrã esquerdo"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Ecrã direito inteiro"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Ecrã superior inteiro"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"70% no ecrã superior"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% no ecrã superior"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurar"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Encaixar à esquerda"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Encaixar à direita"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Definições de Abrir por predefinição"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Escolha como abrir links da Web para esta app"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Na app"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index d9e5f8c..d881abab 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Esquerda a 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Esquerda a 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Lado direito em tela cheia"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Parte superior em tela cheia"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Parte superior a 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Parte superior a 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurar"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Ajustar à esquerda"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Ajustar à direita"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Configurações \"Abrir por padrão\""</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Escolha como abrir links da Web para este app"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"No app"</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index b63a8b3..3039950 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Partea stângă: 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Partea stângă: 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Partea dreaptă pe ecran complet"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Partea de sus pe ecran complet"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Partea de sus: 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Partea de sus: 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restabilește"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Trage la stânga"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Trage la dreapta"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Setări de deschidere în mod prestabilit"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Alege modul de deschidere a linkurilor web pentru aplicație"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"În aplicație"</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 709e90e..1fc0e6f 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Левый на 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Левый на 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Правый во весь экран"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Верхний во весь экран"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Верхний на 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Верхний на 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Восстановить"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Привязать слева"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Привязать справа"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Настройки, регулирующие, как по умолчанию открываются ссылки"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Выберите, где будут открываться ссылки из этого приложения"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"В приложении"</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index da1aa9d..f1116c0 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"වම් 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"වම් 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"දකුණු පූර්ණ තිරය"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ඉහළම පූර්ණ තිරය"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ඉහළම 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ඉහළම 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ප්‍රතිසාධනය කරන්න"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"වමට ස්නැප් කරන්න"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"දකුණට ස්නැප් කරන්න"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"පෙරනිමි සැකසීම් මඟින් විවෘත කරන්න"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"මෙම යෙදුම සඳහා වෙබ් සබැඳි විවෘත කරන ආකාරය තෝරා ගන්න"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"යෙදුම තුළ"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index aa77997..a6c7343 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ľavá – 50 %"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Ľavá – 30 %"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Pravá– na celú obrazovku"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Horná – na celú obrazovku"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Horná – 70 %"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Horná – 50 %"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Obnoviť"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Prichytiť vľavo"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Prichytiť vpravo"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Otvárať podľa predvolených nastavení"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Vyberte, ako sa majú v tejto aplikácii otvárať webové odkazy"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"V aplikácii"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 55452bd..02ced0d 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Levi 50 %"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Levi 30 %"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Desni v celozaslonski način"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Zgornji v celozaslonski način"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Zgornji 70 %"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Zgornji 50 %"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Obnovi"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Pripni levo"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Pripni desno"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Nastavitve privzetega odpiranja"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Izberite način odpiranja spletnih povezav za to aplikacijo"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"V aplikaciji"</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index 0492b2f9..fe03feb 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Majtas 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Majtas 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Ekrani i plotë djathtas"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Ekrani i plotë lart"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Lart 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Lart 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restauro"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Zhvendos majtas"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Zhvendos djathtas"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Hap sipas cilësimeve të parazgjedhura"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Zgjidh si do t\'i hapësh lidhjet e uebit për këtë aplikacion"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Në aplikacion"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index af8ac68..e3cb1f3 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Леви екран 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Леви екран 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Режим целог екрана за доњи екран"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Режим целог екрана за горњи екран"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Горњи екран 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горњи екран 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Вратите"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Прикачите лево"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Прикачите десно"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Подешавање Подразумевано отварај"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Одаберите начин отварања веб-линкова за ову апликацију"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"У апликацији"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 0c3c18c..29f4aab 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Vänster 50 %"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Vänster 30 %"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Helskärm på höger skärm"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Helskärm på övre skärm"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Övre 70 %"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Övre 50 %"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Återställ"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Fäst till vänster"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Fäst till höger"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Inställningar för Öppna som standard"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Välj hur webblänkar ska öppnas för den här appen"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"I appen"</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 4f0a6ac..6471e3b 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kushoto 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Kushoto 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Skrini nzima ya kulia"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Skrini nzima ya juu"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Juu 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Juu 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Rejesha"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Telezesha kushoto"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Telezesha kulia"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Fungua kwa mipangilio chaguomsingi"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Chagua jinsi ya kufungua viungo vya wavuti vya programu hii"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Kwenye programu"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index 5fca404..03e55c8 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"இடது புறம் 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"இடது புறம் 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"வலது புறம் முழுத் திரை"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"மேற்புறம் முழுத் திரை"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"மேலே 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"மேலே 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"மீட்டெடுக்கும்"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"இடதுபுறம் நகர்த்தும்"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"வலதுபுறம் நகர்த்தும்"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"இயல்பாக அமைப்புகளைத் திறக்கும்"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"இந்த ஆப்ஸில் வலை இணைப்புகளைத் திறக்கும் வழிமுறையைத் தேர்வுசெய்யுங்கள்"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ஆப்ஸில்"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index abc4d08..af8abaa 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ఎడమవైపు 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ఎడమవైపు 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"కుడివైపు ఫుల్-స్క్రీన్‌"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"ఎగువ ఫుల్-స్క్రీన్‌"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ఎగువ 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ఎగువ 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"రీస్టోర్ చేయండి"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ఎడమ వైపున స్నాప్ చేయండి"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"కుడి వైపున స్నాప్ చేయండి"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"ఆటోమేటిక్ సెట్టింగ్‌ల ద్వారా తెరవండి"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"ఈ యాప్‌నకు సంబంధించిన వెబ్ లింక్‌లను ఎలా తెరవాలో ఎంచుకోండి"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"యాప్‌లో"</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index 7be7373..565b4ee 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ซ้าย 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ซ้าย 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"เต็มหน้าจอทางขวา"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"เต็มหน้าจอด้านบน"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ด้านบน 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ด้านบน 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"คืนค่า"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"จัดพอดีกับทางซ้าย"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"จัดพอดีกับทางขวา"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"เปิดตามการตั้งค่าเริ่มต้น"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"เลือกวิธีเปิดเว็บลิงก์สำหรับแอปนี้"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ในแอป"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index 22b0174..e8cb1d2 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Gawing 50% ang nasa kaliwa"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Gawing 30% ang nasa kaliwa"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"I-full screen ang nasa kanan"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"I-full screen ang nasa itaas"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Gawing 70% ang nasa itaas"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gawing 50% ang nasa itaas"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"I-restore"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"I-snap pakaliwa"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"I-snap pakanan"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Buksan sa pamamagitan ng mga default na setting"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Piliin kung paano magbukas ng web link para sa app na ito"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Sa app"</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 79d64ba1..8d12e54 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Solda %50"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Solda %30"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Sağda tam ekran"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Üstte tam ekran"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Üstte %70"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Üstte %50"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Geri yükle"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Sola tuttur"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Sağa tuttur"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Varsayılan olarak açma ayarları"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Bu uygulama için web bağlantılarının nasıl açılacağını seçin"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Uygulamada"</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index aeba982..66d8a62 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Ліве вікно на 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Ліве вікно на 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Праве вікно на весь екран"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Верхнє вікно на весь екран"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Верхнє вікно на 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Верхнє вікно на 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Відновити"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Закріпити ліворуч"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Закріпити праворуч"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Налаштування \"Відкривати за умовчанням\""</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Виберіть, як відкривати вебпосилання в цьому додатку"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"У додатку"</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index cf6fb89..653ba0e6 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"بائیں %50"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"بائیں %30"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"دائیں فل اسکرین"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"بالائی فل اسکرین"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"اوپر %70"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"اوپر %50"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"بحال کریں"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"دائیں منتقل کریں"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"بائیں منتقل کریں"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"بطور ڈیفالٹ ترتیبات کھولیں"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"اس ایپ کے لیے ویب لنکس کھولنے کا طریقہ منتخب کریں"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ایپ میں"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index c64b843..63d82bf 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Chapda 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Chapda 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"O‘ngda to‘liq ekran"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Tepada to‘liq ekran"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Tepada 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Tepada 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Tiklash"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Chapga tortish"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Oʻngga tortish"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Birlamchi sozlamalar asosida ochish"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Bu ilovalardagi veb havolalar qanday ochilishini tanlang"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Ilovada"</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 2a7dae4..f1b728b 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Trái 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Trái 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Toàn màn hình bên phải"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Toàn màn hình phía trên"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Trên 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Trên 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Khôi phục"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Di chuyển nhanh sang trái"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Di chuyển nhanh sang phải"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Mở các chế độ cài đặt theo mặc định"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Chọn cách mở đường liên kết trang web cho ứng dụng này"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Trong ứng dụng"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index e45fbba..5437808 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"左侧 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"左侧 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"右侧全屏"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"顶部全屏"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"顶部 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"顶部 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"恢复"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"贴靠左侧"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"贴靠右侧"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"默认打开设置"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"选择如何打开此应用中的网页链接"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"在此应用内"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index d5e1063..938024d 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"左邊 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"左邊 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"右邊全螢幕"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"頂部全螢幕"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"頂部 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"頂部 50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"還原"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"貼齊左邊"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"貼齊右邊"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"採用預設設定打開"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"選擇此應用程式開啟網絡連結的方式"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"在應用程式內"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index a0357e12..3a5a87d 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"以 50% 的螢幕空間顯示左側畫面"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"以 30% 的螢幕空間顯示左側畫面"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"以全螢幕顯示右側畫面"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"以全螢幕顯示頂端畫面"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"以 70% 的螢幕空間顯示頂端畫面"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"以 50% 的螢幕空間顯示頂端畫面"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"還原"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"靠左對齊"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"靠右對齊"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"開啟連結的預設設定"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"選擇如何開啟這個應用程式的網頁連結"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"使用應用程式"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 810b6c8..cba8e04 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -43,6 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"Kwesokunxele ngo-50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"Kwesokunxele ngo-30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"Isikrini esigcwele esingakwesokudla"</string>
+    <!-- no translation found for accessibility_action_divider_swap (7026003137401725787) -->
+    <skip />
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"Isikrini esigcwele esiphezulu"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"Okuphezulu okungu-70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Okuphezulu okungu-50%"</string>
@@ -141,6 +143,26 @@
     <string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Buyisela"</string>
     <string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Chofoza kwesobunxele"</string>
     <string name="desktop_mode_maximize_menu_snap_right_button_text" msgid="7117751068945657304">"Chofoza kwesokudla"</string>
+    <!-- no translation found for desktop_mode_a11y_action_snap_left (2932955411661734668) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_snap_right (4577032451624261787) -->
+    <skip />
+    <!-- no translation found for desktop_mode_a11y_action_maximize_restore (8026037983417986686) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_split_screen_mode_button_text (7182959681057464802) -->
+    <skip />
+    <!-- no translation found for app_handle_menu_talkback_desktop_mode_button_text (1230110046930843630) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_left_text (500309467459084564) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_snap_right_text (7010831426654467163) -->
+    <skip />
+    <!-- no translation found for maximize_menu_talkback_action_maximize_restore_text (4942610897847934859) -->
+    <skip />
+    <!-- no translation found for maximize_button_talkback_action_maximize_restore_text (4122441323153198455) -->
+    <skip />
+    <!-- no translation found for minimize_button_talkback_action_maximize_restore_text (8890767445425625935) -->
+    <skip />
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"Vula amasethingi ngokuzenzakalela"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"Khetha indlela yokuvula amalinki ewebhu ale app"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"Ku-app"</string>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 9e2d23b..e23d572 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -270,6 +270,8 @@
     <dimen name="bubble_bar_expanded_view_switch_offset">48dp</dimen>
     <!-- Minimum width of the bubble bar manage menu. -->
     <dimen name="bubble_bar_manage_menu_min_width">200dp</dimen>
+    <!-- The Bubble Bar drop zone square size. -->
+    <dimen name="bubble_bar_drop_zone_side_size">200dp</dimen>
     <!-- Size of the dismiss icon in the bubble bar manage menu. -->
     <dimen name="bubble_bar_manage_menu_dismiss_icon_size">16dp</dimen>
     <!-- Padding of the bubble bar manage menu, provides space for menu shadows -->
@@ -293,6 +295,10 @@
     <dimen name="bubble_bar_dismiss_zone_width">192dp</dimen>
     <!-- Height of the box around bottom center of the screen where drag only leads to dismiss -->
     <dimen name="bubble_bar_dismiss_zone_height">242dp</dimen>
+    <!-- Height of the box at the corner of the screen where drag leads to app moving to bubble -->
+    <dimen name="bubble_transform_area_width">140dp</dimen>
+    <!-- Width of the box at the corner of the screen where drag leads to app moving to bubble -->
+    <dimen name="bubble_transform_area_height">140dp</dimen>
 
     <!-- Bottom and end margin for compat buttons. -->
     <dimen name="compat_button_margin">24dp</dimen>
diff --git a/libs/WindowManager/Shell/res/values/ids.xml b/libs/WindowManager/Shell/res/values/ids.xml
index 122cde0..c6082b3 100644
--- a/libs/WindowManager/Shell/res/values/ids.xml
+++ b/libs/WindowManager/Shell/res/values/ids.xml
@@ -25,6 +25,7 @@
     <item type="id" name="action_move_tl_50" />
     <item type="id" name="action_move_tl_30" />
     <item type="id" name="action_move_rb_full" />
+    <item type="id" name="action_swap_apps" />
 
     <!-- For saving PhysicsAnimationLayout animations/animators as view tags. -->
     <item type="id" name="translation_x_dynamicanimation_tag"/>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index c29b927..a2231dd 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -90,6 +90,8 @@
     <string name="accessibility_action_divider_left_30">Left 30%</string>
     <!-- Accessibility action for moving docked stack divider to make the right screen full screen [CHAR LIMIT=NONE] -->
     <string name="accessibility_action_divider_right_full">Right full screen</string>
+    <!-- Accessibility action for swapping the apps around the divider (double tap action) [CHAR LIMIT=NONE] -->
+    <string name="accessibility_action_divider_swap">Swap Apps</string>
 
     <!-- Accessibility action for moving docked stack divider to make the top screen full screen [CHAR LIMIT=NONE] -->
     <string name="accessibility_action_divider_top_full">Top full screen</string>
diff --git a/libs/WindowManager/Shell/res/values/strings_tv.xml b/libs/WindowManager/Shell/res/values/strings_tv.xml
index 8f806cf..b50812f 100644
--- a/libs/WindowManager/Shell/res/values/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values/strings_tv.xml
@@ -59,5 +59,7 @@
     <!-- Accessibility action: done with moving the PiP [CHAR LIMIT=30] -->
     <string name="a11y_action_pip_move_done">Done</string>
 
+    <string name="font_display_medium" translatable="false">sans-serif</string>
+
 </resources>
 
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
index 8a4a702..4ebb7dc 100644
--- a/libs/WindowManager/Shell/res/values/styles.xml
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -75,15 +75,6 @@
         <item name="android:background">@color/split_divider_background</item>
     </style>
 
-    <style name="TvPipEduText">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
-        <item name="android:textAllCaps">true</item>
-        <item name="android:textSize">10sp</item>
-        <item name="android:lineSpacingExtra">4sp</item>
-        <item name="android:lineHeight">16sp</item>
-        <item name="android:textColor">@color/tv_pip_edu_text</item>
-    </style>
-
     <style name="LetterboxDialog" parent="@android:style/Theme.DeviceDefault.Dialog.Alert">
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
diff --git a/libs/WindowManager/Shell/res/values/styles_tv.xml b/libs/WindowManager/Shell/res/values/styles_tv.xml
new file mode 100644
index 0000000..a4f5edc
--- /dev/null
+++ b/libs/WindowManager/Shell/res/values/styles_tv.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2025 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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">
+
+    <style name="TvPipEduText">
+        <item name="android:fontFamily">@string/font_display_medium</item>
+        <item name="android:textAllCaps">true</item>
+        <item name="android:textFontWeight">700</item>
+        <item name="android:textSize">10sp</item>
+        <item name="android:lineSpacingExtra">4sp</item>
+        <item name="android:lineHeight">16sp</item>
+        <item name="android:textColor">@color/tv_pip_edu_text</item>
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/shared/Android.bp b/libs/WindowManager/Shell/shared/Android.bp
index 261c639..af46ca2 100644
--- a/libs/WindowManager/Shell/shared/Android.bp
+++ b/libs/WindowManager/Shell/shared/Android.bp
@@ -74,6 +74,7 @@
         "**/desktopmode/*.kt",
     ],
     static_libs: [
+        "WindowManager-Shell-shared-AOSP",
         "com.android.window.flags.window-aconfig-java",
         "wm_shell-shared-utils",
     ],
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleDropTargetBoundsProvider.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleDropTargetBoundsProvider.kt
new file mode 100644
index 0000000..9bee11a
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleDropTargetBoundsProvider.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.bubbles
+
+import android.graphics.Rect
+
+/**
+ * Provide bounds for Bubbles drop targets that are shown when dragging over drag zones
+ */
+interface BubbleDropTargetBoundsProvider {
+    /**
+     * Get bubble bar expanded view visual drop target bounds on screen
+     */
+    fun getBubbleBarExpandedViewDropTargetBounds(onLeft: Boolean): Rect
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DeviceConfig.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DeviceConfig.kt
similarity index 98%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DeviceConfig.kt
rename to libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DeviceConfig.kt
index 9293309..f479da0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DeviceConfig.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DeviceConfig.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.bubbles
+package com.android.wm.shell.shared.bubbles
 
 import android.content.Context
 import android.content.res.Configuration
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DragZone.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DragZone.kt
new file mode 100644
index 0000000..5d346c0
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DragZone.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.bubbles
+
+import android.graphics.Rect
+
+/**
+ * Represents an invisible area on the screen that determines what happens to a dragged object if it
+ * is released in that area.
+ *
+ * [bounds] are the bounds of the drag zone. Drag zones have an associated drop target that serves
+ * as visual feedback hinting what would happen if the object is released. When a dragged object is
+ * dragged into a drag zone, the associated drop target will be displayed. Not all drag zones have
+ * drop targets; only those that are made visible by Bubbles do.
+ */
+sealed interface DragZone {
+
+    /** The bounds of this drag zone. */
+    val bounds: Rect
+
+    fun contains(x: Int, y: Int) = bounds.contains(x, y)
+
+    /** Represents the bubble drag area on the screen. */
+    sealed class Bubble(override val bounds: Rect) : DragZone {
+        data class Left(override val bounds: Rect, val dropTarget: Rect) : Bubble(bounds)
+        data class Right(override val bounds: Rect, val dropTarget: Rect) : Bubble(bounds)
+    }
+
+    /** Represents dragging to Desktop Window. */
+    data class DesktopWindow(override val bounds: Rect, val dropTarget: Rect) : DragZone
+
+    /** Represents dragging to Full Screen. */
+    data class FullScreen(override val bounds: Rect, val dropTarget: Rect) : DragZone
+
+    /** Represents dragging to dismiss. */
+    data class Dismiss(override val bounds: Rect) : DragZone
+
+    /** Represents dragging to enter Split or replace a Split app. */
+    sealed class Split(override val bounds: Rect) : DragZone {
+        data class Left(override val bounds: Rect) : Split(bounds)
+        data class Right(override val bounds: Rect) : Split(bounds)
+        data class Top(override val bounds: Rect) : Split(bounds)
+        data class Bottom(override val bounds: Rect) : Split(bounds)
+    }
+}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DragZoneFactory.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DragZoneFactory.kt
new file mode 100644
index 0000000..c2eef33
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DragZoneFactory.kt
@@ -0,0 +1,450 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.bubbles
+
+import android.graphics.Rect
+import com.android.wm.shell.shared.bubbles.DragZoneFactory.SplitScreenModeChecker.SplitScreenMode
+
+/** A class for creating drag zones for dragging bubble objects or dragging into bubbles. */
+class DragZoneFactory(
+    private val deviceConfig: DeviceConfig,
+    private val splitScreenModeChecker: SplitScreenModeChecker,
+    private val desktopWindowModeChecker: DesktopWindowModeChecker,
+) {
+
+    private val windowBounds: Rect
+        get() = deviceConfig.windowBounds
+
+    // TODO b/393172431: move these to xml
+    private val dismissDragZoneSize = if (deviceConfig.isSmallTablet) 140 else 200
+    private val bubbleDragZoneTabletSize = 200
+    private val bubbleDragZoneFoldableSize = 140
+    private val fullScreenDragZoneWidth = 512
+    private val fullScreenDragZoneHeight = 44
+    private val desktopWindowDragZoneWidth = 880
+    private val desktopWindowDragZoneHeight = 300
+    private val desktopWindowFromExpandedViewDragZoneWidth = 200
+    private val desktopWindowFromExpandedViewDragZoneHeight = 350
+    private val splitFromBubbleDragZoneHeight = 100
+    private val splitFromBubbleDragZoneWidth = 60
+    private val hSplitFromExpandedViewDragZoneWidth = 60
+    private val vSplitFromExpandedViewDragZoneWidth = 200
+    private val vSplitFromExpandedViewDragZoneHeightTablet = 285
+    private val vSplitFromExpandedViewDragZoneHeightFold = 150
+    private val vUnevenSplitFromExpandedViewDragZoneHeight = 96
+
+    /**
+     * Creates the list of drag zones for the dragged object.
+     *
+     * Drag zones may have overlap, but the list is sorted by priority where the first drag zone has
+     * the highest priority so it should be checked first.
+     */
+    fun createSortedDragZones(draggedObject: DraggedObject): List<DragZone> {
+        val dragZones = mutableListOf<DragZone>()
+        when (draggedObject) {
+            is DraggedObject.BubbleBar -> {
+                dragZones.add(createDismissDragZone())
+                dragZones.addAll(createBubbleDragZones())
+            }
+            is DraggedObject.Bubble -> {
+                dragZones.add(createDismissDragZone())
+                dragZones.addAll(createBubbleDragZones())
+                dragZones.add(createFullScreenDragZone())
+                if (shouldShowDesktopWindowDragZones()) {
+                    dragZones.add(createDesktopWindowDragZoneForBubble())
+                }
+                dragZones.addAll(createSplitScreenDragZonesForBubble())
+            }
+            is DraggedObject.ExpandedView -> {
+                dragZones.add(createDismissDragZone())
+                dragZones.add(createFullScreenDragZone())
+                if (shouldShowDesktopWindowDragZones()) {
+                    dragZones.add(createDesktopWindowDragZoneForExpandedView())
+                }
+                if (deviceConfig.isSmallTablet) {
+                    dragZones.addAll(createSplitScreenDragZonesForExpandedViewOnFoldable())
+                } else {
+                    dragZones.addAll(createSplitScreenDragZonesForExpandedViewOnTablet())
+                }
+                createBubbleDragZonesForExpandedView()
+            }
+        }
+        return dragZones
+    }
+
+    private fun createDismissDragZone(): DragZone {
+        return DragZone.Dismiss(
+            bounds =
+                Rect(
+                    windowBounds.right / 2 - dismissDragZoneSize / 2,
+                    windowBounds.bottom - dismissDragZoneSize,
+                    windowBounds.right / 2 + dismissDragZoneSize / 2,
+                    windowBounds.bottom
+                )
+        )
+    }
+
+    private fun createBubbleDragZones(): List<DragZone> {
+        val dragZoneSize =
+            if (deviceConfig.isSmallTablet) {
+                bubbleDragZoneFoldableSize
+            } else {
+                bubbleDragZoneTabletSize
+            }
+        return listOf(
+            DragZone.Bubble.Left(
+                bounds =
+                    Rect(0, windowBounds.bottom - dragZoneSize, dragZoneSize, windowBounds.bottom),
+                dropTarget = Rect(0, 0, 0, 0),
+            ),
+            DragZone.Bubble.Right(
+                bounds =
+                    Rect(
+                        windowBounds.right - dragZoneSize,
+                        windowBounds.bottom - dragZoneSize,
+                        windowBounds.right,
+                        windowBounds.bottom,
+                    ),
+                dropTarget = Rect(0, 0, 0, 0),
+            )
+        )
+    }
+
+    private fun createBubbleDragZonesForExpandedView(): List<DragZone> {
+        return listOf(
+            DragZone.Bubble.Left(
+                bounds = Rect(0, 0, windowBounds.right / 2, windowBounds.bottom),
+                dropTarget = Rect(0, 0, 0, 0),
+            ),
+            DragZone.Bubble.Right(
+                bounds =
+                    Rect(
+                        windowBounds.right / 2,
+                        0,
+                        windowBounds.right,
+                        windowBounds.bottom,
+                    ),
+                dropTarget = Rect(0, 0, 0, 0),
+            )
+        )
+    }
+
+    private fun createFullScreenDragZone(): DragZone {
+        return DragZone.FullScreen(
+            bounds =
+                Rect(
+                    windowBounds.right / 2 - fullScreenDragZoneWidth / 2,
+                    0,
+                    windowBounds.right / 2 + fullScreenDragZoneWidth / 2,
+                    fullScreenDragZoneHeight
+                ),
+            dropTarget = Rect(0, 0, 0, 0)
+        )
+    }
+
+    private fun shouldShowDesktopWindowDragZones() =
+        !deviceConfig.isSmallTablet && desktopWindowModeChecker.isSupported()
+
+    private fun createDesktopWindowDragZoneForBubble(): DragZone {
+        return DragZone.DesktopWindow(
+            bounds =
+                if (deviceConfig.isLandscape) {
+                    Rect(
+                        windowBounds.right / 2 - desktopWindowDragZoneWidth / 2,
+                        windowBounds.bottom / 2 - desktopWindowDragZoneHeight / 2,
+                        windowBounds.right / 2 + desktopWindowDragZoneWidth / 2,
+                        windowBounds.bottom / 2 + desktopWindowDragZoneHeight / 2
+                    )
+                } else {
+                    Rect(
+                        0,
+                        windowBounds.bottom / 2 - desktopWindowDragZoneHeight / 2,
+                        windowBounds.right,
+                        windowBounds.bottom / 2 + desktopWindowDragZoneHeight / 2
+                    )
+                },
+            dropTarget = Rect(0, 0, 0, 0)
+        )
+    }
+
+    private fun createDesktopWindowDragZoneForExpandedView(): DragZone {
+        return DragZone.DesktopWindow(
+            bounds =
+                Rect(
+                    windowBounds.right / 2 - desktopWindowFromExpandedViewDragZoneWidth / 2,
+                    windowBounds.bottom / 2 - desktopWindowFromExpandedViewDragZoneHeight / 2,
+                    windowBounds.right / 2 + desktopWindowFromExpandedViewDragZoneWidth / 2,
+                    windowBounds.bottom / 2 + desktopWindowFromExpandedViewDragZoneHeight / 2
+                ),
+            dropTarget = Rect(0, 0, 0, 0)
+        )
+    }
+
+    private fun createSplitScreenDragZonesForBubble(): List<DragZone> {
+        // for foldables in landscape mode or tables in portrait modes we have vertical split drag
+        // zones. otherwise we have horizontal split drag zones.
+        val isVerticalSplit = deviceConfig.isSmallTablet == deviceConfig.isLandscape
+        return if (isVerticalSplit) {
+            when (splitScreenModeChecker.getSplitScreenMode()) {
+                SplitScreenMode.SPLIT_50_50,
+                SplitScreenMode.NONE ->
+                    listOf(
+                        DragZone.Split.Top(
+                            bounds = Rect(0, 0, windowBounds.right, windowBounds.bottom / 2),
+                        ),
+                        DragZone.Split.Bottom(
+                            bounds =
+                                Rect(
+                                    0,
+                                    windowBounds.bottom / 2,
+                                    windowBounds.right,
+                                    windowBounds.bottom
+                                ),
+                        )
+                    )
+                SplitScreenMode.SPLIT_90_10 -> {
+                    listOf(
+                        DragZone.Split.Top(
+                            bounds =
+                                Rect(
+                                    0,
+                                    0,
+                                    windowBounds.right,
+                                    windowBounds.bottom - splitFromBubbleDragZoneHeight
+                                ),
+                        ),
+                        DragZone.Split.Bottom(
+                            bounds =
+                                Rect(
+                                    0,
+                                    windowBounds.bottom - splitFromBubbleDragZoneHeight,
+                                    windowBounds.right,
+                                    windowBounds.bottom
+                                ),
+                        )
+                    )
+                }
+                SplitScreenMode.SPLIT_10_90 -> {
+                    listOf(
+                        DragZone.Split.Top(
+                            bounds = Rect(0, 0, windowBounds.right, splitFromBubbleDragZoneHeight),
+                        ),
+                        DragZone.Split.Bottom(
+                            bounds =
+                                Rect(
+                                    0,
+                                    splitFromBubbleDragZoneHeight,
+                                    windowBounds.right,
+                                    windowBounds.bottom
+                                ),
+                        )
+                    )
+                }
+            }
+        } else {
+            when (splitScreenModeChecker.getSplitScreenMode()) {
+                SplitScreenMode.SPLIT_50_50,
+                SplitScreenMode.NONE ->
+                    listOf(
+                        DragZone.Split.Left(
+                            bounds = Rect(0, 0, windowBounds.right / 2, windowBounds.bottom),
+                        ),
+                        DragZone.Split.Right(
+                            bounds =
+                                Rect(
+                                    windowBounds.right / 2,
+                                    0,
+                                    windowBounds.right,
+                                    windowBounds.bottom
+                                ),
+                        )
+                    )
+                SplitScreenMode.SPLIT_90_10 ->
+                    listOf(
+                        DragZone.Split.Left(
+                            bounds =
+                                Rect(
+                                    0,
+                                    0,
+                                    windowBounds.right - splitFromBubbleDragZoneWidth,
+                                    windowBounds.bottom
+                                ),
+                        ),
+                        DragZone.Split.Right(
+                            bounds =
+                                Rect(
+                                    windowBounds.right - splitFromBubbleDragZoneWidth,
+                                    0,
+                                    windowBounds.right,
+                                    windowBounds.bottom
+                                ),
+                        )
+                    )
+                SplitScreenMode.SPLIT_10_90 ->
+                    listOf(
+                        DragZone.Split.Left(
+                            bounds = Rect(0, 0, splitFromBubbleDragZoneWidth, windowBounds.bottom),
+                        ),
+                        DragZone.Split.Right(
+                            bounds =
+                                Rect(
+                                    splitFromBubbleDragZoneWidth,
+                                    0,
+                                    windowBounds.right,
+                                    windowBounds.bottom
+                                ),
+                        )
+                    )
+            }
+        }
+    }
+
+    private fun createSplitScreenDragZonesForExpandedViewOnTablet(): List<DragZone> {
+        return if (deviceConfig.isLandscape) {
+            createHorizontalSplitDragZonesForExpandedView()
+        } else {
+            // for tablets in portrait mode, split drag zones appear below the full screen drag zone
+            // for the top split zone, and above the dismiss zone. Both are horizontally centered.
+            val splitZoneLeft = windowBounds.right / 2 - vSplitFromExpandedViewDragZoneWidth / 2
+            val splitZoneRight = splitZoneLeft + vSplitFromExpandedViewDragZoneWidth
+            val bottomSplitZoneBottom = windowBounds.bottom - dismissDragZoneSize
+            listOf(
+                DragZone.Split.Top(
+                    bounds =
+                        Rect(
+                            splitZoneLeft,
+                            fullScreenDragZoneHeight,
+                            splitZoneRight,
+                            fullScreenDragZoneHeight + vSplitFromExpandedViewDragZoneHeightTablet
+                        ),
+                ),
+                DragZone.Split.Bottom(
+                    bounds =
+                        Rect(
+                            splitZoneLeft,
+                            bottomSplitZoneBottom - vSplitFromExpandedViewDragZoneHeightTablet,
+                            splitZoneRight,
+                            bottomSplitZoneBottom
+                        ),
+                )
+            )
+        }
+    }
+
+    private fun createSplitScreenDragZonesForExpandedViewOnFoldable(): List<DragZone> {
+        return if (deviceConfig.isLandscape) {
+            // vertical split drag zones are aligned with the full screen drag zone width
+            val splitZoneLeft = windowBounds.right / 2 - fullScreenDragZoneWidth / 2
+            when (splitScreenModeChecker.getSplitScreenMode()) {
+                SplitScreenMode.SPLIT_50_50,
+                SplitScreenMode.NONE ->
+                    listOf(
+                        DragZone.Split.Top(
+                            bounds =
+                                Rect(
+                                    splitZoneLeft,
+                                    fullScreenDragZoneHeight,
+                                    splitZoneLeft + fullScreenDragZoneWidth,
+                                    fullScreenDragZoneHeight +
+                                        vSplitFromExpandedViewDragZoneHeightFold
+                                ),
+                        ),
+                        DragZone.Split.Bottom(
+                            bounds =
+                                Rect(
+                                    splitZoneLeft,
+                                    windowBounds.bottom / 2,
+                                    splitZoneLeft + fullScreenDragZoneWidth,
+                                    windowBounds.bottom / 2 +
+                                        vSplitFromExpandedViewDragZoneHeightFold
+                                ),
+                        )
+                    )
+                // TODO b/393172431: add this zone when it's defined
+                SplitScreenMode.SPLIT_10_90 -> listOf()
+                SplitScreenMode.SPLIT_90_10 ->
+                    listOf(
+                        DragZone.Split.Top(
+                            bounds =
+                                Rect(
+                                    splitZoneLeft,
+                                    fullScreenDragZoneHeight,
+                                    splitZoneLeft + fullScreenDragZoneWidth,
+                                    fullScreenDragZoneHeight +
+                                        vUnevenSplitFromExpandedViewDragZoneHeight
+                                ),
+                        ),
+                        DragZone.Split.Bottom(
+                            bounds =
+                                Rect(
+                                    0,
+                                    windowBounds.bottom -
+                                        vUnevenSplitFromExpandedViewDragZoneHeight,
+                                    windowBounds.right,
+                                    windowBounds.bottom
+                                ),
+                        )
+                    )
+            }
+        } else {
+            // horizontal split drag zones
+            createHorizontalSplitDragZonesForExpandedView()
+        }
+    }
+
+    private fun createHorizontalSplitDragZonesForExpandedView(): List<DragZone> {
+        // horizontal split drag zones for expanded view appear on the edges of the screen from the
+        // top down until the dismiss drag zone height
+        return listOf(
+            DragZone.Split.Left(
+                bounds =
+                    Rect(
+                        0,
+                        0,
+                        hSplitFromExpandedViewDragZoneWidth,
+                        windowBounds.bottom - dismissDragZoneSize
+                    ),
+            ),
+            DragZone.Split.Right(
+                bounds =
+                    Rect(
+                        windowBounds.right - hSplitFromExpandedViewDragZoneWidth,
+                        0,
+                        windowBounds.right,
+                        windowBounds.bottom - dismissDragZoneSize
+                    ),
+            )
+        )
+    }
+
+    /** Checks the current split screen mode. */
+    fun interface SplitScreenModeChecker {
+        enum class SplitScreenMode {
+            NONE,
+            SPLIT_50_50,
+            SPLIT_10_90,
+            SPLIT_90_10
+        }
+
+        fun getSplitScreenMode(): SplitScreenMode
+    }
+
+    /** Checks if desktop window mode is supported. */
+    fun interface DesktopWindowModeChecker {
+        fun isSupported(): Boolean
+    }
+}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DraggedObject.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DraggedObject.kt
new file mode 100644
index 0000000..0286227
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DraggedObject.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.bubbles
+
+/** A Bubble object being dragged. */
+sealed interface DraggedObject {
+    /** The initial location of the object at the start of the drag gesture. */
+    val initialLocation: BubbleBarLocation
+
+    data class Bubble(override val initialLocation: BubbleBarLocation) : DraggedObject
+    data class BubbleBar(override val initialLocation: BubbleBarLocation) : DraggedObject
+    data class ExpandedView(override val initialLocation: BubbleBarLocation) : DraggedObject
+}
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
index e196880..2586bd6 100644
--- 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
@@ -18,6 +18,8 @@
 
 import static android.hardware.display.DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED;
 
+import static com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper.enableBubbleToFullscreen;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -187,7 +189,7 @@
      * there should be no pooling.
      */
     public static int getWindowDecorScvhPoolSize(@NonNull Context context) {
-        if (!Flags.enableDesktopWindowingScvhCacheBugFix()) return 0;
+        if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_SCVH_CACHE.isTrue()) return 0;
         final int maxTaskLimit = getMaxTaskLimit(context);
         if (maxTaskLimit > 0) {
             return maxTaskLimit;
@@ -206,8 +208,7 @@
     /**
      * Return {@code true} if the current device supports desktop mode.
      */
-    @VisibleForTesting
-    public static boolean isDesktopModeSupported(@NonNull Context context) {
+    private static boolean isDesktopModeSupported(@NonNull Context context) {
         return context.getResources().getBoolean(R.bool.config_isDesktopModeSupported);
     }
 
@@ -230,7 +231,7 @@
      * Return {@code true} if desktop mode dev option should be shown on current device
      */
     public static boolean canShowDesktopExperienceDevOption(@NonNull Context context) {
-        return Flags.showDesktopExperienceDevOption();
+        return Flags.showDesktopExperienceDevOption() && isDeviceEligibleForDesktopMode(context);
     }
 
     /** Returns if desktop mode dev option should be enabled if there is no user override. */
@@ -270,7 +271,8 @@
      * necessarily enabling desktop mode
      */
     public static boolean overridesShowAppHandle(@NonNull Context context) {
-        return Flags.showAppHandleLargeScreens() && deviceHasLargeScreen(context);
+        return (Flags.showAppHandleLargeScreens() || enableBubbleToFullscreen())
+                && deviceHasLargeScreen(context);
     }
 
     /**
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/pip/PipContentOverlay.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/pip/PipContentOverlay.java
index 62ca5c6..b1bc6e8 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/pip/PipContentOverlay.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/pip/PipContentOverlay.java
@@ -28,6 +28,7 @@
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.hardware.HardwareBuffer;
 import android.util.TypedValue;
 import android.view.SurfaceControl;
 import android.window.TaskSnapshot;
@@ -225,12 +226,17 @@
 
         @Override
         public void attach(SurfaceControl.Transaction tx, SurfaceControl parentLeash) {
+            final HardwareBuffer buffer = mBitmap.getHardwareBuffer();
             tx.show(mLeash);
             tx.setLayer(mLeash, Integer.MAX_VALUE);
-            tx.setBuffer(mLeash, mBitmap.getHardwareBuffer());
+            tx.setBuffer(mLeash, buffer);
             tx.setAlpha(mLeash, 0f);
             tx.reparent(mLeash, parentLeash);
             tx.apply();
+            // Cleanup the bitmap and buffer after setting up the leash
+            mBitmap.recycle();
+            mBitmap = null;
+            buffer.close();
         }
 
         @Override
@@ -253,14 +259,6 @@
                     .setAlpha(mLeash, fraction < 0.5f ? 0 : (fraction - 0.5f) * 2);
         }
 
-        @Override
-        public void detach(SurfaceControl.Transaction tx) {
-            super.detach(tx);
-            if (mBitmap != null && !mBitmap.isRecycled()) {
-                mBitmap.recycle();
-            }
-        }
-
         private void prepareAppIconOverlay(Drawable appIcon) {
             final Canvas canvas = new Canvas();
             canvas.setBitmap(mBitmap);
@@ -282,7 +280,9 @@
                     mOverlayHalfSize + mAppIconSizePx / 2);
             appIcon.setBounds(appIconBounds);
             appIcon.draw(canvas);
+            Bitmap oldBitmap = mBitmap;
             mBitmap = mBitmap.copy(Bitmap.Config.HARDWARE, false /* mutable */);
+            oldBitmap.recycle();
         }
     }
 }
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 c40a276..d77c177 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
@@ -72,12 +72,18 @@
 public class Bubble implements BubbleViewProvider {
     private static final String TAG = "Bubble";
 
-    /** A string suffix used in app bubbles' {@link #mKey}. */
+    /** A string prefix used in app bubbles' {@link #mKey}. */
     public static final String KEY_APP_BUBBLE = "key_app_bubble";
 
+    /** A string prefix used in note bubbles' {@link #mKey}. */
+    public static final String KEY_NOTE_BUBBLE = "key_note_bubble";
+
     /** Whether the bubble is an app bubble. */
     private final boolean mIsAppBubble;
 
+    /** Whether the bubble is a notetaking bubble. */
+    private final boolean mIsNoteBubble;
+
     private final String mKey;
     @Nullable
     private final String mGroupKey;
@@ -186,10 +192,10 @@
      * that bubble being added back to the stack anyways.
      */
     @Nullable
-    private PendingIntent mIntent;
-    private boolean mIntentActive;
+    private PendingIntent mPendingIntent;
+    private boolean mPendingIntentActive;
     @Nullable
-    private PendingIntent.CancelListener mIntentCancelListener;
+    private PendingIntent.CancelListener mPendingIntentCancelListener;
 
     /**
      * Sent when the bubble & notification are no longer visible to the user (i.e. no
@@ -199,12 +205,10 @@
     private PendingIntent mDeleteIntent;
 
     /**
-     * Used only for a special bubble in the stack that has {@link #mIsAppBubble} set to true.
-     * There can only be one of these bubbles in the stack and this intent will be populated for
-     * that bubble.
+     * Used for app & note bubbles.
      */
     @Nullable
-    private Intent mAppIntent;
+    private Intent mIntent;
 
     /**
      * Set while preparing a transition for animation. Several steps are needed before animation
@@ -245,6 +249,7 @@
         mTaskId = taskId;
         mBubbleMetadataFlagListener = listener;
         mIsAppBubble = false;
+        mIsNoteBubble = false;
     }
 
     private Bubble(
@@ -252,6 +257,7 @@
             UserHandle user,
             @Nullable Icon icon,
             boolean isAppBubble,
+            boolean isNoteBubble,
             String key,
             @ShellMainThread Executor mainExecutor,
             @ShellBackgroundThread Executor bgExecutor) {
@@ -261,12 +267,13 @@
         mUser = user;
         mIcon = icon;
         mIsAppBubble = isAppBubble;
+        mIsNoteBubble = isNoteBubble;
         mKey = key;
         mShowBubbleUpdateDot = false;
         mMainExecutor = mainExecutor;
         mBgExecutor = bgExecutor;
         mTaskId = INVALID_TASK_ID;
-        mAppIntent = intent;
+        mIntent = intent;
         mDesiredHeight = Integer.MAX_VALUE;
         mPackageName = intent.getPackage();
     }
@@ -279,12 +286,13 @@
         mUser = info.getUserHandle();
         mIcon = info.getIcon();
         mIsAppBubble = false;
+        mIsNoteBubble = false;
         mKey = getBubbleKeyForShortcut(info);
         mShowBubbleUpdateDot = false;
         mMainExecutor = mainExecutor;
         mBgExecutor = bgExecutor;
         mTaskId = INVALID_TASK_ID;
-        mAppIntent = null;
+        mIntent = null;
         mDesiredHeight = Integer.MAX_VALUE;
         mPackageName = info.getPackage();
         mShortcutInfo = info;
@@ -303,16 +311,28 @@
         mUser = user;
         mIcon = icon;
         mIsAppBubble = true;
+        mIsNoteBubble = false;
         mKey = key;
         mShowBubbleUpdateDot = false;
         mMainExecutor = mainExecutor;
         mBgExecutor = bgExecutor;
         mTaskId = task.taskId;
-        mAppIntent = null;
+        mIntent = null;
         mDesiredHeight = Integer.MAX_VALUE;
         mPackageName = task.baseActivity.getPackageName();
     }
 
+    /** Creates a notetaking bubble. */
+    public static Bubble createNotesBubble(Intent intent, UserHandle user, @Nullable Icon icon,
+            @ShellMainThread Executor mainExecutor, @ShellBackgroundThread Executor bgExecutor) {
+        return new Bubble(intent,
+                user,
+                icon,
+                /* isAppBubble= */ true,
+                /* isNoteBubble= */ true,
+                /* key= */ getNoteBubbleKeyForApp(intent.getPackage(), user),
+                mainExecutor, bgExecutor);
+    }
 
     /** Creates an app bubble. */
     public static Bubble createAppBubble(Intent intent, UserHandle user, @Nullable Icon icon,
@@ -321,6 +341,7 @@
                 user,
                 icon,
                 /* isAppBubble= */ true,
+                /* isNoteBubble= */ false,
                 /* key= */ getAppBubbleKeyForApp(intent.getPackage(), user),
                 mainExecutor, bgExecutor);
     }
@@ -353,6 +374,16 @@
     }
 
     /**
+     * Returns the key for a note bubble from an app with package name, {@code packageName} on an
+     * Android user, {@code user}.
+     */
+    public static String getNoteBubbleKeyForApp(String packageName, UserHandle user) {
+        Objects.requireNonNull(packageName);
+        Objects.requireNonNull(user);
+        return KEY_NOTE_BUBBLE + ":" + user.getIdentifier()  + ":" + packageName;
+    }
+
+    /**
      * Returns the key for a shortcut bubble using {@code packageName}, {@code user}, and the
      * {@code shortcutInfo} id.
      */
@@ -375,13 +406,14 @@
             final Bubbles.PendingIntentCanceledListener intentCancelListener,
             @ShellMainThread Executor mainExecutor, @ShellBackgroundThread Executor bgExecutor) {
         mIsAppBubble = false;
+        mIsNoteBubble = false;
         mKey = entry.getKey();
         mGroupKey = entry.getGroupKey();
         mLocusId = entry.getLocusId();
         mBubbleMetadataFlagListener = listener;
-        mIntentCancelListener = intent -> {
-            if (mIntent != null) {
-                mIntent.unregisterCancelListener(mIntentCancelListener);
+        mPendingIntentCancelListener = intent -> {
+            if (mPendingIntent != null) {
+                mPendingIntent.unregisterCancelListener(mPendingIntentCancelListener);
             }
             mainExecutor.execute(() -> {
                 intentCancelListener.onPendingIntentCanceled(this);
@@ -567,10 +599,10 @@
         if (cleanupTaskView) {
             cleanupTaskView();
         }
-        if (mIntent != null) {
-            mIntent.unregisterCancelListener(mIntentCancelListener);
+        if (mPendingIntent != null) {
+            mPendingIntent.unregisterCancelListener(mPendingIntentCancelListener);
         }
-        mIntentActive = false;
+        mPendingIntentActive = false;
     }
 
     /** Cleans-up the taskview associated with this bubble (possibly removing the task from wm) */
@@ -840,19 +872,19 @@
             mDesiredHeightResId = entry.getBubbleMetadata().getDesiredHeightResId();
             mIcon = entry.getBubbleMetadata().getIcon();
 
-            if (!mIntentActive || mIntent == null) {
-                if (mIntent != null) {
-                    mIntent.unregisterCancelListener(mIntentCancelListener);
+            if (!mPendingIntentActive || mPendingIntent == null) {
+                if (mPendingIntent != null) {
+                    mPendingIntent.unregisterCancelListener(mPendingIntentCancelListener);
                 }
-                mIntent = entry.getBubbleMetadata().getIntent();
-                if (mIntent != null) {
-                    mIntent.registerCancelListener(mIntentCancelListener);
+                mPendingIntent = entry.getBubbleMetadata().getIntent();
+                if (mPendingIntent != null) {
+                    mPendingIntent.registerCancelListener(mPendingIntentCancelListener);
                 }
-            } else if (mIntent != null && entry.getBubbleMetadata().getIntent() == null) {
+            } else if (mPendingIntent != null && entry.getBubbleMetadata().getIntent() == null) {
                 // Was an intent bubble now it's a shortcut bubble... still unregister the listener
-                mIntent.unregisterCancelListener(mIntentCancelListener);
-                mIntentActive = false;
-                mIntent = null;
+                mPendingIntent.unregisterCancelListener(mPendingIntentCancelListener);
+                mPendingIntentActive = false;
+                mPendingIntent = null;
             }
             mDeleteIntent = entry.getBubbleMetadata().getDeleteIntent();
         }
@@ -892,12 +924,15 @@
      * Sets if the intent used for this bubble is currently active (i.e. populating an
      * expanded view, expanded or not).
      */
-    void setIntentActive() {
-        mIntentActive = true;
+    void setPendingIntentActive() {
+        mPendingIntentActive = true;
     }
 
-    boolean isIntentActive() {
-        return mIntentActive;
+    /**
+     * Whether the pending intent of this bubble is active (i.e. has been sent).
+     */
+    boolean isPendingIntentActive() {
+        return mPendingIntentActive;
     }
 
     public InstanceId getInstanceId() {
@@ -1084,9 +1119,12 @@
         }
     }
 
+    /**
+     * Returns the pending intent used to populate the bubble.
+     */
     @Nullable
-    PendingIntent getBubbleIntent() {
-        return mIntent;
+    PendingIntent getPendingIntent() {
+        return mPendingIntent;
     }
 
     /**
@@ -1094,40 +1132,49 @@
      * intent for an app. In this case we don't show a badge on the icon.
      */
     public boolean isAppLaunchIntent() {
-        if (BubbleAnythingFlagHelper.enableCreateAnyBubble() && mAppIntent != null) {
-            return mAppIntent.hasCategory("android.intent.category.LAUNCHER");
+        if (BubbleAnythingFlagHelper.enableCreateAnyBubble() && mIntent != null) {
+            return mIntent.hasCategory("android.intent.category.LAUNCHER");
         }
         return false;
     }
 
+    /**
+     * Returns the pending intent to send when a bubble is dismissed (set via the notification API).
+     */
     @Nullable
     PendingIntent getDeleteIntent() {
         return mDeleteIntent;
     }
 
-    @Nullable
-    @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.
+     * Returns the intent used to populate the bubble.
      */
-    void setAppBubbleIntent(Intent appIntent) {
-        mAppIntent = appIntent;
+    @Nullable
+    public Intent getIntent() {
+        return mIntent;
     }
 
     /**
-     * Returns whether this bubble is from an app versus a notification.
+     * Sets the intent used to populate the bubble.
+     */
+    void setIntent(Intent intent) {
+        mIntent = intent;
+    }
+
+    /**
+     * Returns whether this bubble is from an app (as well as notetaking) versus a notification.
      */
     public boolean isAppBubble() {
         return mIsAppBubble;
     }
 
+    /**
+     * Returns whether this bubble is specific from the notetaking API.
+     */
+    public boolean isNoteBubble() {
+        return mIsNoteBubble;
+    }
+
     /** Creates open app settings intent */
     public Intent getSettingsIntent(final Context context) {
         final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS);
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 e3f8e0c..2c81945 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
@@ -49,7 +49,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
 import android.content.pm.ShortcutInfo;
@@ -94,8 +93,8 @@
 import com.android.wm.shell.Flags;
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.bubbles.bar.BubbleBarDragListener;
 import com.android.wm.shell.bubbles.bar.BubbleBarLayerView;
-import com.android.wm.shell.bubbles.properties.BubbleProperties;
 import com.android.wm.shell.bubbles.shortcut.BubbleShortcutHelper;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayImeController;
@@ -117,6 +116,8 @@
 import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
 import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
 import com.android.wm.shell.shared.bubbles.BubbleBarUpdate;
+import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider;
+import com.android.wm.shell.shared.bubbles.DeviceConfig;
 import com.android.wm.shell.sysui.ConfigurationChangeListener;
 import com.android.wm.shell.sysui.ShellCommandHandler;
 import com.android.wm.shell.sysui.ShellController;
@@ -149,7 +150,8 @@
  * The controller manages addition, removal, and visible state of bubbles on screen.
  */
 public class BubbleController implements ConfigurationChangeListener,
-        RemoteCallable<BubbleController>, Bubbles.SysuiProxy.Provider {
+        RemoteCallable<BubbleController>, Bubbles.SysuiProxy.Provider,
+        BubbleBarDragListener {
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleController" : TAG_BUBBLES;
 
@@ -205,9 +207,9 @@
     private final ShellController mShellController;
     private final ShellCommandHandler mShellCommandHandler;
     private final IWindowManager mWmService;
-    private final BubbleProperties mBubbleProperties;
     private final BubbleTaskViewFactory mBubbleTaskViewFactory;
     private final BubbleExpandedViewManager mExpandedViewManager;
+    private final ResizabilityChecker mResizabilityChecker;
 
     // Used to post to main UI thread
     private final ShellExecutor mMainExecutor;
@@ -323,7 +325,7 @@
             Transitions transitions,
             SyncTransactionQueue syncQueue,
             IWindowManager wmService,
-            BubbleProperties bubbleProperties) {
+            ResizabilityChecker resizabilityChecker) {
         mContext = context;
         mShellCommandHandler = shellCommandHandler;
         mShellController = shellController;
@@ -372,7 +374,6 @@
         mDragAndDropController = dragAndDropController;
         mSyncQueue = syncQueue;
         mWmService = wmService;
-        mBubbleProperties = bubbleProperties;
         shellInit.addInitCallback(this::onInit, this);
         mBubbleTaskViewFactory = new BubbleTaskViewFactory() {
             @Override
@@ -385,6 +386,7 @@
             }
         };
         mExpandedViewManager = BubbleExpandedViewManager.fromBubbleController(this);
+        mResizabilityChecker = resizabilityChecker;
     }
 
     private void registerOneHandedState(OneHandedController oneHanded) {
@@ -417,12 +419,12 @@
         mBubbleData.setListener(mBubbleDataListener);
         mBubbleData.setSuppressionChangedListener(this::onBubbleMetadataFlagChanged);
         mDataRepository.setSuppressionChangedListener(this::onBubbleMetadataFlagChanged);
-
         mBubbleData.setPendingIntentCancelledListener(bubble -> {
-            if (bubble.getBubbleIntent() == null) {
+            if (bubble.getPendingIntent() == null) {
                 return;
             }
-            if (bubble.isIntentActive() || mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
+            if (bubble.isPendingIntentActive()
+                    || mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
                 bubble.setPendingIntentCanceled();
                 return;
             }
@@ -590,8 +592,7 @@
      * <p>If bubble bar is supported, bubble views will be updated to switch to bar mode.
      */
     public void registerBubbleStateListener(Bubbles.BubbleStateListener listener) {
-        mBubbleProperties.refresh();
-        if (canShowAsBubbleBar() && listener != null) {
+        if (Flags.enableBubbleBar() && mBubblePositioner.isLargeScreen() && listener != null) {
             // Only set the listener if we can show the bubble bar.
             mBubbleStateListener = listener;
             setUpBubbleViewsForMode();
@@ -608,7 +609,6 @@
      * will be updated accordingly.
      */
     public void unregisterBubbleStateListener() {
-        mBubbleProperties.refresh();
         if (mBubbleStateListener != null) {
             mBubbleStateListener = null;
             setUpBubbleViewsForMode();
@@ -766,14 +766,11 @@
         }
     }
 
-    /** Whether bubbles are showing in the bubble bar. */
+    /** Whether bubbles would be shown with the bubble bar UI. */
     public boolean isShowingAsBubbleBar() {
-        return canShowAsBubbleBar() && mBubbleStateListener != null;
-    }
-
-    /** Whether the current configuration supports showing as bubble bar. */
-    private boolean canShowAsBubbleBar() {
-        return mBubbleProperties.isBubbleBarEnabled() && mBubblePositioner.isLargeScreen();
+        return Flags.enableBubbleBar()
+                && mBubblePositioner.isLargeScreen()
+                && mBubbleStateListener != null;
     }
 
     /**
@@ -782,7 +779,7 @@
      */
     @Nullable
     public BubbleBarLocation getBubbleBarLocation() {
-        if (canShowAsBubbleBar()) {
+        if (isShowingAsBubbleBar()) {
             return mBubblePositioner.getBubbleBarLocation();
         }
         return null;
@@ -793,7 +790,7 @@
      */
     public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation,
             @BubbleBarLocation.UpdateSource int source) {
-        if (canShowAsBubbleBar()) {
+        if (isShowingAsBubbleBar()) {
             BubbleBarLocation previousLocation = mBubblePositioner.getBubbleBarLocation();
             mBubblePositioner.setBubbleBarLocation(bubbleBarLocation);
             if (mLayerView != null && !mLayerView.isExpandedViewDragged()) {
@@ -845,11 +842,52 @@
      * {@link #setBubbleBarLocation(BubbleBarLocation, int)}.
      */
     public void animateBubbleBarLocation(BubbleBarLocation bubbleBarLocation) {
-        if (canShowAsBubbleBar()) {
+        if (isShowingAsBubbleBar()) {
             mBubbleStateListener.animateBubbleBarLocation(bubbleBarLocation);
         }
     }
 
+    @Override
+    public void onDragItemOverBubbleBarDragZone(@Nullable BubbleBarLocation bubbleBarLocation) {
+        if (bubbleBarLocation == null) return;
+        if (isShowingAsBubbleBar() && BubbleAnythingFlagHelper.enableCreateAnyBubble()) {
+            //TODO(b/388894910) show expanded view drop
+            mBubbleStateListener.onDragItemOverBubbleBarDragZone(bubbleBarLocation);
+        }
+    }
+
+    @Override
+    public void onItemDraggedOutsideBubbleBarDropZone() {
+        if (isShowingAsBubbleBar() && BubbleAnythingFlagHelper.enableCreateAnyBubble()) {
+            //TODO(b/388894910) hide expanded view drop
+            mBubbleStateListener.onItemDraggedOutsideBubbleBarDropZone();
+        }
+    }
+
+    @Override
+    public void onItemDroppedOverBubbleBarDragZone(@Nullable BubbleBarLocation bubbleBarLocation) {
+        if (bubbleBarLocation == null) return;
+        if (isShowingAsBubbleBar() && BubbleAnythingFlagHelper.enableCreateAnyBubble()) {
+            //TODO(b/388894910) handle item drop with expandStackAndSelectBubble()
+        }
+    }
+
+    @Override
+    public Map<BubbleBarLocation, Rect> getBubbleBarDropZones(int l, int t, int r, int b) {
+        Map<BubbleBarLocation, Rect> result = new HashMap<>();
+        if (isShowingAsBubbleBar() && BubbleAnythingFlagHelper.enableCreateAnyBubble()) {
+            // TODO(b/393172431) : Utilise DragZoneFactory once it is ready
+            final int bubbleBarDropZoneSideSize = getContext().getResources().getDimensionPixelSize(
+                    R.dimen.bubble_bar_drop_zone_side_size);
+            int top = t - bubbleBarDropZoneSideSize;
+            result.put(BubbleBarLocation.LEFT,
+                    new Rect(l, top, l + bubbleBarDropZoneSideSize, b));
+            result.put(BubbleBarLocation.RIGHT,
+                    new Rect(r - bubbleBarDropZoneSideSize, top, r, b));
+        }
+        return result;
+    }
+
     /** Whether this userId belongs to the current user. */
     private boolean isCurrentProfile(int userId) {
         return userId == UserHandle.USER_ALL
@@ -888,6 +926,11 @@
         return mBubblePositioner;
     }
 
+    /** Provides bounds for drag zone drop targets */
+    public BubbleDropTargetBoundsProvider getBubbleDropTargetBoundsProvider() {
+        return mBubblePositioner;
+    }
+
     BubbleIconFactory getIconFactory() {
         return mBubbleIconFactory;
     }
@@ -1560,78 +1603,80 @@
 
     /**
      * This method has different behavior depending on:
-     *    - if an app bubble exists
-     *    - if an app bubble is expanded
+     *    - if a notes bubble exists
+     *    - if a notes bubble is expanded
      *
-     * If no app bubble exists, this will add and expand a bubble with the provided intent. The
+     * If no notes bubble exists, this will add and expand a bubble with the provided intent. The
      * intent must be explicit (i.e. include a package name or fully qualified component class name)
      * and the activity for it should be resizable.
      *
-     * If an app bubble exists, this will toggle the visibility of it, i.e. if the app bubble is
-     * expanded, calling this method will collapse it. If the app bubble is not expanded, calling
+     * If a notes bubble exists, this will toggle the visibility of it, i.e. if the notes bubble is
+     * expanded, calling this method will collapse it. If the notes bubble is not expanded, calling
      * this method will expand it.
      *
      * These bubbles are <b>not</b> backed by a notification and remain until the user dismisses
      * the bubble or bubble stack.
      *
-     * Some notes:
-     *    - Only one app bubble is supported at a time, regardless of users. Multi-users support is
-     *      tracked in b/273533235.
-     *    - Calling this method with a different intent than the existing app bubble will do nothing
+     * Some details:
+     *    - Calling this method with a different intent than the existing bubble will do nothing
      *
      * @param intent the intent to display in the bubble expanded view.
      * @param user the {@link UserHandle} of the user to start this activity for.
      * @param icon the {@link Icon} to use for the bubble view.
      */
-    public void showOrHideAppBubble(Intent intent, UserHandle user, @Nullable Icon icon) {
+    public void showOrHideNotesBubble(Intent intent, UserHandle user, @Nullable Icon icon) {
         if (intent == null || intent.getPackage() == null) {
-            Log.w(TAG, "App bubble failed to show, invalid intent: " + intent
+            Log.w(TAG, "Notes bubble failed to show, invalid intent: " + intent
                     + ((intent != null) ? " with package: " + intent.getPackage() : " "));
             return;
         }
 
-        String appBubbleKey = Bubble.getAppBubbleKeyForApp(intent.getPackage(), user);
+        String noteBubbleKey = Bubble.getNoteBubbleKeyForApp(intent.getPackage(), user);
         PackageManager packageManager = getPackageManagerForUser(mContext, user.getIdentifier());
-        if (!isResizableActivity(intent, packageManager, appBubbleKey)) return; // logs errors
+        if (!mResizabilityChecker.isResizableActivity(intent, packageManager, noteBubbleKey)) {
+            // resize check logs any errors
+            return;
+        }
 
-        Bubble existingAppBubble = mBubbleData.getBubbleInStackWithKey(appBubbleKey);
+        Bubble existingNotebubble = mBubbleData.getBubbleInStackWithKey(noteBubbleKey);
         ProtoLog.d(WM_SHELL_BUBBLES,
-                "showOrHideAppBubble, key=%s existingAppBubble=%s stackVisibility=%s "
+                "showOrHideNotesBubble, key=%s existingAppBubble=%s stackVisibility=%s "
                         + "statusBarShade=%s",
-                appBubbleKey, existingAppBubble,
+                noteBubbleKey, existingNotebubble,
                 (mStackView != null ? mStackView.getVisibility() : "null"),
                 mIsStatusBarShade);
 
-        if (existingAppBubble != null) {
+        if (existingNotebubble != null) {
             BubbleViewProvider selectedBubble = mBubbleData.getSelectedBubble();
             if (isStackExpanded()) {
-                if (selectedBubble != null && appBubbleKey.equals(selectedBubble.getKey())) {
-                    ProtoLog.d(WM_SHELL_BUBBLES, "collapseStack for %s", appBubbleKey);
-                    // App bubble is expanded, lets collapse
+                if (selectedBubble != null && noteBubbleKey.equals(selectedBubble.getKey())) {
+                    ProtoLog.d(WM_SHELL_BUBBLES, "collapseStack for %s", noteBubbleKey);
+                    // Notes bubble is expanded, lets collapse
                     collapseStack();
                 } else {
-                    ProtoLog.d(WM_SHELL_BUBBLES, "setSelected for %s", appBubbleKey);
-                    // App bubble is not selected, select it
-                    mBubbleData.setSelectedBubble(existingAppBubble);
+                    ProtoLog.d(WM_SHELL_BUBBLES, "setSelected for %s", noteBubbleKey);
+                    // Notes bubble is not selected, select it
+                    mBubbleData.setSelectedBubble(existingNotebubble);
                 }
             } else {
-                ProtoLog.d(WM_SHELL_BUBBLES, "setSelectedBubbleAndExpandStack %s", appBubbleKey);
-                // App bubble is not selected, select it & expand
-                mBubbleData.setSelectedBubbleAndExpandStack(existingAppBubble);
+                ProtoLog.d(WM_SHELL_BUBBLES, "setSelectedBubbleAndExpandStack %s", noteBubbleKey);
+                // Notes bubble is not selected, select it & expand
+                mBubbleData.setSelectedBubbleAndExpandStack(existingNotebubble);
             }
         } else {
             // Check if it exists in the overflow
-            Bubble b = mBubbleData.getOverflowBubbleWithKey(appBubbleKey);
+            Bubble b = mBubbleData.getOverflowBubbleWithKey(noteBubbleKey);
             if (b != null) {
                 // It's in the overflow, so remove it & reinflate
-                mBubbleData.dismissBubbleWithKey(appBubbleKey, Bubbles.DISMISS_NOTIF_CANCEL);
+                mBubbleData.dismissBubbleWithKey(noteBubbleKey, Bubbles.DISMISS_NOTIF_CANCEL);
                 // Update the bubble entry in the overflow with the latest intent.
-                b.setAppBubbleIntent(intent);
+                b.setIntent(intent);
             } else {
-                // App bubble does not exist, lets add and expand it
-                b = Bubble.createAppBubble(intent, user, icon, mMainExecutor, mBackgroundExecutor);
+                // Notes bubble does not exist, lets add and expand it
+                b = Bubble.createNotesBubble(intent, user, icon, mMainExecutor,
+                        mBackgroundExecutor);
             }
-            ProtoLog.d(WM_SHELL_BUBBLES, "inflateAndAdd %s", appBubbleKey);
+            ProtoLog.d(WM_SHELL_BUBBLES, "inflateAndAdd %s", noteBubbleKey);
             b.setShouldAutoExpand(true);
             inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false);
         }
@@ -1679,9 +1724,9 @@
         }
     }
 
-    /** Sets the app bubble's taskId which is cached for SysUI. */
-    public void setAppBubbleTaskId(String key, int taskId) {
-        mImpl.mCachedState.setAppBubbleTaskId(key, taskId);
+    /** Sets the note bubble's taskId which is cached for SysUI. */
+    public void setNoteBubbleTaskId(String key, int taskId) {
+        mImpl.mCachedState.setNoteBubbleTaskId(key, taskId);
     }
 
     /**
@@ -2539,7 +2584,7 @@
      * @param context the context to use.
      * @param entry   the entry to bubble.
      */
-    static boolean canLaunchInTaskView(Context context, BubbleEntry entry) {
+    boolean canLaunchInTaskView(Context context, BubbleEntry entry) {
         if (BubbleAnythingFlagHelper.enableCreateAnyBubble()) return true;
         PendingIntent intent = entry.getBubbleMetadata() != null
                 ? entry.getBubbleMetadata().getIntent()
@@ -2554,26 +2599,8 @@
         }
         PackageManager packageManager = getPackageManagerForUser(
                 context, entry.getStatusBarNotification().getUser().getIdentifier());
-        return isResizableActivity(intent.getIntent(), packageManager, entry.getKey());
-    }
-
-    static boolean isResizableActivity(Intent intent, PackageManager packageManager, String key) {
-        if (intent == null) {
-            Log.w(TAG, "Unable to send as bubble: " + key + " null intent");
-            return false;
-        }
-        ActivityInfo info = intent.resolveActivityInfo(packageManager, 0);
-        if (info == null) {
-            Log.w(TAG, "Unable to send as bubble: " + key
-                    + " couldn't find activity info for intent: " + intent);
-            return false;
-        }
-        if (!ActivityInfo.isResizeableMode(info.resizeMode)) {
-            Log.w(TAG, "Unable to send as bubble: " + key
-                    + " activity is not resizable for intent: " + intent);
-            return false;
-        }
-        return true;
+        return mResizabilityChecker.isResizableActivity(intent.getIntent(), packageManager,
+                entry.getKey());
     }
 
     static PackageManager getPackageManagerForUser(Context context, int userId) {
@@ -2805,7 +2832,7 @@
             private HashMap<String, String> mSuppressedGroupToNotifKeys = new HashMap<>();
             private HashMap<String, Bubble> mShortcutIdToBubble = new HashMap<>();
 
-            private HashMap<String, Integer> mAppBubbleTaskIds = new HashMap();
+            private HashMap<String, Integer> mNoteBubbleTaskIds = new HashMap();
 
             private ArrayList<Bubble> mTmpBubbles = new ArrayList<>();
 
@@ -2837,20 +2864,20 @@
 
                 mSuppressedBubbleKeys.clear();
                 mShortcutIdToBubble.clear();
-                mAppBubbleTaskIds.clear();
+                mNoteBubbleTaskIds.clear();
                 for (Bubble b : mTmpBubbles) {
                     mShortcutIdToBubble.put(b.getShortcutId(), b);
                     updateBubbleSuppressedState(b);
 
-                    if (b.isAppBubble()) {
-                        mAppBubbleTaskIds.put(b.getKey(), b.getTaskId());
+                    if (b.isNoteBubble()) {
+                        mNoteBubbleTaskIds.put(b.getKey(), b.getTaskId());
                     }
                 }
             }
 
-            /** Sets the app bubble's taskId which is cached for SysUI. */
-            synchronized void setAppBubbleTaskId(String key, int taskId) {
-                mAppBubbleTaskIds.put(key, taskId);
+            /** Sets the note bubble's taskId which is cached for SysUI. */
+            synchronized void setNoteBubbleTaskId(String key, int taskId) {
+                mNoteBubbleTaskIds.put(key, taskId);
             }
 
             /**
@@ -2902,7 +2929,7 @@
                     pw.println("   suppressing: " + key);
                 }
 
-                pw.println("mAppBubbleTaskIds: " + mAppBubbleTaskIds.values());
+                pw.println("mNoteBubbleTaskIds: " + mNoteBubbleTaskIds.values());
             }
         }
 
@@ -2953,14 +2980,14 @@
         }
 
         @Override
-        public void showOrHideAppBubble(Intent intent, UserHandle user, @Nullable Icon icon) {
+        public void showOrHideNoteBubble(Intent intent, UserHandle user, @Nullable Icon icon) {
             mMainExecutor.execute(
-                    () -> BubbleController.this.showOrHideAppBubble(intent, user, icon));
+                    () -> BubbleController.this.showOrHideNotesBubble(intent, user, icon));
         }
 
         @Override
-        public boolean isAppBubbleTaskId(int taskId) {
-            return mCachedState.mAppBubbleTaskIds.values().contains(taskId);
+        public boolean isNoteBubbleTaskId(int taskId) {
+            return mCachedState.mNoteBubbleTaskIds.values().contains(taskId);
         }
 
         @Override
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 97b03a9..ad9ab7a 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
@@ -237,8 +237,7 @@
                         PendingIntent pi = PendingIntent.getActivity(
                                 context,
                                 /* requestCode= */ 0,
-                                mBubble.getAppBubbleIntent()
-                                        .addFlags(FLAG_ACTIVITY_MULTIPLE_TASK),
+                                mBubble.getIntent().addFlags(FLAG_ACTIVITY_MULTIPLE_TASK),
                                 PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT,
                                 /* options= */ null);
                         mTaskView.startActivity(pi, /* fillInIntent= */ null, options,
@@ -252,7 +251,7 @@
                     } else {
                         options.setLaunchedFromBubble(true);
                         if (mBubble != null) {
-                            mBubble.setIntentActive();
+                            mBubble.setPendingIntentActive();
                         }
                         final Intent fillInIntent = new Intent();
                         // Apply flags to make behaviour match documentLaunchMode=always.
@@ -285,9 +284,9 @@
             // The taskId is saved to use for removeTask, preventing appearance in recent tasks.
             mTaskId = taskId;
 
-            if (mBubble != null && mBubble.isAppBubble()) {
+            if (mBubble != null && mBubble.isNoteBubble()) {
                 // Let the controller know sooner what the taskId is.
-                mManager.setAppBubbleTaskId(mBubble.getKey(), mTaskId);
+                mManager.setNoteBubbleTaskId(mBubble.getKey(), mTaskId);
             }
 
             // With the task org, the taskAppeared callback will only happen once the task has
@@ -920,7 +919,7 @@
                     });
 
             if (isNew) {
-                mPendingIntent = mBubble.getBubbleIntent();
+                mPendingIntent = mBubble.getPendingIntent();
                 if ((mPendingIntent != null || mBubble.hasMetadataShortcutId())
                         && mTaskView != null) {
                     setContentVisibility(false);
@@ -947,7 +946,7 @@
      */
     private boolean didBackingContentChange(Bubble newBubble) {
         boolean prevWasIntentBased = mBubble != null && mPendingIntent != null;
-        boolean newIsIntentBased = newBubble.getBubbleIntent() != null;
+        boolean newIsIntentBased = newBubble.getPendingIntent() != null;
         return prevWasIntentBased != newIsIntentBased;
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt
index a026231..6be49dd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt
@@ -28,7 +28,7 @@
     fun promoteBubbleFromOverflow(bubble: Bubble)
     fun removeBubble(key: String, reason: Int)
     fun dismissBubble(bubble: Bubble, reason: Int)
-    fun setAppBubbleTaskId(key: String, taskId: Int)
+    fun setNoteBubbleTaskId(key: String, taskId: Int)
     fun isStackExpanded(): Boolean
     fun isShowingAsBubbleBar(): Boolean
     fun hideCurrentInputMethod()
@@ -73,8 +73,8 @@
                     controller.dismissBubble(bubble, reason)
                 }
 
-                override fun setAppBubbleTaskId(key: String, taskId: Int) {
-                    controller.setAppBubbleTaskId(key, taskId)
+                override fun setNoteBubbleTaskId(key: String, taskId: Int) {
+                    controller.setNoteBubbleTaskId(key, taskId)
                 }
 
                 override fun isStackExpanded(): Boolean = controller.isStackExpanded
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 a725e04..5273a7c 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
@@ -27,18 +27,21 @@
 import android.view.Surface;
 import android.view.WindowManager;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.protolog.ProtoLog;
 import com.android.launcher3.icons.IconNormalizer;
 import com.android.wm.shell.R;
 import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
+import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider;
+import com.android.wm.shell.shared.bubbles.DeviceConfig;
 
 /**
  * Keeps track of display size, configuration, and specific bubble sizes. One place for all
  * placement and positioning calculations to refer to.
  */
-public class BubblePositioner {
+public class BubblePositioner implements BubbleDropTargetBoundsProvider {
 
     /** The screen edge the bubble stack is pinned to */
     public enum StackPinnedEdge {
@@ -99,6 +102,7 @@
     private int mManageButtonHeight;
     private int mOverflowHeight;
     private int mMinimumFlyoutWidthLargeScreen;
+    private int mBubbleBarExpandedViewDropTargetPadding;
 
     private PointF mRestingStackPosition;
 
@@ -163,6 +167,8 @@
                 res.getDimensionPixelSize(R.dimen.bubble_bar_expanded_view_width),
                 mPositionRect.width() - 2 * mExpandedViewPadding
         );
+        mBubbleBarExpandedViewDropTargetPadding = res.getDimensionPixelSize(
+                R.dimen.bubble_bar_expanded_view_drop_target_padding);
 
         if (mShowingInBubbleBar) {
             mExpandedViewLargeScreenWidth = mExpandedViewBubbleBarWidth;
@@ -758,20 +764,20 @@
      * is being shown, for a normal bubble.
      */
     public PointF getDefaultStartPosition() {
-        return getDefaultStartPosition(false /* isAppBubble */);
+        return getDefaultStartPosition(false /* isNoteBubble */);
     }
 
     /**
      * The stack position to use if we don't have a saved location or if user education
      * is being shown.
      *
-     * @param isAppBubble whether this start position is for an app bubble or not.
+     * @param isNoteBubble whether this start position is for a note bubble or not.
      */
-    public PointF getDefaultStartPosition(boolean isAppBubble) {
+    public PointF getDefaultStartPosition(boolean isNoteBubble) {
         // Normal bubbles start on the left if we're in LTR, right otherwise.
         // TODO (b/294284894): update language around "app bubble" here
         // App bubbles start on the right in RTL, left otherwise.
-        final boolean startOnLeft = isAppBubble ? mDeviceConfig.isRtl() : !mDeviceConfig.isRtl();
+        final boolean startOnLeft = isNoteBubble ? mDeviceConfig.isRtl() : !mDeviceConfig.isRtl();
         return getStartPosition(startOnLeft ? StackPinnedEdge.LEFT : StackPinnedEdge.RIGHT);
     }
 
@@ -964,4 +970,14 @@
         int top = getExpandedViewBottomForBubbleBar() - height;
         out.offsetTo(left, top);
     }
+
+    @NonNull
+    @Override
+    public Rect getBubbleBarExpandedViewDropTargetBounds(boolean onLeft) {
+        Rect bounds = new Rect();
+        getBubbleBarExpandedViewBounds(onLeft, false, bounds);
+        bounds.inset(mBubbleBarExpandedViewDropTargetPadding,
+                mBubbleBarExpandedViewDropTargetPadding);
+        return bounds;
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleResizabilityChecker.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleResizabilityChecker.kt
new file mode 100644
index 0000000..6ca0821
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleResizabilityChecker.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.content.Intent
+import android.content.pm.ActivityInfo
+import android.content.pm.PackageManager
+import android.util.Log
+
+/**
+ * Checks if an intent is resizable to display in a bubble.
+ */
+class BubbleResizabilityChecker : ResizabilityChecker {
+
+    override fun isResizableActivity(
+        intent: Intent?,
+        packageManager: PackageManager, key: String
+    ): Boolean {
+        if (intent == null) {
+            Log.w(TAG, "Unable to send as bubble: $key null intent")
+            return false
+        }
+        val info = intent.resolveActivityInfo(packageManager, 0)
+        if (info == null) {
+            Log.w(
+                TAG, ("Unable to send as bubble: " + key
+                        + " couldn't find activity info for intent: " + intent)
+            )
+            return false
+        }
+        if (!ActivityInfo.isResizeableMode(info.resizeMode)) {
+            Log.w(
+                TAG, ("Unable to send as bubble: " + key
+                        + " activity is not resizable for intent: " + intent)
+            )
+            return false
+        }
+        return true
+    }
+
+    companion object {
+        private const val TAG = "BubbleResizeChecker"
+    }
+}
\ No newline at end of file
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 f1f49ed..3babc0d 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
@@ -91,6 +91,7 @@
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.shared.animation.Interpolators;
 import com.android.wm.shell.shared.animation.PhysicsAnimator;
+import com.android.wm.shell.shared.bubbles.DeviceConfig;
 import com.android.wm.shell.shared.bubbles.DismissView;
 import com.android.wm.shell.shared.bubbles.RelativeTouchListener;
 import com.android.wm.shell.shared.magnetictarget.MagnetizedObject;
@@ -1975,12 +1976,11 @@
             return;
         }
 
-        if (firstBubble && bubble.isAppBubble() && !mPositioner.hasUserModifiedDefaultPosition()) {
-            // TODO (b/294284894): update language around "app bubble" here
-            // If it's an app bubble and we don't have a previous resting position, update the
-            // controllers to use the default position for the app bubble (it'd be different from
+        if (firstBubble && bubble.isNoteBubble() && !mPositioner.hasUserModifiedDefaultPosition()) {
+            // If it's an note bubble and we don't have a previous resting position, update the
+            // controllers to use the default position for the note bubble (it'd be different from
             // the position initialized with the controllers originally).
-            PointF startPosition =  mPositioner.getDefaultStartPosition(true /* isAppBubble */);
+            PointF startPosition =  mPositioner.getDefaultStartPosition(true /* isNoteBubble */);
             mStackOnLeftOrWillBe = mPositioner.isStackOnLeft(startPosition);
             mStackAnimationController.setStackPosition(startPosition);
             mExpandedAnimationController.setCollapsePoint(startPosition);
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 a6b8585..0d89bb2 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
@@ -119,7 +119,7 @@
                         PendingIntent pi = PendingIntent.getActivity(
                                 context,
                                 /* requestCode= */ 0,
-                                mBubble.getAppBubbleIntent()
+                                mBubble.getIntent()
                                         .addFlags(FLAG_ACTIVITY_MULTIPLE_TASK),
                                 PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT,
                                 /* options= */ null);
@@ -133,7 +133,7 @@
                     } else {
                         options.setLaunchedFromBubble(true);
                         if (mBubble != null) {
-                            mBubble.setIntentActive();
+                            mBubble.setPendingIntentActive();
                         }
                         final Intent fillInIntent = new Intent();
                         // Apply flags to make behaviour match documentLaunchMode=always.
@@ -167,9 +167,9 @@
             // The taskId is saved to use for removeTask, preventing appearance in recent tasks.
             mTaskId = taskId;
 
-            if (mBubble != null && mBubble.isAppBubble()) {
+            if (mBubble != null && mBubble.isNoteBubble()) {
                 // Let the controller know sooner what the taskId is.
-                mExpandedViewManager.setAppBubbleTaskId(mBubble.getKey(), mTaskId);
+                mExpandedViewManager.setNoteBubbleTaskId(mBubble.getKey(), mTaskId);
             }
 
             // With the task org, the taskAppeared callback will only happen once the task has
@@ -231,7 +231,7 @@
         boolean isNew = mBubble == null || didBackingContentChange(bubble);
         mBubble = bubble;
         if (isNew) {
-            mPendingIntent = mBubble.getBubbleIntent();
+            mPendingIntent = mBubble.getPendingIntent();
             return true;
         }
         return false;
@@ -276,7 +276,7 @@
      */
     private boolean didBackingContentChange(Bubble newBubble) {
         boolean prevWasIntentBased = mBubble != null && mPendingIntent != null;
-        boolean newIsIntentBased = newBubble.getBubbleIntent() != null;
+        boolean newIsIntentBased = newBubble.getPendingIntent() != null;
         return prevWasIntentBased != newIsIntentBased;
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index 4297fac..44ae744 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -135,33 +135,31 @@
 
     /**
      * This method has different behavior depending on:
-     * - if an app bubble exists
-     * - if an app bubble is expanded
+     *    - if a notes bubble exists
+     *    - if a notes bubble is expanded
      *
-     * If no app bubble exists, this will add and expand a bubble with the provided intent. The
+     * If no notes bubble exists, this will add and expand a bubble with the provided intent. The
      * intent must be explicit (i.e. include a package name or fully qualified component class name)
      * and the activity for it should be resizable.
      *
-     * If an app bubble exists, this will toggle the visibility of it, i.e. if the app bubble is
-     * expanded, calling this method will collapse it. If the app bubble is not expanded, calling
+     * If a notes bubble exists, this will toggle the visibility of it, i.e. if the notes bubble is
+     * expanded, calling this method will collapse it. If the notes bubble is not expanded, calling
      * this method will expand it.
      *
      * These bubbles are <b>not</b> backed by a notification and remain until the user dismisses
      * the bubble or bubble stack.
      *
-     * Some notes:
-     * - Only one app bubble is supported at a time, regardless of users. Multi-users support is
-     * tracked in b/273533235.
-     * - Calling this method with a different intent than the existing app bubble will do nothing
+     * Some details:
+     *    - Calling this method with a different intent than the existing bubble will do nothing
      *
      * @param intent the intent to display in the bubble expanded view.
-     * @param user   the {@link UserHandle} of the user to start this activity for.
-     * @param icon   the {@link Icon} to use for the bubble view.
+     * @param user the {@link UserHandle} of the user to start this activity for.
+     * @param icon the {@link Icon} to use for the bubble view.
      */
-    void showOrHideAppBubble(Intent intent, UserHandle user, @Nullable Icon icon);
+    void showOrHideNoteBubble(Intent intent, UserHandle user, @Nullable Icon icon);
 
     /** @return true if the specified {@code taskId} corresponds to app bubble's taskId. */
-    boolean isAppBubbleTaskId(int taskId);
+    boolean isNoteBubbleTaskId(int taskId);
 
     /**
 `    * @return a {@link SynchronousScreenCaptureListener} after performing a screenshot that may
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ResizabilityChecker.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ResizabilityChecker.kt
new file mode 100644
index 0000000..1ccc05d
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ResizabilityChecker.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.content.Intent
+import android.content.pm.PackageManager
+
+/**
+ * Interface to check whether the activity backed by a specific intent is resizable.
+ */
+interface ResizabilityChecker {
+
+    /**
+     * Returns whether the provided intent represents a resizable activity.
+     *
+     * @param intent the intent to check
+     * @param packageManager the package manager to use to do the look up
+     * @param key a key representing thing being checked (used for error logging)
+     */
+    fun isResizableActivity(intent: Intent?, packageManager: PackageManager, key: String): Boolean
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarDragListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarDragListener.kt
new file mode 100644
index 0000000..00eaad6
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarDragListener.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.bar
+
+import android.graphics.Rect
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation
+
+/** Controller that takes care of the bubble bar drag events. */
+interface BubbleBarDragListener {
+
+    /** Called when the drag event is over the bubble bar drop zone. */
+    fun onDragItemOverBubbleBarDragZone(location: BubbleBarLocation)
+
+    /** Called when the drag event leaves the bubble bar drop zone. */
+    fun onItemDraggedOutsideBubbleBarDropZone()
+
+    /** Called when the drop event happens over the bubble bar drop zone. */
+    fun onItemDroppedOverBubbleBarDragZone(location: BubbleBarLocation?)
+
+    /**
+     * Returns mapping of the bubble bar locations to the corresponding
+     * [rect][android.graphics.Rect] zone.
+     */
+    fun getBubbleBarDropZones(l: Int, t: Int, r: Int, b: Int): Map<BubbleBarLocation, Rect>
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
index f3f8d6f..b1035bc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
@@ -45,11 +45,11 @@
 import com.android.wm.shell.bubbles.BubbleOverflow;
 import com.android.wm.shell.bubbles.BubblePositioner;
 import com.android.wm.shell.bubbles.BubbleViewProvider;
-import com.android.wm.shell.bubbles.DeviceConfig;
 import com.android.wm.shell.bubbles.DismissViewUtils;
 import com.android.wm.shell.bubbles.bar.BubbleBarExpandedViewDragController.DragListener;
 import com.android.wm.shell.shared.bubbles.BaseBubblePinController;
 import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
+import com.android.wm.shell.shared.bubbles.DeviceConfig;
 import com.android.wm.shell.shared.bubbles.DismissView;
 
 import kotlin.Unit;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/properties/BubbleProperties.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/properties/BubbleProperties.kt
deleted file mode 100644
index 4206d93..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/properties/BubbleProperties.kt
+++ /dev/null
@@ -1,35 +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.bubbles.properties
-
-/**
- * An interface for exposing bubble properties via flags which can be controlled easily in tests.
- */
-interface BubbleProperties {
-    /**
-     * Whether bubble bar is enabled.
-     *
-     * When this is `true`, depending on additional factors, such as screen size and taskbar state,
-     * bubbles will be displayed in the bubble bar instead of floating.
-     *
-     * When this is `false`, bubbles will be floating.
-     */
-    val isBubbleBarEnabled: Boolean
-
-    /** Refreshes the current value of [isBubbleBarEnabled]. */
-    fun refresh()
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/properties/ProdBubbleProperties.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/properties/ProdBubbleProperties.kt
deleted file mode 100644
index 33b61b1..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/properties/ProdBubbleProperties.kt
+++ /dev/null
@@ -1,35 +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.bubbles.properties
-
-import android.os.SystemProperties
-import com.android.wm.shell.Flags
-
-/** Provides bubble properties in production. */
-object ProdBubbleProperties : BubbleProperties {
-
-    private var _isBubbleBarEnabled = Flags.enableBubbleBar() ||
-            SystemProperties.getBoolean("persist.wm.debug.bubble_bar", false)
-
-    override val isBubbleBarEnabled
-        get() = _isBubbleBarEnabled
-
-    override fun refresh() {
-        _isBubbleBarEnabled = Flags.enableBubbleBar() ||
-                SystemProperties.getBoolean("persist.wm.debug.bubble_bar", false)
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/InputChannelSupplier.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/InputChannelSupplier.kt
new file mode 100644
index 0000000..4138204
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/InputChannelSupplier.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.view.InputChannel
+import com.android.wm.shell.dagger.WMSingleton
+import java.util.function.Supplier
+import javax.inject.Inject
+
+/**
+ * An Injectable [Supplier<InputChannel>]. This can be used in place of kotlin default
+ * parameters values [builder = ::InputChannel] which requires the [@JvmOverloads] annotation to
+ * make this available in Java.
+ * This can be used every time a component needs the dependency to the default [Supplier] for
+ * [InputChannel]s.
+ */
+@WMSingleton
+class InputChannelSupplier @Inject constructor() : Supplier<InputChannel> {
+    override fun get(): InputChannel = InputChannel()
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/WindowSessionSupplier.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/WindowSessionSupplier.kt
new file mode 100644
index 0000000..2c66e97
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/WindowSessionSupplier.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.view.IWindowSession
+import android.view.WindowManagerGlobal
+import com.android.wm.shell.dagger.WMSingleton
+import java.util.function.Supplier
+import javax.inject.Inject
+
+/**
+ * An Injectable [Supplier<IWindowSession>]. This can be used in place of kotlin default
+ * parameters values [builder = WindowManagerGlobal::getWindowSession] which requires the
+ * [@JvmOverloads] annotation to make this available in Java.
+ * This can be used every time a component needs the dependency to the default [Supplier] for
+ * [IWindowSession]s.
+ */
+@WMSingleton
+class WindowSessionSupplier @Inject constructor() : Supplier<IWindowSession> {
+    override fun get(): IWindowSession = WindowManagerGlobal.getWindowSession()
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.java
new file mode 100644
index 0000000..c10c2c9
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.pip;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+
+import android.app.ActivityManager;
+import android.window.DisplayAreaInfo;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
+
+import com.android.window.flags.Flags;
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
+import com.android.wm.shell.desktopmode.DesktopRepository;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
+import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider;
+import com.android.wm.shell.pip2.phone.PipTransition;
+
+import java.util.Optional;
+
+/** Helper class for PiP on Desktop Mode. */
+public class PipDesktopState {
+    private final PipDisplayLayoutState mPipDisplayLayoutState;
+    private final Optional<DesktopUserRepositories> mDesktopUserRepositoriesOptional;
+    private final Optional<DesktopWallpaperActivityTokenProvider>
+            mDesktopWallpaperActivityTokenProviderOptional;
+    private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
+
+    public PipDesktopState(PipDisplayLayoutState pipDisplayLayoutState,
+            Optional<DesktopUserRepositories> desktopUserRepositoriesOptional,
+            Optional<DesktopWallpaperActivityTokenProvider>
+                    desktopWallpaperActivityTokenProviderOptional,
+            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
+        mPipDisplayLayoutState = pipDisplayLayoutState;
+        mDesktopUserRepositoriesOptional = desktopUserRepositoriesOptional;
+        mDesktopWallpaperActivityTokenProviderOptional =
+                desktopWallpaperActivityTokenProviderOptional;
+        mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
+    }
+
+    /**
+     * Returns whether PiP in Desktop Windowing is enabled by checking the following:
+     * - Desktop Windowing in PiP flag is enabled
+     * - DesktopWallpaperActivityTokenProvider is injected
+     * - DesktopUserRepositories is injected
+     */
+    public boolean isDesktopWindowingPipEnabled() {
+        return Flags.enableDesktopWindowingPip()
+                && mDesktopWallpaperActivityTokenProviderOptional.isPresent()
+                && mDesktopUserRepositoriesOptional.isPresent();
+    }
+
+    /** Returns whether PiP in Connected Displays is enabled by checking the flag. */
+    public boolean isConnectedDisplaysPipEnabled() {
+        return Flags.enableConnectedDisplaysPip();
+    }
+
+    /** Returns whether the display with the PiP task is in freeform windowing mode. */
+    private boolean isDisplayInFreeform() {
+        final DisplayAreaInfo tdaInfo = mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(
+                mPipDisplayLayoutState.getDisplayId());
+        if (tdaInfo != null) {
+            return tdaInfo.configuration.windowConfiguration.getWindowingMode()
+                    == WINDOWING_MODE_FREEFORM;
+        }
+        return false;
+    }
+
+    /** Returns whether PiP is exiting while we're in a Desktop Mode session. */
+    private boolean isPipExitingToDesktopMode() {
+        // Early return if PiP in Desktop Windowing is not supported.
+        if (!isDesktopWindowingPipEnabled()) {
+            return false;
+        }
+        final int displayId = mPipDisplayLayoutState.getDisplayId();
+        return getDesktopRepository().getVisibleTaskCount(displayId) > 0
+                || getDesktopWallpaperActivityTokenProvider().isWallpaperActivityVisible(displayId)
+                || isDisplayInFreeform();
+    }
+
+    /** Returns whether {@param pipTask} would be entering in a Desktop Mode session. */
+    public boolean isPipEnteringInDesktopMode(ActivityManager.RunningTaskInfo pipTask) {
+        // Early return if PiP in Desktop Windowing is not supported.
+        if (!isDesktopWindowingPipEnabled()) {
+            return false;
+        }
+        final DesktopRepository desktopRepository = getDesktopRepository();
+        return desktopRepository.getVisibleTaskCount(pipTask.getDisplayId()) > 0
+                || desktopRepository.isMinimizedPipPresentInDisplay(pipTask.getDisplayId());
+    }
+
+    /**
+     * Invoked when an EXIT_PiP transition is detected in {@link PipTransition}.
+     * Returns whether the PiP exiting should also trigger the active Desktop Mode session to exit.
+     */
+    public boolean shouldExitPipExitDesktopMode() {
+        // Early return if PiP in Desktop Windowing is not supported.
+        if (!isDesktopWindowingPipEnabled()) {
+            return false;
+        }
+        final int displayId = mPipDisplayLayoutState.getDisplayId();
+        return getDesktopRepository().getVisibleTaskCount(displayId) == 0
+                && getDesktopWallpaperActivityTokenProvider().isWallpaperActivityVisible(displayId);
+    }
+
+    /**
+     * Returns a {@link WindowContainerTransaction} that reorders the {@link WindowContainerToken}
+     * of the DesktopWallpaperActivity for the display with the given {@param displayId}.
+     */
+    public WindowContainerTransaction getWallpaperActivityTokenWct(int displayId) {
+        return new WindowContainerTransaction().reorder(
+                getDesktopWallpaperActivityTokenProvider().getToken(displayId), /* onTop= */ false);
+    }
+
+    /**
+     * The windowing mode to restore to when resizing out of PIP direction.
+     * Defaults to undefined and can be overridden to restore to an alternate windowing mode.
+     */
+    public int getOutPipWindowingMode() {
+        // If we are exiting PiP while the device is in Desktop mode (the task should expand to
+        // freeform windowing mode):
+        // 1) If the display windowing mode is freeform, set windowing mode to UNDEFINED so it will
+        //    resolve the windowing mode to the display's windowing mode.
+        // 2) If the display windowing mode is not FREEFORM, set windowing mode to FREEFORM.
+        if (isPipExitingToDesktopMode()) {
+            if (isDisplayInFreeform()) {
+                return WINDOWING_MODE_UNDEFINED;
+            } else {
+                return WINDOWING_MODE_FREEFORM;
+            }
+        }
+
+        // By default, or if the task is going to fullscreen, reset the windowing mode to undefined.
+        return WINDOWING_MODE_UNDEFINED;
+    }
+
+    private DesktopRepository getDesktopRepository() {
+        return mDesktopUserRepositoriesOptional.get().getCurrent();
+    }
+
+    private DesktopWallpaperActivityTokenProvider getDesktopWallpaperActivityTokenProvider() {
+        return mDesktopWallpaperActivityTokenProviderOptional.get();
+    }
+}
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 2c418d3..06044cc 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
@@ -125,11 +125,13 @@
         }
     };
 
-    private final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() {
+    final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() {
         @Override
         public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
             super.onInitializeAccessibilityNodeInfo(host, info);
             final DividerSnapAlgorithm snapAlgorithm = mSplitLayout.mDividerSnapAlgorithm;
+            info.addAction(new AccessibilityAction(R.id.action_swap_apps,
+                    mContext.getString(R.string.accessibility_action_divider_swap)));
             if (mSplitLayout.isLeftRightSplit()) {
                 info.addAction(new AccessibilityAction(R.id.action_move_tl_full,
                         mContext.getString(R.string.accessibility_action_divider_left_full)));
@@ -172,6 +174,11 @@
         @Override
         public boolean performAccessibilityAction(@NonNull View host, int action,
                 @Nullable Bundle args) {
+            if (action == R.id.action_swap_apps) {
+                mSplitLayout.onDoubleTappedDivider();
+                return true;
+            }
+
             DividerSnapAlgorithm.SnapTarget nextTarget = null;
             DividerSnapAlgorithm snapAlgorithm = mSplitLayout.mDividerSnapAlgorithm;
             if (action == R.id.action_move_tl_full) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/transition/SurfaceBuilderSupplier.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/transition/SurfaceBuilderSupplier.kt
new file mode 100644
index 0000000..0b6c06a
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/transition/SurfaceBuilderSupplier.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.transition
+
+import android.view.SurfaceControl
+import com.android.wm.shell.dagger.WMSingleton
+import java.util.function.Supplier
+import javax.inject.Inject
+
+/**
+ * An Injectable [Supplier<SurfaceControl.Builder>]. This can be used in place of kotlin default
+ * parameters values [builder = ::SurfaceControl.Builder] which requires the [@JvmOverloads]
+ * annotation to make this available in Java.
+ * This can be used every time a component needs the dependency to the default builder for
+ * [SurfaceControl]s.
+ */
+@WMSingleton
+class SurfaceBuilderSupplier @Inject constructor() : Supplier<SurfaceControl.Builder> {
+    override fun get(): SurfaceControl.Builder = SurfaceControl.Builder()
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/transition/TransactionSupplier.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/transition/TransactionSupplier.kt
new file mode 100644
index 0000000..2d9899b
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/transition/TransactionSupplier.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.transition
+
+import android.view.SurfaceControl
+import com.android.wm.shell.dagger.WMSingleton
+import java.util.function.Supplier
+import javax.inject.Inject
+
+/**
+ * An Injectable [Supplier<SurfaceControl.Transaction>]. This can be used in place of kotlin default
+ * parameters values [builder = ::SurfaceControl.Transaction] which requires the [@JvmOverloads]
+ * annotation to make this available in Java.
+ * This can be used every time a component needs the dependency to the default builder for
+ * [SurfaceControl.Transaction]s.
+ */
+@WMSingleton
+class TransactionSupplier @Inject constructor() : Supplier<SurfaceControl.Transaction> {
+    override fun get(): SurfaceControl.Transaction = SurfaceControl.Transaction()
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxGestureListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxGestureListener.kt
new file mode 100644
index 0000000..f7afbb5
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxGestureListener.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.letterbox
+
+import android.view.GestureDetector.OnContextClickListener
+import android.view.GestureDetector.OnDoubleTapListener
+import android.view.GestureDetector.OnGestureListener
+import android.view.MotionEvent
+
+/**
+ * Interface which unions all the interfaces related to gestures.
+ */
+interface LetterboxGestureListener : OnGestureListener, OnDoubleTapListener, OnContextClickListener
+
+/**
+ * Convenience class which provide an overrideable implementation of
+ * {@link LetterboxGestureListener}.
+ */
+object LetterboxGestureDelegate : LetterboxGestureListener {
+    override fun onDown(e: MotionEvent): Boolean = false
+
+    override fun onShowPress(e: MotionEvent) {
+    }
+
+    override fun onSingleTapUp(e: MotionEvent): Boolean = false
+
+    override fun onScroll(
+        e1: MotionEvent?,
+        e2: MotionEvent,
+        distanceX: Float,
+        distanceY: Float
+    ): Boolean = false
+
+    override fun onLongPress(e: MotionEvent) {
+    }
+
+    override fun onFling(
+        e1: MotionEvent?,
+        e2: MotionEvent,
+        velocityX: Float,
+        velocityY: Float
+    ): Boolean = false
+
+    override fun onSingleTapConfirmed(e: MotionEvent): Boolean = false
+
+    override fun onDoubleTap(e: MotionEvent): Boolean = false
+
+    override fun onDoubleTapEvent(e: MotionEvent): Boolean = false
+
+    override fun onContextClick(e: MotionEvent): Boolean = false
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputController.kt
new file mode 100644
index 0000000..afd8e15
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputController.kt
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.letterbox
+
+import android.content.Context
+import android.graphics.Rect
+import android.graphics.Region
+import android.os.Handler
+import android.view.SurfaceControl
+import android.view.SurfaceControl.Transaction
+import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.common.InputChannelSupplier
+import com.android.wm.shell.common.WindowSessionSupplier
+import com.android.wm.shell.compatui.letterbox.LetterboxUtils.Maps.runOnItem
+import com.android.wm.shell.dagger.WMSingleton
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_APP_COMPAT
+import java.util.function.Supplier
+import javax.inject.Inject
+
+/**
+ * [LetterboxController] implementation responsible for handling the spy [SurfaceControl] we use
+ * to detect letterbox events.
+ */
+@WMSingleton
+class LetterboxInputController @Inject constructor(
+    private val context: Context,
+    private val handler: Handler,
+    private val inputSurfaceBuilder: LetterboxInputSurfaceBuilder,
+    private val listenerSupplier: Supplier<LetterboxGestureListener>,
+    private val windowSessionSupplier: WindowSessionSupplier,
+    private val inputChannelSupplier: InputChannelSupplier
+) : LetterboxController {
+
+    companion object {
+        @JvmStatic
+        private val TAG = "LetterboxInputController"
+    }
+
+    private val inputDetectorMap = mutableMapOf<LetterboxKey, LetterboxInputDetector>()
+
+    override fun createLetterboxSurface(
+        key: LetterboxKey,
+        transaction: Transaction,
+        parentLeash: SurfaceControl
+    ) {
+        inputDetectorMap.runOnItem(key, onMissed = { k, m ->
+            m[k] =
+                LetterboxInputDetector(
+                    context,
+                    handler,
+                    listenerSupplier.get(),
+                    inputSurfaceBuilder,
+                    windowSessionSupplier,
+                    inputChannelSupplier
+                ).apply {
+                    start(transaction, parentLeash, key)
+                }
+        })
+    }
+
+    override fun destroyLetterboxSurface(
+        key: LetterboxKey,
+        transaction: Transaction
+    ) {
+        with(inputDetectorMap) {
+            runOnItem(key, onFound = { item ->
+                item.stop(transaction)
+            })
+            remove(key)
+        }
+    }
+
+    override fun updateLetterboxSurfaceVisibility(
+        key: LetterboxKey,
+        transaction: Transaction,
+        visible: Boolean
+    ) {
+        with(inputDetectorMap) {
+            runOnItem(key, onFound = { item ->
+                item.updateVisibility(transaction, visible)
+            })
+        }
+    }
+
+    override fun updateLetterboxSurfaceBounds(
+        key: LetterboxKey,
+        transaction: Transaction,
+        taskBounds: Rect,
+        activityBounds: Rect
+    ) {
+        inputDetectorMap.runOnItem(key, onFound = { item ->
+            item.updateTouchableRegion(transaction, Region(taskBounds))
+        })
+    }
+
+    override fun dump() {
+        ProtoLog.v(WM_SHELL_APP_COMPAT, "%s: %s", TAG, "${inputDetectorMap.keys}")
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt
new file mode 100644
index 0000000..812cc01
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.letterbox
+
+import android.content.Context
+import android.graphics.Region
+import android.os.Binder
+import android.os.Handler
+import android.os.IBinder
+import android.os.RemoteException
+import android.view.GestureDetector
+import android.view.IWindowSession
+import android.view.InputChannel
+import android.view.InputEvent
+import android.view.InputEventReceiver
+import android.view.MotionEvent
+import android.view.SurfaceControl
+import android.view.SurfaceControl.Transaction
+import android.view.WindowManager
+import android.window.InputTransferToken
+import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.common.InputChannelSupplier
+import com.android.wm.shell.common.WindowSessionSupplier
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_APP_COMPAT
+
+/**
+ * This is responsible for detecting events on a given [SurfaceControl].
+ */
+class LetterboxInputDetector(
+    private val context: Context,
+    private val handler: Handler,
+    private val listener: LetterboxGestureListener,
+    private val inputSurfaceBuilder: LetterboxInputSurfaceBuilder,
+    private val windowSessionSupplier: WindowSessionSupplier,
+    private val inputChannelSupplier: InputChannelSupplier
+) {
+
+    companion object {
+        @JvmStatic
+        private val TAG = "LetterboxInputDetector"
+    }
+
+    private var state: InputDetectorState? = null
+
+    fun start(tx: Transaction, source: SurfaceControl, key: LetterboxKey) {
+        if (!isRunning()) {
+            val tmpState =
+                InputDetectorState(
+                    context,
+                    handler,
+                    source,
+                    key.displayId,
+                    listener,
+                    inputSurfaceBuilder,
+                    windowSessionSupplier.get(),
+                    inputChannelSupplier
+                )
+            if (tmpState.start(tx)) {
+                state = tmpState
+            } else {
+                ProtoLog.v(
+                    WM_SHELL_APP_COMPAT,
+                    "%s not started for %s on %s",
+                    TAG,
+                    "$source",
+                    "$key"
+                )
+            }
+        }
+    }
+
+    fun updateTouchableRegion(tx: Transaction, region: Region) {
+        if (isRunning()) {
+            state?.setTouchableRegion(tx, region)
+        }
+    }
+
+    fun isRunning() = state != null
+
+    fun updateVisibility(tx: Transaction, visible: Boolean) {
+        if (isRunning()) {
+            state?.updateVisibility(tx, visible)
+        }
+    }
+
+    fun stop(tx: Transaction) {
+        if (isRunning()) {
+            state!!.stop(tx)
+            state = null
+        }
+    }
+
+    /**
+     * The state for a {@link SurfaceControl} for a given displayId.
+     */
+    private class InputDetectorState(
+        val context: Context,
+        val handler: Handler,
+        val source: SurfaceControl,
+        val displayId: Int,
+        val listener: LetterboxGestureListener,
+        val inputSurfaceBuilder: LetterboxInputSurfaceBuilder,
+        val windowSession: IWindowSession,
+        inputChannelSupplier: InputChannelSupplier
+    ) {
+
+        private val inputToken: IBinder
+        private val inputChannel: InputChannel
+        private var receiver: EventReceiver? = null
+        private var inputSurface: SurfaceControl? = null
+
+        init {
+            inputToken = Binder()
+            inputChannel = inputChannelSupplier.get()
+        }
+
+        fun start(tx: Transaction): Boolean {
+            val inputTransferToken = InputTransferToken()
+            try {
+                inputSurface =
+                    inputSurfaceBuilder.createInputSurface(
+                        tx,
+                        source,
+                        "Sink for $source",
+                        "$TAG creation"
+                    )
+                windowSession.grantInputChannel(
+                    displayId,
+                    inputSurface,
+                    inputToken,
+                    null,
+                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+                    WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY,
+                    WindowManager.LayoutParams.INPUT_FEATURE_SPY,
+                    WindowManager.LayoutParams.TYPE_INPUT_CONSUMER,
+                    null,
+                    inputTransferToken,
+                    "$TAG of $source",
+                    inputChannel
+                )
+
+                receiver = EventReceiver(context, inputChannel, handler, listener)
+                return true
+            } catch (e: RemoteException) {
+                e.rethrowFromSystemServer()
+            }
+            return false
+        }
+
+        fun setTouchableRegion(tx: Transaction, region: Region) {
+            try {
+                tx.setWindowCrop(inputSurface, region.bounds.width(), region.bounds.height())
+
+                windowSession.updateInputChannel(
+                    inputChannel.token,
+                    displayId,
+                    inputSurface,
+                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+                    WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY,
+                    WindowManager.LayoutParams.INPUT_FEATURE_SPY,
+                    region
+                )
+            } catch (e: RemoteException) {
+                e.rethrowFromSystemServer()
+            }
+        }
+
+        fun updateVisibility(tx: Transaction, visible: Boolean) {
+            inputSurface?.let {
+                tx.setVisibility(it, visible)
+            }
+        }
+
+        fun stop(tx: Transaction) {
+            receiver?.dispose()
+            receiver = null
+            inputChannel.dispose()
+            windowSession.removeToken(inputToken)
+            inputSurface?.let { s ->
+                tx.remove(s)
+            }
+        }
+
+        // Removes the provided token
+        private fun IWindowSession.removeToken(token: IBinder) {
+            try {
+                remove(token)
+            } catch (e: RemoteException) {
+                e.rethrowFromSystemServer()
+            }
+        }
+    }
+
+    /**
+     * Reads from the provided {@link InputChannel} and identifies a specific event.
+     */
+    private class EventReceiver(
+        context: Context,
+        inputChannel: InputChannel,
+        uiHandler: Handler,
+        listener: LetterboxGestureListener
+    ) : InputEventReceiver(inputChannel, uiHandler.looper) {
+        private val eventDetector: GestureDetector
+
+        init {
+            eventDetector = GestureDetector(
+                context, listener,
+                uiHandler
+            )
+        }
+
+        override fun onInputEvent(event: InputEvent) {
+            finishInputEvent(event, eventDetector.onTouchEvent(event as MotionEvent))
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputSurfaceBuilder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputSurfaceBuilder.kt
new file mode 100644
index 0000000..fd8d865
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputSurfaceBuilder.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.letterbox
+
+import android.view.SurfaceControl
+import android.view.SurfaceControl.Transaction
+import com.android.wm.shell.common.transition.SurfaceBuilderSupplier
+import com.android.wm.shell.dagger.WMSingleton
+import javax.inject.Inject
+
+/**
+ * Component responsible for the actual creation of the Letterbox surfaces.
+ */
+@WMSingleton
+class LetterboxInputSurfaceBuilder @Inject constructor(
+    private val surfaceBuilderSupplier: SurfaceBuilderSupplier
+) {
+
+    companion object {
+        /*
+         * Letterbox spy surfaces need to stay above the activity layer which is 0.
+         */
+        // TODO(b/378673153): Consider adding this to [TaskConstants].
+        @JvmStatic
+        private val TASK_CHILD_LAYER_LETTERBOX_SPY = 1000
+    }
+
+    fun createInputSurface(
+        tx: Transaction,
+        parentLeash: SurfaceControl,
+        surfaceName: String,
+        callSite: String
+    ) = surfaceBuilderSupplier.get()
+        .setName(surfaceName)
+        .setContainerLayer()
+        .setParent(parentLeash)
+        .setCallsite(callSite)
+        .build().apply {
+            tx.setLayer(this, TASK_CHILD_LAYER_LETTERBOX_SPY)
+                .setTrustedOverlay(this, true)
+                .show(this)
+                .apply()
+        }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/OWNERS
index 752d2fd..8ab53ea 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/OWNERS
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/OWNERS
@@ -1,2 +1,3 @@
 # WM Shell sub-module dagger owners
-jorgegil@google.com
\ No newline at end of file
+jorgegil@google.com
+madym@google.com
\ No newline at end of file
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 0f232d5..6ab103e 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
@@ -53,13 +53,14 @@
 import com.android.wm.shell.apptoweb.AssistContentRequester;
 import com.android.wm.shell.appzoomout.AppZoomOutController;
 import com.android.wm.shell.back.BackAnimationController;
+import com.android.wm.shell.bubbles.bar.BubbleBarDragListener;
 import com.android.wm.shell.bubbles.BubbleController;
 import com.android.wm.shell.bubbles.BubbleData;
 import com.android.wm.shell.bubbles.BubbleDataRepository;
 import com.android.wm.shell.bubbles.BubbleEducationController;
 import com.android.wm.shell.bubbles.BubbleLogger;
 import com.android.wm.shell.bubbles.BubblePositioner;
-import com.android.wm.shell.bubbles.properties.ProdBubbleProperties;
+import com.android.wm.shell.bubbles.BubbleResizabilityChecker;
 import com.android.wm.shell.bubbles.storage.BubblePersistentRepository;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayImeController;
@@ -169,19 +170,18 @@
 import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationTooltipController;
 import com.android.wm.shell.windowdecor.tiling.DesktopTilingDecorViewModel;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
 import dagger.Binds;
 import dagger.Lazy;
 import dagger.Module;
 import dagger.Provides;
-
 import kotlinx.coroutines.CoroutineScope;
 import kotlinx.coroutines.ExperimentalCoroutinesApi;
 import kotlinx.coroutines.MainCoroutineDispatcher;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
 /**
  * Provides dependencies from {@link com.android.wm.shell}, these dependencies are only accessible
  * from components within the WM subcomponent (can be explicitly exposed to the SysUIComponent, see
@@ -294,7 +294,7 @@
                 transitions,
                 syncQueue,
                 wmService,
-                ProdBubbleProperties.INSTANCE);
+                new BubbleResizabilityChecker());
     }
 
     //
@@ -1157,9 +1157,10 @@
     @WMSingleton
     @Provides
     static DesksTransitionObserver provideDesksTransitionObserver(
-            @NonNull @DynamicOverride DesktopUserRepositories desktopUserRepositories
+            @NonNull @DynamicOverride DesktopUserRepositories desktopUserRepositories,
+            @NonNull DesksOrganizer desksOrganizer
     ) {
-        return new DesksTransitionObserver(desktopUserRepositories);
+        return new DesksTransitionObserver(desktopUserRepositories, desksOrganizer);
     }
 
     @WMSingleton
@@ -1411,6 +1412,7 @@
             IconProvider iconProvider,
             GlobalDragListener globalDragListener,
             Transitions transitions,
+            Lazy<BubbleController> bubbleControllerLazy,
             @ShellMainThread ShellExecutor mainExecutor) {
         return new DragAndDropController(
                 context,
@@ -1423,6 +1425,12 @@
                 iconProvider,
                 globalDragListener,
                 transitions,
+                new Lazy<>() {
+                    @Override
+                    public BubbleBarDragListener get() {
+                        return bubbleControllerLazy.get();
+                    }
+                },
                 mainExecutor);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
index 4133006..e7c76bb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
@@ -31,6 +31,7 @@
 import com.android.wm.shell.common.pip.PipAppOpsListener;
 import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
 import com.android.wm.shell.common.pip.PipBoundsState;
+import com.android.wm.shell.common.pip.PipDesktopState;
 import com.android.wm.shell.common.pip.PipDisplayLayoutState;
 import com.android.wm.shell.common.pip.PipMediaController;
 import com.android.wm.shell.common.pip.PipPerfHintController;
@@ -84,14 +85,11 @@
             @NonNull PipDisplayLayoutState pipDisplayLayoutState,
             @NonNull PipUiStateChangeController pipUiStateChangeController,
             DisplayController displayController,
-            Optional<DesktopUserRepositories> desktopUserRepositoriesOptional,
-            Optional<DesktopWallpaperActivityTokenProvider>
-                    desktopWallpaperActivityTokenProviderOptional) {
+            PipDesktopState pipDesktopState) {
         return new PipTransition(context, shellInit, shellTaskOrganizer, transitions,
                 pipBoundsState, null, pipBoundsAlgorithm, pipTaskListener,
                 pipScheduler, pipStackListenerController, pipDisplayLayoutState,
-                pipUiStateChangeController, displayController, desktopUserRepositoriesOptional,
-                desktopWallpaperActivityTokenProviderOptional);
+                pipUiStateChangeController, displayController, pipDesktopState);
     }
 
     @WMSingleton
@@ -142,13 +140,9 @@
             PipBoundsState pipBoundsState,
             @ShellMainThread ShellExecutor mainExecutor,
             PipTransitionState pipTransitionState,
-            Optional<DesktopUserRepositories> desktopUserRepositoriesOptional,
-            Optional<DesktopWallpaperActivityTokenProvider>
-                    desktopWallpaperActivityTokenProviderOptional,
-            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
+            PipDesktopState pipDesktopState) {
         return new PipScheduler(context, pipBoundsState, mainExecutor, pipTransitionState,
-                desktopUserRepositoriesOptional, desktopWallpaperActivityTokenProviderOptional,
-                rootTaskDisplayAreaOrganizer);
+                pipDesktopState);
     }
 
     @WMSingleton
@@ -233,4 +227,17 @@
         return new PipTaskListener(context, shellTaskOrganizer, pipTransitionState,
                 pipScheduler, pipBoundsState, pipBoundsAlgorithm, mainExecutor);
     }
+
+    @WMSingleton
+    @Provides
+    static PipDesktopState providePipDesktopState(
+            PipDisplayLayoutState pipDisplayLayoutState,
+            Optional<DesktopUserRepositories> desktopUserRepositoriesOptional,
+            Optional<DesktopWallpaperActivityTokenProvider>
+                    desktopWallpaperActivityTokenProviderOptional,
+            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer
+    ) {
+        return new PipDesktopState(pipDisplayLayoutState, desktopUserRepositoriesOptional,
+                desktopWallpaperActivityTokenProviderOptional, rootTaskDisplayAreaOrganizer);
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
index a4620d5..c3da154 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
@@ -23,6 +23,7 @@
 import android.view.SurfaceControl
 import android.view.WindowManager.TRANSIT_CHANGE
 import android.view.animation.DecelerateInterpolator
+import android.window.DesktopModeFlags
 import android.window.DesktopModeFlags.ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS
 import android.window.TransitionInfo
 import android.window.TransitionRequestInfo
@@ -152,7 +153,7 @@
         displayId: Int,
         reason: ExitReason,
     ) {
-        if (!Flags.enableFullyImmersiveInDesktop()) return
+        if (!DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue) return
         val result = exitImmersiveIfApplicable(wct, displayId, excludeTaskId = null, reason)
         result.asExit()?.runOnTransitionStart?.invoke(transition)
     }
@@ -171,7 +172,7 @@
         excludeTaskId: Int? = null,
         reason: ExitReason,
     ): ExitResult {
-        if (!Flags.enableFullyImmersiveInDesktop()) return ExitResult.NoExit
+        if (!DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue) return ExitResult.NoExit
         val immersiveTask =
             desktopUserRepositories.current.getTaskInFullImmersiveState(displayId)
                 ?: return ExitResult.NoExit
@@ -213,7 +214,7 @@
         taskInfo: RunningTaskInfo,
         reason: ExitReason,
     ): ExitResult {
-        if (!Flags.enableFullyImmersiveInDesktop()) return ExitResult.NoExit
+        if (!DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue) return ExitResult.NoExit
         if (desktopUserRepositories.current.isTaskInFullImmersiveState(taskInfo.taskId)) {
             // A full immersive task is being minimized, make sure the immersive state is broken
             // (i.e. resize back to max bounds).
@@ -396,7 +397,7 @@
                 taskId = taskId,
                 immersive = pendingTransition.direction == Direction.ENTER,
             )
-            if (Flags.enableRestoreToPreviousSizeFromDesktopImmersive()) {
+            if (DesktopModeFlags.ENABLE_RESTORE_TO_PREVIOUS_SIZE_FROM_DESKTOP_IMMERSIVE.isTrue) {
                 when (pendingTransition.direction) {
                     Direction.EXIT -> {
                         desktopRepository.removeBoundsBeforeFullImmersive(taskId)
@@ -457,7 +458,7 @@
         val displayLayout =
             displayController.getDisplayLayout(taskInfo.displayId)
                 ?: error("Expected non-null display layout for displayId: ${taskInfo.displayId}")
-        return if (Flags.enableRestoreToPreviousSizeFromDesktopImmersive()) {
+        return if (DesktopModeFlags.ENABLE_RESTORE_TO_PREVIOUS_SIZE_FROM_DESKTOP_IMMERSIVE.isTrue) {
             desktopUserRepositories.current.removeBoundsBeforeFullImmersive(taskInfo.taskId)
                 ?: if (ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS.isTrue()) {
                     calculateInitialBounds(displayLayout, taskInfo)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt
index 9666ca9..3356a1c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt
@@ -33,7 +33,6 @@
 import androidx.annotation.VisibleForTesting
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.protolog.ProtoLog
-import com.android.window.flags.Flags
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.freeform.FreeformTaskTransitionHandler
 import com.android.wm.shell.freeform.FreeformTaskTransitionStarter
@@ -105,7 +104,7 @@
         exitingImmersiveTask: Int? = null,
     ): IBinder {
         if (
-            !Flags.enableFullyImmersiveInDesktop() &&
+            !DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue &&
                 !DesktopModeFlags.ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS_BUGFIX.isTrue
         ) {
             return transitions.startTransition(transitionType, wct, /* handler= */ null)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt
index b93d2e3..03bc42f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt
@@ -57,7 +57,7 @@
                 return false
             }
         if (!Flags.enableMultipleDesktopsBackend()) {
-            return controller.moveTaskToDesktop(taskId, transitionSource = UNKNOWN)
+            return controller.moveTaskToDefaultDeskAndActivate(taskId, transitionSource = UNKNOWN)
         }
         if (args.size < 3) {
             pw.println("Error: desk id should be provided as arguments")
@@ -70,8 +70,9 @@
                 pw.println("Error: desk id should be an integer")
                 return false
             }
+        controller.moveTaskToDesk(taskId = taskId, deskId = deskId, transitionSource = UNKNOWN)
         pw.println("Not implemented.")
-        return false
+        return true
     }
 
     private fun runMoveToNextDisplay(args: Array<String>, pw: PrintWriter): Boolean {
@@ -131,8 +132,8 @@
                 pw.println("Error: desk id should be an integer")
                 return false
             }
-        pw.println("Not implemented.")
-        return false
+        controller.activateDesk(deskId)
+        return true
     }
 
     private fun runRemoveDesk(args: Array<String>, pw: PrintWriter): Boolean {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
index 32ee319..27aed17 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
@@ -59,6 +59,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.bubbles.BubbleAnythingFlagHelper;
+import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 
 /**
  * Animated visual indicator for Desktop Mode windowing transitions.
@@ -74,7 +77,11 @@
         /** Indicates impending transition into split select on the left side */
         TO_SPLIT_LEFT_INDICATOR,
         /** Indicates impending transition into split select on the right side */
-        TO_SPLIT_RIGHT_INDICATOR
+        TO_SPLIT_RIGHT_INDICATOR,
+        /** Indicates impending transition into bubble on the left side */
+        TO_BUBBLE_LEFT_INDICATOR,
+        /** Indicates impending transition into bubble on the right side */
+        TO_BUBBLE_RIGHT_INDICATOR
     }
 
     /**
@@ -113,6 +120,7 @@
     private final RootTaskDisplayAreaOrganizer mRootTdaOrganizer;
     private final ActivityManager.RunningTaskInfo mTaskInfo;
     private final SurfaceControl mTaskSurface;
+    private final @Nullable BubbleDropTargetBoundsProvider mBubbleBoundsProvider;
     private SurfaceControl mLeash;
 
     private final SyncTransactionQueue mSyncQueue;
@@ -127,13 +135,15 @@
             ActivityManager.RunningTaskInfo taskInfo, DisplayController displayController,
             Context context, SurfaceControl taskSurface,
             RootTaskDisplayAreaOrganizer taskDisplayAreaOrganizer,
-            DragStartState dragStartState) {
+            DragStartState dragStartState,
+            @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider) {
         mSyncQueue = syncQueue;
         mTaskInfo = taskInfo;
         mDisplayController = displayController;
         mContext = context;
         mTaskSurface = taskSurface;
         mRootTdaOrganizer = taskDisplayAreaOrganizer;
+        mBubbleBoundsProvider = bubbleBoundsProvider;
         mCurrentType = NO_INDICATOR;
         mDragStartState = dragStartState;
     }
@@ -149,12 +159,19 @@
         // left, and split right for the right edge. This is universal across all drag event types.
         if (inputCoordinates.x < 0) return TO_SPLIT_LEFT_INDICATOR;
         if (inputCoordinates.x > layout.width()) return TO_SPLIT_RIGHT_INDICATOR;
-        // If we are in freeform, we don't want a visible indicator in the "freeform" drag zone.
-        // In drags not originating on a freeform caption, we should default to a TO_DESKTOP
-        // indicator.
-        IndicatorType result = mDragStartState == DragStartState.FROM_FREEFORM
-                ? NO_INDICATOR
-                : TO_DESKTOP_INDICATOR;
+        IndicatorType result;
+        if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()
+                && !DesktopModeStatus.canEnterDesktopMode(mContext)) {
+            // If desktop is not available, default to "no indicator"
+            result = NO_INDICATOR;
+        } else {
+            // If we are in freeform, we don't want a visible indicator in the "freeform" drag zone.
+            // In drags not originating on a freeform caption, we should default to a TO_DESKTOP
+            // indicator.
+            result = mDragStartState == DragStartState.FROM_FREEFORM
+                    ? NO_INDICATOR
+                    : TO_DESKTOP_INDICATOR;
+        }
         final int transitionAreaWidth = mContext.getResources().getDimensionPixelSize(
                 com.android.wm.shell.R.dimen.desktop_mode_transition_region_thickness);
         // Because drags in freeform use task position for indicator calculation, we need to
@@ -166,15 +183,24 @@
                 captionHeight);
         final Region splitRightRegion = calculateSplitRightRegion(layout, transitionAreaWidth,
                 captionHeight);
-        if (fullscreenRegion.contains((int) inputCoordinates.x, (int) inputCoordinates.y)) {
+        final int x = (int) inputCoordinates.x;
+        final int y = (int) inputCoordinates.y;
+        if (fullscreenRegion.contains(x, y)) {
             result = TO_FULLSCREEN_INDICATOR;
         }
-        if (splitLeftRegion.contains((int) inputCoordinates.x, (int) inputCoordinates.y)) {
+        if (splitLeftRegion.contains(x, y)) {
             result = IndicatorType.TO_SPLIT_LEFT_INDICATOR;
         }
-        if (splitRightRegion.contains((int) inputCoordinates.x, (int) inputCoordinates.y)) {
+        if (splitRightRegion.contains(x, y)) {
             result = IndicatorType.TO_SPLIT_RIGHT_INDICATOR;
         }
+        if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
+            if (calculateBubbleLeftRegion(layout).contains(x, y)) {
+                result = IndicatorType.TO_BUBBLE_LEFT_INDICATOR;
+            } else if (calculateBubbleRightRegion(layout).contains(x, y)) {
+                result = IndicatorType.TO_BUBBLE_RIGHT_INDICATOR;
+            }
+        }
         if (mDragStartState != DragStartState.DRAGGED_INTENT) {
             transitionIndicator(result);
         }
@@ -238,6 +264,25 @@
         return region;
     }
 
+    @VisibleForTesting
+    Region calculateBubbleLeftRegion(DisplayLayout layout) {
+        int regionWidth = mContext.getResources().getDimensionPixelSize(
+                com.android.wm.shell.R.dimen.bubble_transform_area_width);
+        int regionHeight = mContext.getResources().getDimensionPixelSize(
+                com.android.wm.shell.R.dimen.bubble_transform_area_height);
+        return new Region(0, layout.height() - regionHeight, regionWidth, layout.height());
+    }
+
+    @VisibleForTesting
+    Region calculateBubbleRightRegion(DisplayLayout layout) {
+        int regionWidth = mContext.getResources().getDimensionPixelSize(
+                com.android.wm.shell.R.dimen.bubble_transform_area_width);
+        int regionHeight = mContext.getResources().getDimensionPixelSize(
+                com.android.wm.shell.R.dimen.bubble_transform_area_height);
+        return new Region(layout.width() - regionWidth, layout.height() - regionHeight,
+                layout.width(), layout.height());
+    }
+
     /**
      * Create a fullscreen indicator with no animation
      */
@@ -288,6 +333,11 @@
         });
     }
 
+    @VisibleForTesting
+    Rect getIndicatorBounds() {
+        return mView.getBackground().getBounds();
+    }
+
     /**
      * Fade indicator in as provided type. Animator fades it in while expanding the bounds outwards.
      */
@@ -295,7 +345,8 @@
         mView.setBackgroundResource(R.drawable.desktop_windowing_transition_background);
         final VisualIndicatorAnimator animator = VisualIndicatorAnimator
                 .fadeBoundsIn(mView, type,
-                        mDisplayController.getDisplayLayout(mTaskInfo.displayId));
+                        mDisplayController.getDisplayLayout(mTaskInfo.displayId),
+                        mBubbleBoundsProvider);
         animator.start();
         mCurrentType = type;
     }
@@ -314,7 +365,8 @@
         }
         final VisualIndicatorAnimator animator = VisualIndicatorAnimator
                 .fadeBoundsOut(mView, mCurrentType,
-                        mDisplayController.getDisplayLayout(mTaskInfo.displayId));
+                        mDisplayController.getDisplayLayout(mTaskInfo.displayId),
+                        mBubbleBoundsProvider);
         animator.start();
         if (finishCallback != null) {
             animator.addListener(new AnimatorListenerAdapter() {
@@ -342,7 +394,7 @@
         } else {
             final VisualIndicatorAnimator animator = VisualIndicatorAnimator.animateIndicatorType(
                     mView, mDisplayController.getDisplayLayout(mTaskInfo.displayId), mCurrentType,
-                    newType);
+                    newType, mBubbleBoundsProvider);
             mCurrentType = newType;
             animator.start();
         }
@@ -397,8 +449,9 @@
         }
 
         private static VisualIndicatorAnimator fadeBoundsIn(
-                @NonNull View view, IndicatorType type, @NonNull DisplayLayout displayLayout) {
-            final Rect endBounds = getIndicatorBounds(displayLayout, type);
+                @NonNull View view, IndicatorType type, @NonNull DisplayLayout displayLayout,
+                @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider) {
+            final Rect endBounds = getIndicatorBounds(displayLayout, type, bubbleBoundsProvider);
             final Rect startBounds = getMinBounds(endBounds);
             view.getBackground().setBounds(startBounds);
 
@@ -410,8 +463,9 @@
         }
 
         private static VisualIndicatorAnimator fadeBoundsOut(
-                @NonNull View view, IndicatorType type, @NonNull DisplayLayout displayLayout) {
-            final Rect startBounds = getIndicatorBounds(displayLayout, type);
+                @NonNull View view, IndicatorType type, @NonNull DisplayLayout displayLayout,
+                @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider) {
+            final Rect startBounds = getIndicatorBounds(displayLayout, type, bubbleBoundsProvider);
             final Rect endBounds = getMinBounds(startBounds);
             view.getBackground().setBounds(startBounds);
 
@@ -426,16 +480,19 @@
          * Create animator for visual indicator changing type (i.e., fullscreen to freeform,
          * freeform to split, etc.)
          *
-         * @param view          the view for this indicator
-         * @param displayLayout information about the display the transitioning task is currently on
-         * @param origType      the original indicator type
-         * @param newType       the new indicator type
+         * @param view                 the view for this indicator
+         * @param displayLayout        information about the display the transitioning task is
+         *                             currently on
+         * @param origType             the original indicator type
+         * @param newType              the new indicator type
+         * @param bubbleBoundsProvider provides bounds for bubbles indicators
          */
         private static VisualIndicatorAnimator animateIndicatorType(@NonNull View view,
-                @NonNull DisplayLayout displayLayout, IndicatorType origType,
-                IndicatorType newType) {
-            final Rect startBounds = getIndicatorBounds(displayLayout, origType);
-            final Rect endBounds = getIndicatorBounds(displayLayout, newType);
+                @NonNull DisplayLayout displayLayout, IndicatorType origType, IndicatorType newType,
+                @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider) {
+            final Rect startBounds = getIndicatorBounds(displayLayout, origType,
+                    bubbleBoundsProvider);
+            final Rect endBounds = getIndicatorBounds(displayLayout, newType, bubbleBoundsProvider);
             final VisualIndicatorAnimator animator = new VisualIndicatorAnimator(
                     view, startBounds, endBounds);
             animator.setInterpolator(new DecelerateInterpolator());
@@ -444,7 +501,8 @@
         }
 
         /** Calculates the bounds the indicator should have when fully faded in. */
-        private static Rect getIndicatorBounds(DisplayLayout layout, IndicatorType type) {
+        private static Rect getIndicatorBounds(DisplayLayout layout, IndicatorType type,
+                @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider) {
             final Rect desktopStableBounds = new Rect();
             layout.getStableBounds(desktopStableBounds);
             final int padding = desktopStableBounds.top;
@@ -472,6 +530,18 @@
                     return new Rect(desktopStableBounds.width() / 2 + padding, padding,
                             desktopStableBounds.width() - padding,
                             desktopStableBounds.height());
+                case TO_BUBBLE_LEFT_INDICATOR:
+                    if (bubbleBoundsProvider == null) {
+                        return new Rect();
+                    }
+                    return bubbleBoundsProvider.getBubbleBarExpandedViewDropTargetBounds(
+                            /* onLeft= */ true);
+                case TO_BUBBLE_RIGHT_INDICATOR:
+                    if (bubbleBoundsProvider == null) {
+                        return new Rect();
+                    }
+                    return bubbleBoundsProvider.getBubbleBarExpandedViewDropTargetBounds(
+                            /* onLeft= */ false);
                 default:
                     throw new IllegalArgumentException("Invalid indicator type provided.");
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
index 043b353..4777e7f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
@@ -226,31 +226,42 @@
         desktopData.setActiveDesk(displayId = displayId, deskId = deskId)
     }
 
+    /** Returns the id of the active desk in the given display, if any. */
+    @VisibleForTesting
+    fun getActiveDeskId(displayId: Int): Int? = desktopData.getActiveDesk(displayId)?.deskId
+
     /**
      * Adds task with [taskId] to the list of freeform tasks on [displayId]'s active desk.
      *
      * TODO: b/389960283 - add explicit [deskId] argument.
      */
     fun addTask(displayId: Int, taskId: Int, isVisible: Boolean) {
-        addOrMoveFreeformTaskToTop(displayId, taskId)
-        addActiveTask(displayId, taskId)
-        updateTask(displayId, taskId, isVisible)
+        val activeDesk =
+            checkNotNull(desktopData.getDefaultDesk(displayId)) {
+                "Expected desk in display: $displayId"
+            }
+        addTaskToDesk(displayId = displayId, deskId = activeDesk.deskId, taskId = taskId, isVisible)
     }
 
-    /**
-     * Adds task with [taskId] to the list of active tasks on [displayId]'s active desk.
-     *
-     * TODO: b/389960283 - add explicit [deskId] argument.
-     */
-    private fun addActiveTask(displayId: Int, taskId: Int) {
-        val activeDesk = desktopData.getDefaultDesk(displayId)
-        checkNotNull(activeDesk) { "Expected desk in display: $displayId" }
+    fun addTaskToDesk(displayId: Int, deskId: Int, taskId: Int, isVisible: Boolean) {
+        addOrMoveTaskToTopOfDesk(displayId = displayId, deskId = deskId, taskId = taskId)
+        addActiveTaskToDesk(displayId = displayId, deskId = deskId, taskId = taskId)
+        updateTaskInDesk(
+            displayId = displayId,
+            deskId = deskId,
+            taskId = taskId,
+            isVisible = isVisible,
+        )
+    }
 
-        // Removes task if it is active on another desk excluding [activeDesk].
-        removeActiveTask(taskId, excludedDeskId = activeDesk.deskId)
+    private fun addActiveTaskToDesk(displayId: Int, deskId: Int, taskId: Int) {
+        val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" }
 
-        if (activeDesk.activeTasks.add(taskId)) {
-            logD("Adds active task=%d displayId=%d deskId=%d", taskId, displayId, activeDesk.deskId)
+        // Removes task if it is active on another desk excluding this desk.
+        removeActiveTask(taskId, excludedDeskId = deskId)
+
+        if (desk.activeTasks.add(taskId)) {
+            logD("Adds active task=%d displayId=%d deskId=%d", taskId, displayId, deskId)
             updateActiveTasksListeners(displayId)
         }
     }
@@ -401,10 +412,10 @@
                 emptySet()
             }
 
-    /** Removes task from visible tasks of all displays except [excludedDisplayId]. */
-    private fun removeVisibleTask(taskId: Int, excludedDisplayId: Int? = null) {
+    /** Removes task from visible tasks of all desks except [excludedDeskId]. */
+    private fun removeVisibleTask(taskId: Int, excludedDeskId: Int? = null) {
         desktopData.forAllDesks { displayId, desk ->
-            if (displayId != excludedDisplayId && desk.visibleTasks.remove(taskId)) {
+            if (desk.deskId != excludedDeskId && desk.visibleTasks.remove(taskId)) {
                 notifyVisibleTaskListeners(displayId, desk.visibleTasks.size)
             }
         }
@@ -419,30 +430,58 @@
      * TODO: b/389960283 - add explicit [deskId] argument.
      */
     fun updateTask(displayId: Int, taskId: Int, isVisible: Boolean) {
-        logD("updateTask taskId=%d, displayId=%d, isVisible=%b", taskId, displayId, isVisible)
-
-        if (isVisible) {
-            // If task is visible, remove it from any other display besides [displayId].
-            removeVisibleTask(taskId, excludedDisplayId = displayId)
-        } else if (displayId == INVALID_DISPLAY) {
-            // Task has vanished. Check which display to remove the task from.
-            removeVisibleTask(taskId)
+        val validDisplayId =
+            if (displayId == INVALID_DISPLAY) {
+                // When a task vanishes it doesn't have a displayId. Find the display of the task.
+                getDisplayIdForTask(taskId)
+            } else {
+                displayId
+            }
+        if (validDisplayId == null) {
+            logW("No display id found for task: taskId=%d", taskId)
             return
         }
-        val prevCount = getVisibleTaskCount(displayId)
+        val desk =
+            checkNotNull(desktopData.getDefaultDesk(validDisplayId)) {
+                "Expected a desk in display: $validDisplayId"
+            }
+        updateTaskInDesk(
+            displayId = validDisplayId,
+            deskId = desk.deskId,
+            taskId = taskId,
+            isVisible,
+        )
+    }
+
+    private fun updateTaskInDesk(displayId: Int, deskId: Int, taskId: Int, isVisible: Boolean) {
+        check(displayId != INVALID_DISPLAY) { "Display must be valid" }
+        logD(
+            "updateTaskInDesk taskId=%d, deskId=%d, displayId=%d, isVisible=%b",
+            taskId,
+            deskId,
+            displayId,
+            isVisible,
+        )
+
         if (isVisible) {
-            desktopData.getDefaultDesk(displayId)?.visibleTasks?.add(taskId)
-                ?: error("Expected non-null desk in display $displayId")
+            // If task is visible, remove it from any other desk besides [deskId].
+            removeVisibleTask(taskId, excludedDeskId = deskId)
+        }
+        val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" }
+        val prevCount = getVisibleTaskCountInDesk(deskId)
+        if (isVisible) {
+            desk.visibleTasks.add(taskId)
             unminimizeTask(displayId, taskId)
         } else {
-            desktopData.getActiveDesk(displayId)?.visibleTasks?.remove(taskId)
+            desk.visibleTasks.remove(taskId)
         }
-        val newCount = getVisibleTaskCount(displayId)
+        val newCount = getVisibleTaskCount(deskId)
         if (prevCount != newCount) {
             logD(
-                "Update task visibility taskId=%d visible=%b displayId=%d",
+                "Update task visibility taskId=%d visible=%b deskId=%d displayId=%d",
                 taskId,
                 isVisible,
+                deskId,
                 displayId,
             )
             logD("VisibleTaskCount has changed from %d to %d", prevCount, newCount)
@@ -602,33 +641,32 @@
     /**
      * Gets number of visible freeform tasks on given [displayId]'s active desk.
      *
-     * TODO: b/389960283 - add explicit [deskId] argument.
+     * TODO: b/389960283 - migrate callers to [getVisibleTaskCountInDesk].
      */
     fun getVisibleTaskCount(displayId: Int): Int =
         (desktopData.getActiveDesk(displayId)?.visibleTasks?.size ?: 0).also {
             logD("getVisibleTaskCount=$it")
         }
 
+    /** Gets the number of visible tasks on the given desk. */
+    fun getVisibleTaskCountInDesk(deskId: Int): Int =
+        desktopData.getDesk(deskId)?.visibleTasks?.size ?: 0
+
     /**
      * Adds task (or moves if it already exists) to the top of the ordered list.
      *
      * Unminimizes the task if it is minimized.
-     *
-     * TODO: b/389960283 - add explicit [deskId] argument.
      */
-    private fun addOrMoveFreeformTaskToTop(displayId: Int, taskId: Int) {
-        val desk = getDefaultDesk(displayId) ?: error("Expected a desk in display: $displayId")
-        logD(
-            "Add or move task to top: display=%d taskId=%d deskId=%d",
-            taskId,
-            displayId,
-            desk.deskId,
-        )
+    private fun addOrMoveTaskToTopOfDesk(displayId: Int, deskId: Int, taskId: Int) {
+        val desk = desktopData.getDesk(deskId) ?: error("Could not find desk: $deskId")
+        logD("addOrMoveTaskToTopOfDesk: display=%d deskId=%d taskId=%d", displayId, deskId, taskId)
         desktopData.forAllDesks { _, desk1 -> desk1.freeformTasksInZOrder.remove(taskId) }
         desk.freeformTasksInZOrder.add(0, taskId)
+        // TODO: double check minimization logic.
         // Unminimize the task if it is minimized.
         unminimizeTask(displayId, taskId)
         if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
+            // TODO: can probably just update the desk.
             updatePersistentRepository(displayId)
         }
     }
@@ -644,6 +682,7 @@
             // mark it as minimized.
             getDisplayIdForTask(taskId)?.let { minimizeTask(it, taskId) }
                 ?: logW("Minimize task: No display id found for task: taskId=%d", taskId)
+            return
         } else {
             logD("Minimize Task: display=%d, task=%d", displayId, taskId)
             desktopData.getActiveDesk(displayId)?.minimizedTasks?.add(taskId)
@@ -676,7 +715,7 @@
     private fun getDisplayIdForTask(taskId: Int): Int? {
         var displayForTask: Int? = null
         desktopData.forAllDesks { displayId, desk ->
-            if (taskId in desk.freeformTasksInZOrder) {
+            if (taskId in desk.activeTasks) {
                 displayForTask = displayId
             }
         }
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 3f88e7b..0d32acd 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
@@ -150,6 +150,7 @@
 import java.util.concurrent.Executor
 import java.util.concurrent.TimeUnit
 import java.util.function.Consumer
+import kotlin.jvm.optionals.getOrNull
 
 /** Handles moving tasks in and out of desktop */
 class DesktopTasksController(
@@ -315,24 +316,10 @@
     }
 
     /** Show all tasks, that are part of the desktop, on top of launcher */
+    @Deprecated("Use activateDesk() instead.", ReplaceWith("activateDesk()"))
     fun showDesktopApps(displayId: Int, remoteTransition: RemoteTransition? = null) {
         logV("showDesktopApps")
-        val wct = WindowContainerTransaction()
-        bringDesktopAppsToFront(displayId, wct)
-
-        val transitionType = transitionType(remoteTransition)
-        val handler =
-            remoteTransition?.let {
-                OneShotRemoteHandler(transitions.mainExecutor, remoteTransition)
-            }
-        transitions.startTransition(transitionType, wct, handler).also { t ->
-            handler?.setTransition(t)
-        }
-
-        // launch from recent DesktopTaskView
-        desktopModeEnterExitTransitionListener?.onEnterDesktopModeTransitionStarted(
-            FREEFORM_ANIMATION_DURATION
-        )
+        activateDefaultDeskInDisplay(displayId, remoteTransition)
     }
 
     /** Gets number of visible freeform tasks in [displayId]. */
@@ -371,15 +358,15 @@
             0 -> return
             // Full screen case
             1 ->
-                moveRunningTaskToDesktop(
-                    allFocusedTasks.single(),
+                moveTaskToDefaultDeskAndActivate(
+                    allFocusedTasks.single().taskId,
                     transitionSource = transitionSource,
                 )
             // Split-screen case where there are two focused tasks, then we find the child
             // task to move to desktop.
             2 ->
-                moveRunningTaskToDesktop(
-                    getSplitFocusedTask(allFocusedTasks[0], allFocusedTasks[1]),
+                moveTaskToDefaultDeskAndActivate(
+                    getSplitFocusedTask(allFocusedTasks[0], allFocusedTasks[1]).taskId,
                     transitionSource = transitionSource,
                 )
             else ->
@@ -442,7 +429,7 @@
 
     /** Moves task to desktop mode if task is running, else launches it in desktop mode. */
     @JvmOverloads
-    fun moveTaskToDesktop(
+    fun moveTaskToDefaultDeskAndActivate(
         taskId: Int,
         wct: WindowContainerTransaction = WindowContainerTransaction(),
         transitionSource: DesktopModeTransitionSource,
@@ -450,7 +437,49 @@
         callback: IMoveToDesktopCallback? = null,
     ): Boolean {
         val runningTask = shellTaskOrganizer.getRunningTaskInfo(taskId)
-        if (runningTask == null) {
+        val backgroundTask = recentTasksController?.findTaskInBackground(taskId)
+        if (runningTask == null && backgroundTask == null) {
+            logW("moveTaskToDefaultDeskAndActivate taskId=%d not found", taskId)
+            return false
+        }
+        // TODO(342378842): Instead of using default display, support multiple displays
+        val displayId = runningTask?.displayId ?: DEFAULT_DISPLAY
+        val deskId =
+            checkNotNull(taskRepository.getDefaultDeskId(displayId)) {
+                "Expected a default desk to exist"
+            }
+        return moveTaskToDesk(
+            taskId = taskId,
+            deskId = deskId,
+            wct = wct,
+            transitionSource = transitionSource,
+            remoteTransition = remoteTransition,
+        )
+    }
+
+    /** Moves task to desktop mode if task is running, else launches it in desktop mode. */
+    fun moveTaskToDesk(
+        taskId: Int,
+        deskId: Int,
+        wct: WindowContainerTransaction = WindowContainerTransaction(),
+        transitionSource: DesktopModeTransitionSource,
+        remoteTransition: RemoteTransition? = null,
+        callback: IMoveToDesktopCallback? = null,
+    ): Boolean {
+        val runningTask = shellTaskOrganizer.getRunningTaskInfo(taskId)
+        if (runningTask != null) {
+            moveRunningTaskToDesk(
+                task = runningTask,
+                deskId = deskId,
+                wct = wct,
+                transitionSource = transitionSource,
+                remoteTransition = remoteTransition,
+                callback = callback,
+            )
+        }
+        val backgroundTask = recentTasksController?.findTaskInBackground(taskId)
+        if (backgroundTask != null) {
+            // TODO: b/391484662 - add support for |deskId|.
             return moveBackgroundTaskToDesktop(
                 taskId,
                 wct,
@@ -459,8 +488,8 @@
                 callback,
             )
         }
-        moveRunningTaskToDesktop(runningTask, wct, transitionSource, remoteTransition, callback)
-        return true
+        logW("moveTaskToDesk taskId=%d not found", taskId)
+        return false
     }
 
     private fun moveBackgroundTaskToDesktop(
@@ -514,8 +543,9 @@
     }
 
     /** Moves a running task to desktop. */
-    fun moveRunningTaskToDesktop(
+    private fun moveRunningTaskToDesk(
         task: RunningTaskInfo,
+        deskId: Int,
         wct: WindowContainerTransaction = WindowContainerTransaction(),
         transitionSource: DesktopModeTransitionSource,
         remoteTransition: RemoteTransition? = null,
@@ -525,20 +555,49 @@
             logW("Cannot enter desktop for taskId %d, ineligible top activity found", task.taskId)
             return
         }
-        logV("moveRunningTaskToDesktop taskId=%d", task.taskId)
+        val displayId = taskRepository.getDisplayForDesk(deskId)
+        logV(
+            "moveRunningTaskToDesk taskId=%d deskId=%d displayId=%d",
+            task.taskId,
+            deskId,
+            displayId,
+        )
         exitSplitIfApplicable(wct, task)
         val exitResult =
             desktopImmersiveController.exitImmersiveIfApplicable(
                 wct = wct,
-                displayId = task.displayId,
+                displayId = displayId,
                 excludeTaskId = task.taskId,
                 reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
             )
 
-        // Bring other apps to front first
         val taskIdToMinimize =
-            bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId)
-        addMoveToDesktopChanges(wct, task)
+            if (Flags.enableMultipleDesktopsBackend()) {
+                // Activate the desk first.
+                prepareForDeskActivation(displayId, wct)
+                desksOrganizer.activateDesk(wct, deskId)
+                if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
+                    // TODO: 362720497 - do non-running tasks need to be restarted with
+                    // |wct#startTask|?
+                }
+                taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(
+                    doesAnyTaskRequireTaskbarRounding(displayId)
+                )
+                // TODO: 362720497 - activating a desk with the intention to move a new task to it
+                //  means we may need to minimize something in the activating desk. Do so here
+                // similar
+                //  to how it's done in #bringDesktopAppsToFrontBeforeShowingNewTask instead of
+                //  returning null.
+                null
+            } else {
+                // Bring other apps to front first.
+                bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId)
+            }
+        if (Flags.enableMultipleDesktopsBackend()) {
+            prepareMoveTaskToDesk(wct, task, deskId)
+        } else {
+            addMoveToDesktopChanges(wct, task)
+        }
 
         val transition: IBinder
         if (remoteTransition != null) {
@@ -557,6 +616,18 @@
             addPendingMinimizeTransition(transition, it, MinimizeReason.TASK_LIMIT)
         }
         exitResult.asExit()?.runOnTransitionStart?.invoke(transition)
+        if (Flags.enableMultipleDesktopsBackend()) {
+            desksTransitionObserver.addPendingTransition(
+                DeskTransition.ActiveDeskWithTask(
+                    token = transition,
+                    displayId = displayId,
+                    deskId = deskId,
+                    enterTaskId = task.taskId,
+                )
+            )
+        } else {
+            taskRepository.setActiveDesk(displayId = displayId, deskId = deskId)
+        }
     }
 
     private fun invokeCallbackToOverview(transition: IBinder, callback: IMoveToDesktopCallback?) {
@@ -606,9 +677,9 @@
         val wct = WindowContainerTransaction()
         exitSplitIfApplicable(wct, taskInfo)
         if (Flags.enablePerDisplayDesktopWallpaperActivity()) {
-            moveHomeTask(wct, toTop = true, taskInfo.displayId)
+            moveHomeTask(taskInfo.displayId, wct)
         } else {
-            moveHomeTask(wct, toTop = true)
+            moveHomeTask(context.displayId, wct)
         }
         val taskIdToMinimize =
             bringDesktopAppsToFrontBeforeShowingNewTask(taskInfo.displayId, wct, taskInfo.taskId)
@@ -780,7 +851,7 @@
 
         // We are moving a freeform task to fullscreen, put the home task under the fullscreen task.
         if (!forceEnterDesktop(task.displayId)) {
-            moveHomeTask(wct, toTop = true, task.displayId)
+            moveHomeTask(task.displayId, wct)
             wct.reorder(task.token, /* onTop= */ true)
         }
 
@@ -1018,6 +1089,23 @@
         }
 
         val wct = WindowContainerTransaction()
+
+        // check if the task is part of splitscreen
+        if (
+            Flags.enableNonDefaultDisplaySplit() &&
+                Flags.enableMoveToNextDisplayShortcut() &&
+                splitScreenController.isTaskInSplitScreen(task.taskId)
+        ) {
+            val stageCoordinatorRootTaskToken =
+                splitScreenController.multiDisplayProvider.getDisplayRootForDisplayId(
+                    DEFAULT_DISPLAY
+                )
+
+            wct.reparent(stageCoordinatorRootTaskToken, displayAreaInfo.token, true /* onTop */)
+            transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ null)
+            return
+        }
+
         if (!task.isFreeform) {
             addMoveToDesktopChanges(wct, task, displayId)
         } else if (Flags.enableMoveToNextDisplayShortcut()) {
@@ -1037,6 +1125,10 @@
                 task.displayId,
                 wct,
                 forceToFullscreen = false,
+                // TODO: b/371096166 - Temporary turing home relaunch off to prevent home stealing
+                // display focus. Remove shouldEndUpAtHome = false when home focus handling
+                // with connected display is implemented in wm core.
+                shouldEndUpAtHome = false,
             )
         }
 
@@ -1416,33 +1508,36 @@
             ?: WINDOWING_MODE_UNDEFINED
     }
 
+    private fun prepareForDeskActivation(displayId: Int, wct: WindowContainerTransaction) {
+        // Move home to front, ensures that we go back home when all desktop windows are closed
+        val useParamDisplayId =
+            Flags.enableMultipleDesktopsBackend() ||
+                Flags.enablePerDisplayDesktopWallpaperActivity()
+        moveHomeTask(displayId = if (useParamDisplayId) displayId else context.displayId, wct = wct)
+        // Currently, we only handle the desktop on the default display really.
+        if (
+            (displayId == DEFAULT_DISPLAY || Flags.enablePerDisplayDesktopWallpaperActivity()) &&
+                ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY.isTrue()
+        ) {
+            // Add translucent wallpaper activity to show the wallpaper underneath.
+            addWallpaperActivity(displayId, wct)
+        }
+    }
+
     private fun bringDesktopAppsToFrontBeforeShowingNewTask(
         displayId: Int,
         wct: WindowContainerTransaction,
         newTaskIdInFront: Int,
     ): Int? = bringDesktopAppsToFront(displayId, wct, newTaskIdInFront)
 
+    @Deprecated("Use activeDesk() instead.", ReplaceWith("activateDesk()"))
     private fun bringDesktopAppsToFront(
         displayId: Int,
         wct: WindowContainerTransaction,
         newTaskIdInFront: Int? = null,
     ): Int? {
         logV("bringDesktopAppsToFront, newTaskId=%d", newTaskIdInFront)
-        // Move home to front, ensures that we go back home when all desktop windows are closed
-        if (Flags.enablePerDisplayDesktopWallpaperActivity()) {
-            moveHomeTask(wct, toTop = true, displayId)
-        } else {
-            moveHomeTask(wct, toTop = true)
-        }
-
-        // Currently, we only handle the desktop on the default display really.
-        if (
-            (displayId == DEFAULT_DISPLAY || Flags.enablePerDisplayDesktopWallpaperActivity()) &&
-                ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY.isTrue()
-        ) {
-            // Add translucent wallpaper activity to show the wallpaper underneath
-            addWallpaperActivity(displayId, wct)
-        }
+        prepareForDeskActivation(displayId, wct)
 
         val expandedTasksOrderedFrontToBack = taskRepository.getExpandedTasksOrdered(displayId)
         // If we're adding a new Task we might need to minimize an old one
@@ -1486,15 +1581,11 @@
         return taskIdToMinimize
     }
 
-    private fun moveHomeTask(
-        wct: WindowContainerTransaction,
-        toTop: Boolean,
-        displayId: Int = DEFAULT_DISPLAY,
-    ) {
+    private fun moveHomeTask(displayId: Int, wct: WindowContainerTransaction) {
         shellTaskOrganizer
             .getRunningTasks(displayId)
             .firstOrNull { task -> task.activityType == ACTIVITY_TYPE_HOME }
-            ?.let { homeTask -> wct.reorder(homeTask.getToken(), /* onTop= */ toTop) }
+            ?.let { homeTask -> wct.reorder(homeTask.getToken(), /* onTop= */ true) }
     }
 
     private fun addLaunchHomePendingIntent(wct: WindowContainerTransaction, displayId: Int) {
@@ -1528,16 +1619,11 @@
     private fun addWallpaperActivity(displayId: Int, wct: WindowContainerTransaction) {
         logV("addWallpaperActivity")
         if (ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER.isTrue()) {
-
-            // If the wallpaper activity for this display already exists, let's reorder it to top.
-            val wallpaperActivityToken = desktopWallpaperActivityTokenProvider.getToken(displayId)
-            if (wallpaperActivityToken != null) {
-                wct.reorder(wallpaperActivityToken, /* onTop= */ true)
-                return
-            }
-
             val intent = Intent(context, DesktopWallpaperActivity::class.java)
-            if (Flags.enablePerDisplayDesktopWallpaperActivity()) {
+            if (
+                desktopWallpaperActivityTokenProvider.getToken(displayId) == null &&
+                    Flags.enablePerDisplayDesktopWallpaperActivity()
+            ) {
                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                 intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
             }
@@ -1751,7 +1837,7 @@
     /** Whether the given [change] in the [transition] is a known desktop change. */
     fun isDesktopChange(transition: IBinder, change: TransitionInfo.Change): Boolean {
         // Only the immersive controller is currently involved in mixed transitions.
-        return Flags.enableFullyImmersiveInDesktop() &&
+        return DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue &&
             desktopImmersiveController.isImmersiveChange(transition, change)
     }
 
@@ -1762,7 +1848,7 @@
      */
     fun shouldPlayDesktopAnimation(info: TransitionRequestInfo): Boolean {
         // Only immersive mixed transition are currently supported.
-        if (!Flags.enableFullyImmersiveInDesktop()) return false
+        if (!DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue) return false
         val triggerTask = info.triggerTask ?: return false
         if (!isDesktopModeShowing(triggerTask.displayId)) {
             return false
@@ -2155,6 +2241,7 @@
      * different [displayId] if the task should be moved to a different display.
      */
     @VisibleForTesting
+    @Deprecated("Deprecated with multiple desks", ReplaceWith("prepareMoveTaskToDesk()"))
     fun addMoveToDesktopChanges(
         wct: WindowContainerTransaction,
         taskInfo: RunningTaskInfo,
@@ -2182,6 +2269,24 @@
         }
     }
 
+    private fun prepareMoveTaskToDesk(
+        wct: WindowContainerTransaction,
+        taskInfo: RunningTaskInfo,
+        deskId: Int,
+    ) {
+        if (!Flags.enableMultipleDesktopsBackend()) return
+        val displayId = taskRepository.getDisplayForDesk(deskId)
+        val displayLayout = displayController.getDisplayLayout(displayId) ?: return
+        val initialBounds = getInitialBounds(displayLayout, taskInfo, displayId)
+        if (canChangeTaskPosition(taskInfo)) {
+            wct.setBounds(taskInfo.token, initialBounds)
+        }
+        desksOrganizer.moveTaskToDesk(wct, deskId = deskId, task = taskInfo)
+        if (useDesktopOverrideDensity()) {
+            wct.setDensityDpi(taskInfo.token, DESKTOP_DENSITY_OVERRIDE)
+        }
+    }
+
     /**
      * Apply changes to move a freeform task from one display to another, which includes handling
      * density changes between displays.
@@ -2377,6 +2482,57 @@
         )
     }
 
+    private fun activateDefaultDeskInDisplay(
+        displayId: Int,
+        remoteTransition: RemoteTransition? = null,
+    ) {
+        val deskId =
+            checkNotNull(taskRepository.getDefaultDeskId(displayId)) {
+                "Expected a default desk to exist"
+            }
+        activateDesk(deskId, remoteTransition)
+    }
+
+    /** Activates the given desk. */
+    fun activateDesk(deskId: Int, remoteTransition: RemoteTransition? = null) {
+        val displayId = taskRepository.getDisplayForDesk(deskId)
+        val wct = WindowContainerTransaction()
+        if (Flags.enableMultipleDesktopsBackend()) {
+            prepareForDeskActivation(displayId, wct)
+            desksOrganizer.activateDesk(wct, deskId)
+            if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
+                // TODO: 362720497 - do non-running tasks need to be restarted with |wct#startTask|?
+            }
+            taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(
+                doesAnyTaskRequireTaskbarRounding(displayId)
+            )
+        } else {
+            bringDesktopAppsToFront(displayId, wct)
+        }
+
+        val transitionType = transitionType(remoteTransition)
+        val handler =
+            remoteTransition?.let {
+                OneShotRemoteHandler(transitions.mainExecutor, remoteTransition)
+            }
+
+        val transition = transitions.startTransition(transitionType, wct, handler)
+        handler?.setTransition(transition)
+        if (Flags.enableMultipleDesktopsBackend()) {
+            desksTransitionObserver.addPendingTransition(
+                DeskTransition.ActivateDesk(
+                    token = transition,
+                    displayId = displayId,
+                    deskId = deskId,
+                )
+            )
+        }
+
+        desktopModeEnterExitTransitionListener?.onEnterDesktopModeTransitionStarted(
+            FREEFORM_ANIMATION_DURATION
+        )
+    }
+
     /** Removes the default desk in the given display. */
     @Deprecated("Deprecated with multi-desks.", ReplaceWith("removeDesk()"))
     fun removeDefaultDeskInDisplay(displayId: Int) {
@@ -2551,6 +2707,7 @@
                     taskSurface,
                     rootTaskDisplayAreaOrganizer,
                     dragStartState,
+                    bubbleController.getOrNull()?.bubbleDropTargetBoundsProvider,
                 )
         if (visualIndicator == null) visualIndicator = indicator
         return indicator.updateIndicatorType(PointF(inputX, taskTop))
@@ -2633,7 +2790,11 @@
                     desktopModeWindowDecoration,
                 )
             }
-            IndicatorType.NO_INDICATOR -> {
+            IndicatorType.NO_INDICATOR,
+            IndicatorType.TO_BUBBLE_LEFT_INDICATOR,
+            IndicatorType.TO_BUBBLE_RIGHT_INDICATOR -> {
+                // TODO(b/391928049): add support fof dragging desktop apps to a bubble
+
                 // Create a copy so that we can animate from the current bounds if we end up having
                 // to snap the surface back without a WCT change.
                 val destinationBounds = Rect(currentDragBounds)
@@ -2760,6 +2921,11 @@
                 )
                 requestSplit(taskInfo, leftOrTop = false)
             }
+            IndicatorType.TO_BUBBLE_LEFT_INDICATOR,
+            IndicatorType.TO_BUBBLE_RIGHT_INDICATOR -> {
+                // TODO(b/388851898): move to bubble
+                cancelDragToDesktop(taskInfo)
+            }
         }
         return indicatorType
     }
@@ -2905,7 +3071,7 @@
 
     /** Called when a task's info changes. */
     fun onTaskInfoChanged(taskInfo: RunningTaskInfo) {
-        if (!Flags.enableFullyImmersiveInDesktop()) return
+        if (!DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue) return
         val inImmersive = taskRepository.isTaskInFullImmersiveState(taskInfo.taskId)
         val requestingImmersive = taskInfo.requestingImmersive
         if (
@@ -3125,7 +3291,7 @@
             callback: IMoveToDesktopCallback?,
         ) {
             executeRemoteCallWithTaskPermission(controller, "moveTaskToDesktop") { c ->
-                c.moveTaskToDesktop(
+                c.moveTaskToDefaultDeskAndActivate(
                     taskId,
                     transitionSource = transitionSource,
                     remoteTransition = remoteTransition,
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 cc3d86c..2ac76f3 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
@@ -959,9 +959,16 @@
         super.setupEndDragToDesktop(info, startTransaction, finishTransaction)
 
         val state = requireTransitionState()
-        val homeLeash = state.homeChange?.leash ?: error("Expects home leash to be non-null")
-        // Hide home on finish to prevent flickering when wallpaper activity flag is enabled
-        finishTransaction.hide(homeLeash)
+        val homeLeash = state.homeChange?.leash
+        if (homeLeash == null) {
+            ProtoLog.e(
+                ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
+                "DragToDesktop: home leash is null",
+            )
+        } else {
+            // Hide home on finish to prevent flickering when wallpaper activity flag is enabled
+            finishTransaction.hide(homeLeash)
+        }
         // Setup freeform tasks before animation
         state.freeformTaskChanges.forEach { change ->
             val startScale = FREEFORM_TASKS_INITIAL_SCALE
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppHandleEducationDatastoreRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppHandleEducationDatastoreRepository.kt
index d061e03..3af52b3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppHandleEducationDatastoreRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppHandleEducationDatastoreRepository.kt
@@ -22,6 +22,7 @@
 import androidx.datastore.core.DataStore
 import androidx.datastore.core.DataStoreFactory
 import androidx.datastore.core.Serializer
+import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
 import androidx.datastore.dataStoreFile
 import com.android.framework.protobuf.InvalidProtocolBufferException
 import com.android.internal.annotations.VisibleForTesting
@@ -48,6 +49,10 @@
         DataStoreFactory.create(
             serializer = WindowingEducationProtoSerializer,
             produceFile = { context.dataStoreFile(APP_HANDLE_EDUCATION_DATASTORE_FILEPATH) },
+            corruptionHandler =
+                ReplaceFileCorruptionHandler(
+                    produceNewData = { WindowingEducationProto.getDefaultInstance() }
+                ),
         )
     )
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppToWebEducationDatastoreRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppToWebEducationDatastoreRepository.kt
index e5ad901..f16428d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppToWebEducationDatastoreRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppToWebEducationDatastoreRepository.kt
@@ -22,6 +22,7 @@
 import androidx.datastore.core.DataStore
 import androidx.datastore.core.DataStoreFactory
 import androidx.datastore.core.Serializer
+import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
 import androidx.datastore.dataStoreFile
 import com.android.framework.protobuf.InvalidProtocolBufferException
 import com.android.internal.annotations.VisibleForTesting
@@ -42,6 +43,10 @@
         DataStoreFactory.create(
             serializer = WindowingEducationProtoSerializer,
             produceFile = { context.dataStoreFile(APP_TO_WEB_EDUCATION_DATASTORE_FILEPATH) },
+            corruptionHandler =
+                ReplaceFileCorruptionHandler(
+                    produceNewData = { WindowingEducationProto.getDefaultInstance() }
+                ),
         )
     )
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DeskTransition.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DeskTransition.kt
index 47088c0..8c4fd9d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DeskTransition.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DeskTransition.kt
@@ -30,4 +30,16 @@
         val tasks: Set<Int>,
         val onDeskRemovedListener: OnDeskRemovedListener?,
     ) : DeskTransition()
+
+    /** A transition to activate a desk in its display. */
+    data class ActivateDesk(override val token: IBinder, val displayId: Int, val deskId: Int) :
+        DeskTransition()
+
+    /** A transition to activate a desk by moving an outside task to it. */
+    data class ActiveDeskWithTask(
+        override val token: IBinder,
+        val displayId: Int,
+        val deskId: Int,
+        val enterTaskId: Int,
+    ) : DeskTransition()
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt
index 5cbb59f..547890a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt
@@ -43,6 +43,9 @@
      */
     fun getDeskAtEnd(change: TransitionInfo.Change): Int?
 
+    /** Whether the desk is activate according to the given change at the end of a transition. */
+    fun isDeskActiveAtEnd(change: TransitionInfo.Change, deskId: Int): Boolean
+
     /** A callback that is invoked when the desk container is created. */
     fun interface OnCreateCallback {
         /** Calls back when the [deskId] has been created. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserver.kt
index 3e49b8a..6d88c33 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserver.kt
@@ -25,7 +25,10 @@
  * Observer of desk-related transitions, such as adding, removing or activating a whole desk. It
  * tracks pending transitions and updates repository state once they finish.
  */
-class DesksTransitionObserver(private val desktopUserRepositories: DesktopUserRepositories) {
+class DesksTransitionObserver(
+    private val desktopUserRepositories: DesktopUserRepositories,
+    private val desksOrganizer: DesksOrganizer,
+) {
     private val deskTransitions = mutableMapOf<IBinder, DeskTransition>()
 
     /** Adds a pending desk transition to be tracked. */
@@ -53,6 +56,38 @@
                 desktopRepository.removeDesk(deskTransition.deskId)
                 deskTransition.onDeskRemovedListener?.onDeskRemoved(displayId, deskId)
             }
+            is DeskTransition.ActivateDesk -> {
+                val activeDeskChange =
+                    info.changes.find { change ->
+                        desksOrganizer.isDeskActiveAtEnd(change, deskTransition.deskId)
+                    }
+                activeDeskChange?.let {
+                    desktopRepository.setActiveDesk(
+                        displayId = deskTransition.displayId,
+                        deskId = deskTransition.deskId,
+                    )
+                }
+            }
+            is DeskTransition.ActiveDeskWithTask -> {
+                val withTask =
+                    info.changes.find { change ->
+                        change.taskInfo?.taskId == deskTransition.enterTaskId &&
+                            change.taskInfo?.isVisibleRequested == true &&
+                            desksOrganizer.getDeskAtEnd(change) == deskTransition.deskId
+                    }
+                withTask?.let {
+                    desktopRepository.setActiveDesk(
+                        displayId = deskTransition.displayId,
+                        deskId = deskTransition.deskId,
+                    )
+                    desktopRepository.addTaskToDesk(
+                        displayId = deskTransition.displayId,
+                        deskId = deskTransition.deskId,
+                        taskId = deskTransition.enterTaskId,
+                        isVisible = true,
+                    )
+                }
+            }
         }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt
index 79c48c5..5cda76e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt
@@ -22,6 +22,7 @@
 import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
 import android.util.SparseArray
 import android.view.SurfaceControl
+import android.view.WindowManager.TRANSIT_TO_FRONT
 import android.window.TransitionInfo
 import android.window.WindowContainerTransaction
 import androidx.core.util.forEach
@@ -88,12 +89,18 @@
         task: RunningTaskInfo,
     ) {
         val root = roots[deskId] ?: error("Root not found for desk: $deskId")
+        wct.setWindowingMode(task.token, WINDOWING_MODE_UNDEFINED)
         wct.reparent(task.token, root.taskInfo.token, /* onTop= */ true)
     }
 
     override fun getDeskAtEnd(change: TransitionInfo.Change): Int? =
         change.taskInfo?.parentTaskId?.takeIf { it in roots }
 
+    override fun isDeskActiveAtEnd(change: TransitionInfo.Change, deskId: Int): Boolean =
+        change.taskInfo?.taskId == deskId &&
+            change.taskInfo?.isVisibleRequested == true &&
+            change.mode == TRANSIT_TO_FRONT
+
     override fun onTaskAppeared(taskInfo: RunningTaskInfo, leash: SurfaceControl) {
         if (taskInfo.parentTaskId in roots) {
             val deskId = taskInfo.parentTaskId
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt
index 9e41270..1566544f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt
@@ -24,6 +24,7 @@
 import androidx.datastore.core.DataStore
 import androidx.datastore.core.DataStoreFactory
 import androidx.datastore.core.Serializer
+import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
 import androidx.datastore.dataStoreFile
 import com.android.framework.protobuf.InvalidProtocolBufferException
 import com.android.wm.shell.shared.annotations.ShellBackgroundThread
@@ -49,6 +50,10 @@
             serializer = DesktopPersistentRepositoriesSerializer,
             produceFile = { context.dataStoreFile(DESKTOP_REPOSITORIES_DATASTORE_FILE) },
             scope = bgCoroutineScope,
+            corruptionHandler =
+                ReplaceFileCorruptionHandler(
+                    produceNewData = { DesktopPersistentRepositories.getDefaultInstance() }
+                ),
         )
     )
 
@@ -127,7 +132,10 @@
                     .toBuilder()
                     .putDesktopRepoByUser(
                         userId,
-                        currentRepository.toBuilder().putDesktop(desktopId, desktop.build()).build(),
+                        currentRepository
+                            .toBuilder()
+                            .putDesktop(desktopId, desktop.build())
+                            .build(),
                     )
                     .build()
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md
index faa97ac..f50d253 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md
@@ -1,4 +1,5 @@
 # Making changes in the Shell
+[Back to home](README.md)
 
 ---
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md
index 7070dea..9b09904 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/dagger.md
@@ -1,4 +1,5 @@
 # Usage of Dagger in the Shell library
+[Back to home](README.md)
 
 ---
 
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 09e627c..dd5827a 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
@@ -1,4 +1,5 @@
 # Debugging in the Shell
+[Back to home](README.md)
 
 ---
 
@@ -50,6 +51,11 @@
 adb shell wm shell protolog disable-text TAG
 ```
 
+### R8 optimizations & ProtoLog
+
+If the APK that the Shell library is included into has R8 optimizations enabled, then you may need
+to update the proguard flags to keep the generated protolog classes (ie. AOSP SystemUI's [proguard.flags](base/packages/SystemUI/proguard_common.flags)).
+
 ## Winscope Tracing
 
 The Winscope tool is extremely useful in determining what is happening on-screen in both
@@ -57,25 +63,42 @@
 use the tool.  This trace will contain all the information about the windows/activities/surfaces on
 screen.
 
-## WindowManager/SurfaceFlinger hierarchy dump
+## WindowManager/SurfaceFlinger/InputDispatcher information
 
 A quick way to view the WindowManager hierarchy without a winscope trace is via the wm dumps:
 ```shell
 adb shell dumpsys activity containers
+# The output lists the containers in the hierarchy from top -> bottom in z-order
+```
+
+To get more information about windows on the screen:
+```shell
+# All windows in WM
+adb shell dumpsys window -a
+# The windows are listed from top -> bottom in z-order
+
+# Visible windows only
+adb shell dumpsys window -a visible
 ```
 
 Likewise, the SurfaceFlinger hierarchy can be dumped for inspection by running:
 ```shell
 adb shell dumpsys SurfaceFlinger
-# Search output for "Layer Hierarchy"
+# Search output for "Layer Hierarchy", the surfaces in the table are listed bottom -> top in z-order
+```
+
+And the visible input windows can be dumped via:
+```shell
+adb shell dumpsys input
+# Search output for "Windows:", they are ordered top -> bottom in z-order
 ```
 
 ## Tracing global SurfaceControl transaction updates
 
 While Winscope traces are very useful, it sometimes doesn't give you enough information about which
 part of the code is initiating the transaction updates. In such cases, it can be helpful to get
-stack traces when specific surface transaction calls are made, which is possible by enabling the
-following system properties for example:
+stack traces when specific surface transaction calls are made (regardless of process), which is
+possible by enabling the following system properties for example:
 ```shell
 # Enabling
 adb shell setprop persist.wm.debug.sc.tx.log_match_call setAlpha,setPosition  # matches the name of the SurfaceControlTransaction methods
@@ -94,9 +117,16 @@
 It is not necessary to set both `log_match_call` and `log_match_name`, but note logs can be quite
 noisy if unfiltered.
 
-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:
+### Tracing transaction merge & apply
+
+Tracing the method calls on SurfaceControl.Transaction tells you where a change is requested, but
+the changes are not actually committed until the transaction itself is applied.  And because
+transactions can be passed across processes, or prepared in advance for later application (ie.
+when restoring state after a Transition), the ordering of the change logs is not always clear
+by itself.
+
+In such cases, you can also enable the "merge" and "apply" calls to get additional information
+about how/when transactions are respectively merged/applied:
 ```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
@@ -104,6 +134,11 @@
 adb logcat -s "SurfaceControlRegistry"
 ```
 
+Using those logs, you can first look at where the desired change is called, note the transaction
+id, and then search the logs for where that transaction id is used.  If it is merged into another
+transaction, you can continue the search using the merged transaction until you find the final
+transaction which is applied.
+
 ## 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
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/extending.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/extending.md
index 061ae00e..f7707da 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/extending.md
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/extending.md
@@ -1,4 +1,5 @@
 # Extending the Shell for Products/OEMs
+[Back to home](README.md)
 
 ---
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/overview.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/overview.md
index b489fe8..bed0fba 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/overview.md
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/overview.md
@@ -1,4 +1,5 @@
 # What is the WindowManager Shell
+[Back to home](README.md)
 
 ---
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md
index 5e92010..47383b0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/sysui.md
@@ -1,4 +1,5 @@
 # Shell & SystemUI
+[Back to home](README.md)
 
 ---
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/testing.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/testing.md
index 98af930..b455313 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/testing.md
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/testing.md
@@ -1,4 +1,5 @@
 # Testing
+[Back to home](README.md)
 
 ---
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md
index 837a6dd3..bde7223 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md
@@ -1,4 +1,5 @@
 # Threading
+[Back to home](README.md)
 
 ---
 
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 e8996bc..a67557b 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
@@ -62,6 +62,7 @@
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.bubbles.bar.BubbleBarDragListener;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.ExternalInterfaceBinder;
 import com.android.wm.shell.common.RemoteCallable;
@@ -80,6 +81,8 @@
 import java.util.function.Consumer;
 import java.util.function.Function;
 
+import dagger.Lazy;
+
 /**
  * Handles the global drag and drop handling for the Shell.
  */
@@ -101,6 +104,7 @@
     private final GlobalDragListener mGlobalDragListener;
     private final Transitions mTransitions;
     private SplitScreenController mSplitScreen;
+    private Lazy<BubbleBarDragListener> mBubbleBarDragController;
     private ShellExecutor mMainExecutor;
     private ArrayList<DragAndDropListener> mListeners = new ArrayList<>();
 
@@ -143,6 +147,7 @@
             IconProvider iconProvider,
             GlobalDragListener globalDragListener,
             Transitions transitions,
+            Lazy<BubbleBarDragListener> bubbleBarDragController,
             ShellExecutor mainExecutor) {
         mContext = context;
         mShellController = shellController;
@@ -153,6 +158,7 @@
         mIconProvider = iconProvider;
         mGlobalDragListener = globalDragListener;
         mTransitions = transitions;
+        mBubbleBarDragController = bubbleBarDragController;
         mMainExecutor = mainExecutor;
         shellInit.addInitCallback(this::onInit, this);
     }
@@ -246,7 +252,8 @@
                 R.layout.global_drop_target, null);
         rootView.setOnDragListener(this);
         rootView.setVisibility(View.INVISIBLE);
-        DragLayoutProvider dragLayout = new DragLayout(context, mSplitScreen, mIconProvider);
+        DragLayoutProvider dragLayout = new DragLayout(context, mSplitScreen,
+                mBubbleBarDragController.get(), mIconProvider);
         dragLayout.addDraggingView(rootView);
         try {
             wm.addView(rootView, layoutParams);
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 5c72cb7..f0e0295 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
@@ -44,10 +44,8 @@
 import android.graphics.Insets;
 import android.graphics.Point;
 import android.graphics.Rect;
-import android.graphics.RectF;
 import android.graphics.Region;
 import android.graphics.drawable.Drawable;
-import android.util.Log;
 import android.view.DragEvent;
 import android.view.SurfaceControl;
 import android.view.View;
@@ -66,9 +64,11 @@
 import com.android.internal.protolog.ProtoLog;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.R;
+import com.android.wm.shell.bubbles.bar.BubbleBarDragListener;
 import com.android.wm.shell.common.split.SplitScreenUtils;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.shared.animation.Interpolators;
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 
 import java.io.PrintWriter;
@@ -106,9 +106,11 @@
     private boolean mIsLeftRightSplit;
 
     private SplitDragPolicy.Target mCurrentTarget = null;
+    private final BubbleBarDragListener mBubbleBarDragListener;
+    private final Map<BubbleBarLocation, Rect> mBubbleBarLocations = new HashMap<>();
+    private BubbleBarLocation mCurrentBubbleBarTarget = null;
     private DropZoneView mDropZoneView1;
     private DropZoneView mDropZoneView2;
-
     private int mDisplayMargin;
     private int mDividerSize;
     private int mLaunchIntentEdgeMargin;
@@ -128,11 +130,14 @@
     // Used with enableFlexibleSplit() flag
 
     @SuppressLint("WrongConstant")
-    public DragLayout(Context context, SplitScreenController splitScreenController,
+    public DragLayout(Context context,
+            SplitScreenController splitScreenController,
+            BubbleBarDragListener bubbleBarDragListener,
             IconProvider iconProvider) {
         super(context);
         mSplitScreenController = splitScreenController;
         mIconProvider = iconProvider;
+        mBubbleBarDragListener = bubbleBarDragListener;
         mPolicy = new SplitDragPolicy(context, splitScreenController, this);
         mStatusBarManager = context.getSystemService(StatusBarManager.class);
         mLastConfiguration.setTo(context.getResources().getConfiguration());
@@ -188,6 +193,12 @@
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         super.onLayout(changed, l, t, r, b);
         updateTouchableRegion();
+        updateBubbleBarRegions(l, t, r, b);
+    }
+
+    private void updateBubbleBarRegions(int l, int t, int r, int b) {
+        mBubbleBarLocations.clear();
+        mBubbleBarLocations.putAll(mBubbleBarDragListener.getBubbleBarDropZones(l, t, r, b));
     }
 
     /**
@@ -514,17 +525,18 @@
         if (mHasDropped) {
             return;
         }
+        // if event is over the bubble don't let split handle it
+        if (interceptBubbleBarEvent(x, y)) {
+            mLastPosition.set(x, y);
+            return;
+        }
         // Find containing region, if the same as mCurrentRegion, then skip, otherwise, animate the
         // visibility of the current region
         SplitDragPolicy.Target target = mPolicy.getTargetAtLocation(x, y);
         if (mCurrentTarget != target) {
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Current target: %s", target);
             if (target == null) {
-                // Animating to no target
-                animateSplitContainers(false, null /* animCompleteCallback */);
-                if (enableFlexibleSplit()) {
-                    animateHighlight(target);
-                }
+                animateToNoTarget();
             } else if (mCurrentTarget == null) {
                 if (mPolicy.getNumTargets() == 1) {
                     animateFullscreenContainer(true);
@@ -565,6 +577,45 @@
         mLastPosition.set(x, y);
     }
 
+    private boolean interceptBubbleBarEvent(int x, int y) {
+        BubbleBarLocation bubbleBarLocation = getBubbleBarLocation(x, y);
+        boolean isOverTheBubbleBar = bubbleBarLocation != null;
+        if (mCurrentBubbleBarTarget != bubbleBarLocation) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Current bubble bar location: %s",
+                    isOverTheBubbleBar);
+            mCurrentBubbleBarTarget = bubbleBarLocation;
+            if (isOverTheBubbleBar) {
+                mBubbleBarDragListener.onDragItemOverBubbleBarDragZone(bubbleBarLocation);
+                if (mCurrentTarget != null) {
+                    animateToNoTarget();
+                    mCurrentTarget = null;
+                }
+            } else {
+                mBubbleBarDragListener.onItemDraggedOutsideBubbleBarDropZone();
+            }
+            //TODO(b/388894910): handle accessibility
+        }
+        return isOverTheBubbleBar;
+    }
+
+    @Nullable
+    private BubbleBarLocation getBubbleBarLocation(int x, int y) {
+        for (BubbleBarLocation location : mBubbleBarLocations.keySet()) {
+            if (mBubbleBarLocations.get(location).contains(x, y)) {
+                return location;
+            }
+        }
+        return null;
+    }
+
+    private void animateToNoTarget() {
+        // Animating to no target
+        animateSplitContainers(false, null /* animCompleteCallback */);
+        if (enableFlexibleSplit()) {
+            animateHighlight(null);
+        }
+    }
+
     /**
      * Hides the drag layout and animates out the visible drop targets.
      */
@@ -596,11 +647,13 @@
      */
     public boolean drop(DragEvent event, @NonNull SurfaceControl dragSurface,
             @Nullable WindowContainerToken hideTaskToken, Runnable dropCompleteCallback) {
-        final boolean handledDrop = mCurrentTarget != null;
+        final boolean handledDrop = mCurrentTarget != null || mCurrentBubbleBarTarget != null;
         mHasDropped = true;
 
         // Process the drop
         mPolicy.onDropped(mCurrentTarget, hideTaskToken);
+        //TODO(b/388894910) add info about the application
+        mBubbleBarDragListener.onItemDroppedOverBubbleBarDragZone(mCurrentBubbleBarTarget);
 
         // Start animating the drop UI out with the drag surface
         hide(event, dropCompleteCallback);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
index b6d19b6..8059b94 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
@@ -21,13 +21,13 @@
 import android.os.IBinder;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
+import android.window.DesktopModeFlags;
 import android.window.TransitionInfo;
 import android.window.WindowContainerToken;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
-import com.android.window.flags.Flags;
 import com.android.wm.shell.desktopmode.DesktopImmersiveController;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.FocusTransitionObserver;
@@ -85,7 +85,7 @@
             @NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction startT,
             @NonNull SurfaceControl.Transaction finishT) {
-        if (Flags.enableFullyImmersiveInDesktop()) {
+        if (DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()) {
             // TODO(b/367268953): Remove when DesktopTaskListener is introduced and the repository
             //  is updated from there **before** the |mWindowDecorViewModel| methods are invoked.
             //  Otherwise window decoration relayout won't run with the immersive state up to date.
@@ -191,7 +191,7 @@
 
     @Override
     public void onTransitionStarting(@NonNull IBinder transition) {
-        if (Flags.enableFullyImmersiveInDesktop()) {
+        if (DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()) {
             // TODO(b/367268953): Remove when DesktopTaskListener is introduced.
             mDesktopImmersiveController.ifPresent(h -> h.onTransitionStarting(transition));
         }
@@ -199,7 +199,7 @@
 
     @Override
     public void onTransitionMerged(@NonNull IBinder merged, @NonNull IBinder playing) {
-        if (Flags.enableFullyImmersiveInDesktop()) {
+        if (DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()) {
             // TODO(b/367268953): Remove when DesktopTaskListener is introduced.
             mDesktopImmersiveController.ifPresent(h -> h.onTransitionMerged(merged, playing));
         }
@@ -224,7 +224,7 @@
 
     @Override
     public void onTransitionFinished(@NonNull IBinder transition, boolean aborted) {
-        if (Flags.enableFullyImmersiveInDesktop()) {
+        if (DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()) {
             // TODO(b/367268953): Remove when DesktopTaskListener is introduced.
             mDesktopImmersiveController.ifPresent(h -> h.onTransitionFinished(transition, aborted));
         }
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 e74870d..5894ea8 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
@@ -32,6 +32,7 @@
 import android.view.ViewRootImpl;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
+import android.view.accessibility.AccessibilityManager;
 import android.window.SurfaceSyncGroup;
 
 import androidx.annotation.Nullable;
@@ -63,6 +64,8 @@
     private TvPipMenuView mPipMenuView;
     private TvPipBackgroundView mPipBackgroundView;
 
+    private final AccessibilityManager mA11yManager;
+
     private boolean mIsReloading;
     private static final int PIP_MENU_FORCE_CLOSE_DELAY_MS = 10_000;
     private final Runnable mClosePipMenuRunnable = this::closeMenu;
@@ -107,6 +110,8 @@
         mSystemWindows = systemWindows;
         mMainHandler = mainHandler;
 
+        mA11yManager = context.getSystemService(AccessibilityManager.class);
+
         // We need to "close" the menu the platform call for all the system dialogs to close (for
         // example, on the Home button press).
         final BroadcastReceiver closeSystemDialogsBroadcastReceiver = new BroadcastReceiver() {
@@ -499,7 +504,9 @@
             switchToMenuMode(menuMode);
         } else {
             if (isMenuOpen(menuMode)) {
-                mMainHandler.postDelayed(mClosePipMenuRunnable, PIP_MENU_FORCE_CLOSE_DELAY_MS);
+                if (!mA11yManager.isEnabled()) {
+                    mMainHandler.postDelayed(mClosePipMenuRunnable, PIP_MENU_FORCE_CLOSE_DELAY_MS);
+                }
                 mMenuModeOnFocus = menuMode;
             }
             // Send a request to gain window focus if the menu is open, or lose window focus
@@ -594,8 +601,10 @@
     public void onUserInteracting() {
         ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                 "%s: onUserInteracting - mCurrentMenuMode=%s", TAG, getMenuModeString());
-        mMainHandler.removeCallbacks(mClosePipMenuRunnable);
-        mMainHandler.postDelayed(mClosePipMenuRunnable, PIP_MENU_FORCE_CLOSE_DELAY_MS);
+        if (mMainHandler.hasCallbacks(mClosePipMenuRunnable)) {
+            mMainHandler.removeCallbacks(mClosePipMenuRunnable);
+            mMainHandler.postDelayed(mClosePipMenuRunnable, PIP_MENU_FORCE_CLOSE_DELAY_MS);
+        }
 
     }
     @Override
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 21b0820..e17587f 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
@@ -16,14 +16,10 @@
 
 package com.android.wm.shell.pip2.phone;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-
 import android.content.Context;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.view.SurfaceControl;
-import android.window.DisplayAreaInfo;
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
@@ -32,20 +28,14 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.ProtoLog;
-import com.android.window.flags.Flags;
-import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.pip.PipBoundsState;
-import com.android.wm.shell.desktopmode.DesktopUserRepositories;
-import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider;
+import com.android.wm.shell.common.pip.PipDesktopState;
 import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
 import com.android.wm.shell.pip2.animation.PipAlphaAnimator;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
-import java.util.Objects;
-import java.util.Optional;
-
 /**
  * Scheduler for Shell initiated PiP transitions and animations.
  */
@@ -56,10 +46,7 @@
     private final PipBoundsState mPipBoundsState;
     private final ShellExecutor mMainExecutor;
     private final PipTransitionState mPipTransitionState;
-    private final Optional<DesktopUserRepositories> mDesktopUserRepositoriesOptional;
-    private final Optional<DesktopWallpaperActivityTokenProvider>
-            mDesktopWallpaperActivityTokenProviderOptional;
-    private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
+    private final PipDesktopState mPipDesktopState;
     private PipTransitionController mPipTransitionController;
     private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
             mSurfaceControlTransactionFactory;
@@ -72,18 +59,12 @@
             PipBoundsState pipBoundsState,
             ShellExecutor mainExecutor,
             PipTransitionState pipTransitionState,
-            Optional<DesktopUserRepositories> desktopUserRepositoriesOptional,
-            Optional<DesktopWallpaperActivityTokenProvider>
-                    desktopWallpaperActivityTokenProviderOptional,
-            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
+            PipDesktopState pipDesktopState) {
         mContext = context;
         mPipBoundsState = pipBoundsState;
         mMainExecutor = mainExecutor;
         mPipTransitionState = pipTransitionState;
-        mDesktopUserRepositoriesOptional = desktopUserRepositoriesOptional;
-        mDesktopWallpaperActivityTokenProviderOptional =
-                desktopWallpaperActivityTokenProviderOptional;
-        mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
+        mPipDesktopState = pipDesktopState;
 
         mSurfaceControlTransactionFactory =
                 new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory();
@@ -105,7 +86,7 @@
         wct.setBounds(pipTaskToken, null);
         // if we are hitting a multi-activity case
         // windowing mode change will reparent to original host task
-        wct.setWindowingMode(pipTaskToken, getOutPipWindowingMode());
+        wct.setWindowingMode(pipTaskToken, mPipDesktopState.getOutPipWindowingMode());
         return wct;
     }
 
@@ -235,55 +216,6 @@
         maybeUpdateMovementBounds();
     }
 
-    /** Returns whether the display is in freeform windowing mode. */
-    private boolean isDisplayInFreeform() {
-        final DisplayAreaInfo tdaInfo = mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(
-                Objects.requireNonNull(mPipTransitionState.getPipTaskInfo()).displayId);
-        if (tdaInfo != null) {
-            return tdaInfo.configuration.windowConfiguration.getWindowingMode()
-                    == WINDOWING_MODE_FREEFORM;
-        }
-        return false;
-    }
-
-    /** Returns whether PiP is exiting while we're in desktop mode. */
-    private boolean isPipExitingToDesktopMode() {
-        // Early return if PiP in Desktop Windowing is not supported.
-        if (!Flags.enableDesktopWindowingPip() || mDesktopUserRepositoriesOptional.isEmpty()
-                || mDesktopWallpaperActivityTokenProviderOptional.isEmpty()) {
-            return false;
-        }
-        final int displayId = Objects.requireNonNull(
-                mPipTransitionState.getPipTaskInfo()).displayId;
-        return mDesktopUserRepositoriesOptional.get().getCurrent().getVisibleTaskCount(displayId)
-                > 0
-                || mDesktopWallpaperActivityTokenProviderOptional.get().isWallpaperActivityVisible(
-                displayId)
-                || isDisplayInFreeform();
-    }
-
-    /**
-     * The windowing mode to restore to when resizing out of PIP direction. Defaults to undefined
-     * and can be overridden to restore to an alternate windowing mode.
-     */
-    private int getOutPipWindowingMode() {
-        // If we are exiting PiP while the device is in Desktop mode (the task should expand to
-        // freeform windowing mode):
-        // 1) If the display windowing mode is freeform, set windowing mode to undefined so it will
-        //    resolve the windowing mode to the display's windowing mode.
-        // 2) If the display windowing mode is not freeform, set windowing mode to freeform.
-        if (isPipExitingToDesktopMode()) {
-            if (isDisplayInFreeform()) {
-                return WINDOWING_MODE_UNDEFINED;
-            } else {
-                return WINDOWING_MODE_FREEFORM;
-            }
-        }
-
-        // By default, or if the task is going to fullscreen, reset the windowing mode to undefined.
-        return WINDOWING_MODE_UNDEFINED;
-    }
-
     @VisibleForTesting
     void setSurfaceControlTransactionFactory(
             @NonNull PipSurfaceTransactionHelper.SurfaceControlTransactionFactory factory) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java
index d735375..dbcbf36 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java
@@ -132,8 +132,9 @@
                 "onTaskInfoChanged: %s, state=%s oldParams=%s newParams=%s",
                 taskInfo.topActivity, mPipTransitionState, mPictureInPictureParams, params);
         setPictureInPictureParams(params);
+        // Note: params is nullable while mPictureInPictureParams is never null
         float newAspectRatio = mPictureInPictureParams.getAspectRatioFloat();
-        if (params.hasSetAspectRatio()
+        if (mPictureInPictureParams.hasSetAspectRatio()
                 && mPipBoundsAlgorithm.isValidPictureInPictureAspectRatio(newAspectRatio)
                 && PipUtils.aspectRatioChanged(newAspectRatio, mPipBoundsState.getAspectRatio())) {
             mPipTransitionState.setOnIdlePipTransitionStateRunnable(() -> {
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 78aa686..bb9b479 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
@@ -56,19 +56,16 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.util.Preconditions;
-import com.android.window.flags.Flags;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.ComponentUtils;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
 import com.android.wm.shell.common.pip.PipBoundsState;
+import com.android.wm.shell.common.pip.PipDesktopState;
 import com.android.wm.shell.common.pip.PipDisplayLayoutState;
 import com.android.wm.shell.common.pip.PipMenuController;
 import com.android.wm.shell.common.pip.PipUtils;
-import com.android.wm.shell.desktopmode.DesktopRepository;
-import com.android.wm.shell.desktopmode.DesktopUserRepositories;
-import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider;
 import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
 import com.android.wm.shell.pip2.animation.PipAlphaAnimator;
@@ -79,8 +76,6 @@
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.Transitions;
 
-import java.util.Optional;
-
 /**
  * Implementation of transitions for PiP on phone.
  */
@@ -117,9 +112,7 @@
     private final PipDisplayLayoutState mPipDisplayLayoutState;
     private final DisplayController mDisplayController;
     private final PipSurfaceTransactionHelper mPipSurfaceTransactionHelper;
-    private final Optional<DesktopUserRepositories> mDesktopUserRepositoriesOptional;
-    private final Optional<DesktopWallpaperActivityTokenProvider>
-            mDesktopWallpaperActivityTokenProviderOptional;
+    private final PipDesktopState mPipDesktopState;
 
     //
     // Transition caches
@@ -159,9 +152,7 @@
             PipDisplayLayoutState pipDisplayLayoutState,
             PipUiStateChangeController pipUiStateChangeController,
             DisplayController displayController,
-            Optional<DesktopUserRepositories> desktopUserRepositoriesOptional,
-            Optional<DesktopWallpaperActivityTokenProvider>
-                    desktopWallpaperActivityTokenProviderOptional) {
+            PipDesktopState pipDesktopState) {
         super(shellInit, shellTaskOrganizer, transitions, pipBoundsState, pipMenuController,
                 pipBoundsAlgorithm);
 
@@ -174,9 +165,7 @@
         mPipDisplayLayoutState = pipDisplayLayoutState;
         mDisplayController = displayController;
         mPipSurfaceTransactionHelper = new PipSurfaceTransactionHelper(mContext);
-        mDesktopUserRepositoriesOptional = desktopUserRepositoriesOptional;
-        mDesktopWallpaperActivityTokenProviderOptional =
-                desktopWallpaperActivityTokenProviderOptional;
+        mPipDesktopState = pipDesktopState;
     }
 
     @Override
@@ -802,7 +791,7 @@
                     && getFixedRotationDelta(info, pipTaskChange) == ROTATION_90) {
                 adjustedSourceRectHint.offset(cutoutInsets.left, cutoutInsets.top);
             }
-            if (Flags.enableDesktopWindowingPip()) {
+            if (mPipDesktopState.isDesktopWindowingPipEnabled()) {
                 adjustedSourceRectHint.offset(-pipActivityChange.getStartAbsBounds().left,
                         -pipActivityChange.getStartAbsBounds().top);
             }
@@ -862,7 +851,7 @@
 
         // If PiP is enabled on Connected Displays, update PipDisplayLayoutState to have the correct
         // display info that PiP is entering in.
-        if (Flags.enableConnectedDisplaysPip()) {
+        if (mPipDesktopState.isConnectedDisplaysPipEnabled()) {
             final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(
                     pipTask.displayId);
             if (displayLayout != null) {
@@ -910,12 +899,7 @@
         // Since opening a new task while in Desktop Mode always first open in Fullscreen
         // until DesktopMode Shell code resolves it to Freeform, PipTransition will get a
         // possibility to handle it also. In this case return false to not have it enter PiP.
-        final boolean isInDesktopSession = !mDesktopUserRepositoriesOptional.isEmpty()
-                && (mDesktopUserRepositoriesOptional.get().getCurrent().getVisibleTaskCount(
-                        pipTask.displayId) > 0
-                    || mDesktopUserRepositoriesOptional.get().getCurrent()
-                        .isMinimizedPipPresentInDisplay(pipTask.displayId));
-        if (isInDesktopSession) {
+        if (mPipDesktopState.isPipEnteringInDesktopMode(pipTask)) {
             return false;
         }
 
@@ -1089,26 +1073,13 @@
                         "Unexpected bundle for " + mPipTransitionState);
                 break;
             case PipTransitionState.EXITED_PIP:
-                final TaskInfo pipTask = mPipTransitionState.getPipTaskInfo();
-                final boolean desktopPipEnabled = Flags.enableDesktopWindowingPip()
-                        && mDesktopUserRepositoriesOptional.isPresent()
-                        && mDesktopWallpaperActivityTokenProviderOptional.isPresent();
-                if (desktopPipEnabled && pipTask != null) {
-                    final DesktopRepository desktopRepository =
-                            mDesktopUserRepositoriesOptional.get().getCurrent();
-                    final boolean wallpaperIsVisible =
-                            mDesktopWallpaperActivityTokenProviderOptional.get()
-                                    .isWallpaperActivityVisible(pipTask.displayId);
-                    if (desktopRepository.getVisibleTaskCount(pipTask.displayId) == 0
-                            && wallpaperIsVisible) {
-                        mTransitions.startTransition(
-                                TRANSIT_TO_BACK,
-                                new WindowContainerTransaction().reorder(
-                                        mDesktopWallpaperActivityTokenProviderOptional.get()
-                                                .getToken(pipTask.displayId), /* onTop= */ false),
-                                null
-                        );
-                    }
+                if (mPipDesktopState.shouldExitPipExitDesktopMode()) {
+                    mTransitions.startTransition(
+                            TRANSIT_TO_BACK,
+                            mPipDesktopState.getWallpaperActivityTokenWct(
+                                    mPipTransitionState.getPipTaskInfo().getDisplayId()),
+                            null /* firstHandler */
+                    );
                 }
                 mPipTransitionState.setPinnedTaskLeash(null);
                 mPipTransitionState.setPipTaskInfo(null);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayProvider.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayProvider.java
new file mode 100644
index 0000000..d2e57e5
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayProvider.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.splitscreen;
+
+import android.window.WindowContainerToken;
+
+public interface SplitMultiDisplayProvider {
+    /**
+     * Returns the WindowContainerToken for the root of the given display ID.
+     *
+     * @param displayId The ID of the display.
+     * @return The {@link WindowContainerToken} associated with the display's root task.
+     */
+    WindowContainerToken getDisplayRootForDisplayId(int displayId);
+}
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 ae01592..e9f8a4a 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
@@ -321,6 +321,10 @@
         return mStageCoordinator;
     }
 
+    public SplitMultiDisplayProvider getMultiDisplayProvider() {
+        return mStageCoordinator;
+    }
+
     @Nullable
     public ActivityManager.RunningTaskInfo getTaskInfo(@SplitPosition int splitPosition) {
         if (!isSplitScreenVisible() || splitPosition == SPLIT_POSITION_UNDEFINED) {
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 6783df8..13940b1 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
@@ -189,7 +189,8 @@
  */
 public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
         DisplayController.OnDisplaysChangedListener, Transitions.TransitionHandler,
-        ShellTaskOrganizer.TaskListener, StageTaskListener.StageListenerCallbacks {
+        ShellTaskOrganizer.TaskListener, StageTaskListener.StageListenerCallbacks,
+        SplitMultiDisplayProvider {
 
     private static final String TAG = StageCoordinator.class.getSimpleName();
 
@@ -287,6 +288,16 @@
         mSplitTransitions.registerSplitAnimListener(listener, executor);
     }
 
+    @Override
+    public WindowContainerToken getDisplayRootForDisplayId(int displayId) {
+        if (displayId == DEFAULT_DISPLAY) {
+            return mRootTaskInfo != null ? mRootTaskInfo.token : null;
+        }
+
+        // TODO(b/393217881): support different root task on external displays.
+        return null; // Return null for unknown display IDs
+    }
+
     class SplitRequest {
         @SplitPosition
         int mActivatePosition;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
index 9af2308..a6f8726 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
@@ -52,6 +52,7 @@
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.shared.TransitionUtil;
+import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
 import com.android.wm.shell.transition.Transitions;
 
 import java.util.ArrayList;
@@ -571,7 +572,7 @@
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback) {
-        PendingTransition pending = findPending(transition);
+        final PendingTransition pending = findPending(transition);
         if (pending != null) {
             mPending.remove(pending);
         }
@@ -586,10 +587,11 @@
         WindowContainerTransaction wct = null;
         for (int i = 0; i < info.getChanges().size(); ++i) {
             final TransitionInfo.Change chg = info.getChanges().get(i);
-            if (chg.getTaskInfo() == null) continue;
+            final ActivityManager.RunningTaskInfo taskInfo = chg.getTaskInfo();
+            if (taskInfo == null) continue;
             if (TransitionUtil.isClosingType(chg.getMode())) {
                 final boolean isHide = chg.getMode() == TRANSIT_TO_BACK;
-                TaskViewTaskController tv = findTaskView(chg.getTaskInfo());
+                TaskViewTaskController tv = findTaskView(taskInfo);
                 if (tv == null && !isHide) {
                     // TaskView can be null when closing
                     changesHandled++;
@@ -599,7 +601,7 @@
                     if (pending != null) {
                         Slog.w(TAG, "Found a non-TaskView task in a TaskView Transition. This "
                                 + "shouldn't happen, so there may be a visual artifact: "
-                                + chg.getTaskInfo().taskId);
+                                + taskInfo.taskId);
                     }
                     continue;
                 }
@@ -615,40 +617,51 @@
                 }
                 changesHandled++;
             } else if (TransitionUtil.isOpeningType(chg.getMode())) {
-                final boolean taskIsNew = chg.getMode() == TRANSIT_OPEN;
-                final TaskViewTaskController tv;
-                if (taskIsNew) {
-                    if (pending == null
-                            || !chg.getTaskInfo().containsLaunchCookie(pending.mLaunchCookie)) {
+                boolean isNewInTaskView = false;
+                TaskViewTaskController tv;
+                if (chg.getMode() == TRANSIT_OPEN) {
+                    isNewInTaskView = true;
+                    if (pending == null || !taskInfo.containsLaunchCookie(pending.mLaunchCookie)) {
                         Slog.e(TAG, "Found a launching TaskView in the wrong transition. All "
                                 + "TaskView launches should be initiated by shell and in their "
-                                + "own transition: " + chg.getTaskInfo().taskId);
+                                + "own transition: " + taskInfo.taskId);
                         continue;
                     }
                     stillNeedsMatchingLaunch = false;
                     tv = pending.mTaskView;
                 } else {
-                    tv = findTaskView(chg.getTaskInfo());
-                    if (tv == null) {
-                        if (pending != null) {
-                            Slog.w(TAG, "Found a non-TaskView task in a TaskView Transition. This "
-                                    + "shouldn't happen, so there may be a visual artifact: "
-                                    + chg.getTaskInfo().taskId);
+                    tv = findTaskView(taskInfo);
+                    if (tv == null && pending != null) {
+                        if (BubbleAnythingFlagHelper.enableCreateAnyBubble()
+                                && chg.getMode() == TRANSIT_TO_FRONT
+                                && pending.mTaskView.getPendingInfo() != null
+                                && pending.mTaskView.getPendingInfo().taskId == taskInfo.taskId) {
+                            // In this case an existing task, not currently in TaskView, is
+                            // brought to the front to be moved into TaskView. This is still
+                            // "new" from TaskView's perspective. (e.g. task being moved into a
+                            // bubble)
+                            isNewInTaskView = true;
+                            stillNeedsMatchingLaunch = false;
+                            tv = pending.mTaskView;
+                        } else {
+                            Slog.w(TAG, "Found a non-TaskView task in a TaskView Transition. "
+                                    + "This shouldn't happen, so there may be a visual "
+                                    + "artifact: " + taskInfo.taskId);
                         }
-                        continue;
                     }
+                    if (tv == null) continue;
                 }
                 if (wct == null) wct = new WindowContainerTransaction();
-                prepareOpenAnimation(tv, taskIsNew, startTransaction, finishTransaction,
-                        chg.getTaskInfo(), chg.getLeash(), wct);
+                prepareOpenAnimation(tv, isNewInTaskView, startTransaction, finishTransaction,
+                        taskInfo, chg.getLeash(), wct);
                 changesHandled++;
             } else if (chg.getMode() == TRANSIT_CHANGE) {
-                TaskViewTaskController tv = findTaskView(chg.getTaskInfo());
+                TaskViewTaskController tv = findTaskView(taskInfo);
                 if (tv == null) {
                     if (pending != null) {
                         Slog.w(TAG, "Found a non-TaskView task in a TaskView Transition. This "
                                 + "shouldn't happen, so there may be a visual artifact: "
-                                + chg.getTaskInfo().taskId);
+                                + taskInfo.taskId);
                     }
                     continue;
                 }
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 72cbc47..c90f6cf 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
@@ -193,6 +193,9 @@
     /** Transition to end the recents transition */
     public static final int TRANSIT_END_RECENTS_TRANSITION = TRANSIT_FIRST_CUSTOM + 22;
 
+    /** Transition type for app compat reachability. */
+    public static final int TRANSIT_MOVE_LETTERBOX_REACHABILITY = TRANSIT_FIRST_CUSTOM + 23;
+
     /** Transition type for desktop mode transitions. */
     public static final int TRANSIT_DESKTOP_MODE_TYPES =
             WindowManager.TRANSIT_FIRST_CUSTOM + 100;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenu.kt
index 575aac38..02a5433 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHeaderManageWindowsMenu.kt
@@ -25,11 +25,11 @@
 import android.view.WindowInsets.Type.systemBars
 import android.view.WindowManager
 import android.view.WindowlessWindowManager
+import android.window.DesktopModeFlags
 import android.window.TaskConstants
 import android.window.TaskSnapshot
 import androidx.compose.ui.graphics.toArgb
 import com.android.internal.annotations.VisibleForTesting
-import com.android.window.flags.Flags
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.desktopmode.DesktopUserRepositories
@@ -76,7 +76,7 @@
         val flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
                 WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
         val desktopRepository = desktopUserRepositories.getProfile(callerTaskInfo.userId)
-        menuViewContainer = if (Flags.enableFullyImmersiveInDesktop()
+        menuViewContainer = if (DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue
             && desktopRepository.isTaskInFullImmersiveState(callerTaskInfo.taskId)) {
             // Use system view container so that forcibly shown system bars take effect in
             // immersive.
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 6a2a7b6..a3a0bae 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
@@ -131,6 +131,7 @@
 import com.android.wm.shell.shared.FocusTransitionListener;
 import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
+import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
 import com.android.wm.shell.shared.desktopmode.DesktopModeCompatPolicy;
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource;
@@ -754,7 +755,7 @@
         // App sometimes draws before the insets from WindowDecoration#relayout have
         // been added, so they must be added here
         decoration.addCaptionInset(wct);
-        mDesktopTasksController.moveTaskToDesktop(taskId, wct, source,
+        mDesktopTasksController.moveTaskToDefaultDeskAndActivate(taskId, wct, source,
                 /* remoteTransition= */ null, /* moveToDesktopCallback */ null);
         decoration.closeHandleMenu();
 
@@ -903,8 +904,9 @@
          * Whether to pilfer the next motion event to send cancellations to the windows below.
          * Useful when the caption window is spy and the gesture should be handled by the system
          * instead of by the app for their custom header content.
-         * Should not have any effect when {@link Flags#enableAccessibleCustomHeaders()}, because
-         * a spy window is not used then.
+         * Should not have any effect when
+         * {@link DesktopModeFlags#ENABLE_ACCESSIBLE_CUSTOM_HEADERS}, because a spy window is not
+         * used then.
          */
         private boolean mIsCustomHeaderGesture;
         private boolean mIsResizeGesture;
@@ -973,7 +975,7 @@
                 //  should shared with the maximize menu's maximize/restore actions.
                 final DesktopRepository desktopRepository = mDesktopUserRepositories.getProfile(
                         decoration.mTaskInfo.userId);
-                if (Flags.enableFullyImmersiveInDesktop()
+                if (DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()
                         && desktopRepository.isTaskInFullImmersiveState(
                                 decoration.mTaskInfo.taskId)) {
                     // Task is in immersive and should exit.
@@ -1046,7 +1048,7 @@
                 return false;
             }
             if (mInputManager != null
-                    && !Flags.enableAccessibleCustomHeaders()) {
+                    && !DesktopModeFlags.ENABLE_ACCESSIBLE_CUSTOM_HEADERS.isTrue()) {
                 ViewRootImpl viewRootImpl = v.getViewRootImpl();
                 if (viewRootImpl != null) {
                     // Pilfer so that windows below receive cancellations for this gesture.
@@ -1439,13 +1441,17 @@
                 mDragToDesktopAnimationStartBounds.set(
                         relevantDecor.mTaskInfo.configuration.windowConfiguration.getBounds());
                 boolean dragFromStatusBarAllowed = false;
+                final int windowingMode = relevantDecor.mTaskInfo.getWindowingMode();
                 if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
                     // In proto2 any full screen or multi-window task can be dragged to
                     // freeform.
-                    final int windowingMode = relevantDecor.mTaskInfo.getWindowingMode();
                     dragFromStatusBarAllowed = windowingMode == WINDOWING_MODE_FULLSCREEN
                             || windowingMode == WINDOWING_MODE_MULTI_WINDOW;
                 }
+                if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
+                    // TODO(b/388851898): add support for split screen (multi-window wm mode)
+                    dragFromStatusBarAllowed = windowingMode == WINDOWING_MODE_FULLSCREEN;
+                }
                 final boolean shouldStartTransitionDrag =
                         relevantDecor.checkTouchEventInFocusedCaptionHandle(ev)
                                 || DesktopModeFlags.ENABLE_HANDLE_INPUT_FIX.isTrue();
@@ -1653,8 +1659,9 @@
         if (mDesktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(taskInfo)) {
             return false;
         }
-        final boolean isOnLargeScreen = taskInfo.getConfiguration().smallestScreenWidthDp
-                >= WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
+        final boolean isOnLargeScreen =
+                mDisplayController.getDisplay(taskInfo.displayId).getMinSizeDimensionDp()
+                        >= WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
         if (!DesktopModeStatus.canEnterDesktopMode(mContext)
                 && DesktopModeStatus.overridesShowAppHandle(mContext) && !isOnLargeScreen) {
             // Devices with multiple screens may enable the app handle but it should not show on
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 c1a6240..3fdb05e 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
@@ -483,7 +483,7 @@
             boolean hasGlobalFocus, @NonNull Region displayExclusionRegion) {
         Trace.beginSection("DesktopModeWindowDecoration#relayout");
 
-        if (Flags.enableDesktopWindowingAppToWeb()) {
+        if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_APP_TO_WEB.isTrue()) {
             setCapturedLink(taskInfo.capturedLink, taskInfo.capturedLinkTimestamp);
         }
 
@@ -906,7 +906,7 @@
         relayoutParams.mAsyncViewHost = isAppHandle;
 
         final boolean showCaption;
-        if (Flags.enableFullyImmersiveInDesktop()) {
+        if (DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()) {
             if (inFullImmersiveMode) {
                 showCaption = isStatusBarVisible && !isKeyguardVisibleAndOccluded;
             } else {
@@ -935,7 +935,7 @@
                 // The app is requesting to customize the caption bar, which means input on
                 // customizable/exclusion regions must go to the app instead of to the system.
                 // This may be accomplished with spy windows or custom touchable regions:
-                if (Flags.enableAccessibleCustomHeaders()) {
+                if (DesktopModeFlags.ENABLE_ACCESSIBLE_CUSTOM_HEADERS.isTrue()) {
                     // Set the touchable region of the caption to only the areas where input should
                     // be handled by the system (i.e. non custom-excluded areas). The region will
                     // be calculated based on occluding caption elements and exclusion areas
@@ -958,7 +958,8 @@
                 // including non-immersive apps that just don't handle caption insets properly.
                 relayoutParams.mInsetSourceFlags |= FLAG_FORCE_CONSUMING_OPAQUE_CAPTION_BAR;
             }
-            if (Flags.enableFullyImmersiveInDesktop() && inFullImmersiveMode) {
+            if (DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()
+                    && inFullImmersiveMode) {
                 final Insets systemBarInsets = displayInsetsState.calculateInsets(
                         taskInfo.getConfiguration().windowConfiguration.getBounds(),
                         WindowInsets.Type.systemBars() & ~WindowInsets.Type.captionBar(),
@@ -1050,7 +1051,7 @@
     }
 
     private int calculateMaximizeMenuWidth() {
-        final boolean showImmersive = Flags.enableFullyImmersiveInDesktop()
+        final boolean showImmersive = DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()
                 && TaskInfoKt.getRequestingImmersive(mTaskInfo);
         final boolean showMaximize = true;
         final boolean showSnaps = mTaskInfo.isResizeable;
@@ -1278,11 +1279,13 @@
                 calculateMaximizeMenuPosition(menuWidth), mSurfaceControlTransactionSupplier);
 
         mMaximizeMenu.show(
-                /* isTaskInImmersiveMode= */ Flags.enableFullyImmersiveInDesktop()
+                /* isTaskInImmersiveMode= */
+                DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()
                         && mDesktopUserRepositories.getProfile(mTaskInfo.userId)
                             .isTaskInFullImmersiveState(mTaskInfo.taskId),
                 /* menuWidth= */ menuWidth,
-                /* showImmersiveOption= */ Flags.enableFullyImmersiveInDesktop()
+                /* showImmersiveOption= */
+                DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()
                         && TaskInfoKt.getRequestingImmersive(mTaskInfo),
                 /* showSnapOptions= */ mTaskInfo.isResizeable,
                 mOnMaximizeOrRestoreClickListener,
@@ -1790,7 +1793,7 @@
     }
 
     private boolean canOpenMaximizeMenu(boolean animatingTaskResizeOrReposition) {
-        if (!Flags.enableFullyImmersiveInDesktop()) {
+        if (!DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()) {
             return !animatingTaskResizeOrReposition;
         }
         final boolean inImmersiveAndRequesting =
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
index 32a2f82..1d95649 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
@@ -252,6 +252,7 @@
                     view = handleMenuView.rootView,
                     forciblyShownTypes = if (forceShowSystemBars) { systemBars() } else { 0 },
                     ignoreCutouts = Flags.showAppHandleLargeScreens()
+                            || BubbleAnythingFlagHelper.enableBubbleToFullscreen()
                 )
             } else {
                 parentDecor.addWindow(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
index 1264c01..2948fda 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
@@ -41,6 +41,7 @@
 import com.android.window.flags.Flags
 import com.android.wm.shell.R
 import com.android.wm.shell.shared.animation.Interpolators
+import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper
 import com.android.wm.shell.windowdecor.WindowManagerWrapper
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
 
@@ -146,6 +147,7 @@
             taskInfo.taskId, handlePosition.x, handlePosition.y, handleWidth, handleHeight,
             WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
             ignoreCutouts = Flags.showAppHandleLargeScreens()
+                    || BubbleAnythingFlagHelper.enableBubbleToFullscreen()
         )
         val view = statusBarInputLayer?.view ?: error("Unable to find statusBarInputLayer View")
         val lp = statusBarInputLayer?.lp ?: error("Unable to find statusBarInputLayer " +
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
index db12f89..bc2be90 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
@@ -49,7 +49,6 @@
 import com.android.internal.R.color.materialColorSurfaceContainerHigh
 import com.android.internal.R.color.materialColorSurfaceContainerLow
 import com.android.internal.R.color.materialColorSurfaceDim
-import com.android.window.flags.Flags
 import com.android.wm.shell.R
 import android.window.DesktopModeFlags
 import androidx.core.view.ViewCompat
@@ -463,7 +462,8 @@
     private fun shouldShowExitFullImmersiveOrMaximizeIcon(
         isTaskMaximized: Boolean,
         inFullImmersiveState: Boolean
-    ): Boolean = (Flags.enableFullyImmersiveInDesktop() && inFullImmersiveState) || isTaskMaximized
+    ): Boolean = (DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue && inFullImmersiveState)
+            || isTaskMaximized
 
     private fun getHeaderStyle(header: Header): HeaderStyle {
         return HeaderStyle(
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/AndroidManifest.xml b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/AndroidManifest.xml
index 1bbbefa..8fc974d 100644
--- a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/AndroidManifest.xml
@@ -47,6 +47,8 @@
     <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
     <!-- Allow the test to connect to perfetto trace processor -->
     <uses-permission android:name="android.permission.INTERNET"/>
+    <!-- Use trusted virtual displays to emulate an external display -->
+    <uses-permission android:name="android.permission.ADD_TRUSTED_DISPLAY"/>
 
     <!-- Allow the test to write directly to /sdcard/ and connect to trace processor -->
     <application android:requestLegacyExternalStorage="true"
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
index ab1ac1a..9b40273 100644
--- a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
@@ -19,7 +19,7 @@
 import android.tools.PlatformConsts.DESKTOP_MODE_MINIMUM_WINDOW_HEIGHT
 import android.tools.PlatformConsts.DESKTOP_MODE_MINIMUM_WINDOW_WIDTH
 import android.tools.flicker.AssertionInvocationGroup
-import android.tools.flicker.assertors.assertions.AppLayerIncreasesInSize
+import android.tools.flicker.assertors.assertions.ResizeVeilKeepsIncreasingInSize
 import android.tools.flicker.assertors.assertions.AppLayerIsInvisibleAtEnd
 import android.tools.flicker.assertors.assertions.AppLayerIsVisibleAlways
 import android.tools.flicker.assertors.assertions.AppLayerIsVisibleAtStart
@@ -36,6 +36,7 @@
 import android.tools.flicker.assertors.assertions.AppWindowHasMaxDisplayWidth
 import android.tools.flicker.assertors.assertions.AppWindowHasSizeOfAtLeast
 import android.tools.flicker.assertors.assertions.AppWindowInsideDisplayBoundsAtEnd
+import android.tools.flicker.assertors.assertions.AppWindowIsBiggerThanInitialBoundsAtEnd
 import android.tools.flicker.assertors.assertions.AppWindowIsInvisibleAtEnd
 import android.tools.flicker.assertors.assertions.AppWindowIsVisibleAlways
 import android.tools.flicker.assertors.assertions.AppWindowMaintainsAspectRatioAlways
@@ -168,9 +169,12 @@
                         TaggedCujTransitionMatcher(associatedTransitionRequired = false)
                     )
                     .build(),
-                // TODO(373638597) Add AppLayerIncreasesInSize assertion
-                assertions = AssertionTemplates.DESKTOP_MODE_APP_VISIBILITY_ASSERTIONS
-            )
+                assertions = AssertionTemplates.DESKTOP_MODE_APP_VISIBILITY_ASSERTIONS +
+                        listOf(
+                            ResizeVeilKeepsIncreasingInSize(DESKTOP_MODE_APP),
+                            AppWindowIsBiggerThanInitialBoundsAtEnd(DESKTOP_MODE_APP),
+                        ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING })
+                )
 
         val EDGE_RESIZE =
             FlickerConfigEntry(
@@ -184,7 +188,8 @@
                     .build(),
                 assertions = AssertionTemplates.DESKTOP_MODE_APP_VISIBILITY_ASSERTIONS +
                         listOf(
-                            AppLayerIncreasesInSize(DESKTOP_MODE_APP),
+                            ResizeVeilKeepsIncreasingInSize(DESKTOP_MODE_APP),
+                            AppWindowIsBiggerThanInitialBoundsAtEnd(DESKTOP_MODE_APP),
                         ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
             )
 
@@ -223,9 +228,9 @@
                 assertions =
                 AssertionTemplates.DESKTOP_MODE_APP_VISIBILITY_ASSERTIONS +
                         listOf(
-                            // TODO(373638597) Add AppLayerIncreasesInSize assertion
                             AppWindowHasMaxDisplayHeight(DESKTOP_MODE_APP),
-                            AppWindowHasMaxDisplayWidth(DESKTOP_MODE_APP)
+                            AppWindowHasMaxDisplayWidth(DESKTOP_MODE_APP),
+                            ResizeVeilKeepsIncreasingInSize(DESKTOP_MODE_APP),
                         ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
             )
 
@@ -368,7 +373,7 @@
                 ),
                 assertions = AssertionTemplates.DESKTOP_MODE_APP_VISIBILITY_ASSERTIONS +
                         listOf(
-                            AppLayerIncreasesInSize(DESKTOP_MODE_APP),
+                            ResizeVeilKeepsIncreasingInSize(DESKTOP_MODE_APP),
                             AppWindowHasMaxDisplayHeight(DESKTOP_MODE_APP),
                             AppWindowHasMaxDisplayWidth(DESKTOP_MODE_APP)
                         ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
@@ -393,7 +398,7 @@
                 assertions =
                 AssertionTemplates.DESKTOP_MODE_APP_VISIBILITY_ASSERTIONS +
                         listOf(
-                            AppLayerIncreasesInSize(DESKTOP_MODE_APP),
+                            ResizeVeilKeepsIncreasingInSize(DESKTOP_MODE_APP),
                             AppWindowMaintainsAspectRatioAlways(DESKTOP_MODE_APP),
                             AppWindowHasMaxBoundsInOnlyOneDimension(DESKTOP_MODE_APP)
                         ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
@@ -541,5 +546,29 @@
                         AppWindowBecomesPinned(DESKTOP_MODE_APP),
                     ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING })
             )
+
+        val OPEN_APP_WHEN_EXTERNAL_DISPLAY_CONNECTED =
+            FlickerConfigEntry(
+                scenarioId = ScenarioId("OPEN_APP_WHEN_EXTERNAL_DISPLAY_CONNECTED"),
+                extractor =
+                ShellTransitionScenarioExtractor(
+                    transitionMatcher =
+                    object : ITransitionMatcher {
+                        override fun findAll(
+                            transitions: Collection<Transition>
+                        ): Collection<Transition> {
+                                return listOf(transitions
+                                    .filter { it.type == TransitionType.OPEN }
+                                    .maxByOrNull { it.id }!!)
+                        }
+                    }
+                ),
+                assertions =
+                        listOf(
+                            AppWindowBecomesVisible(DESKTOP_MODE_APP),
+                            AppWindowOnTopAtEnd(DESKTOP_MODE_APP),
+                            AppWindowBecomesVisible(DESKTOP_WALLPAPER),
+                        ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
+            )
     }
 }
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/OpenAppWithExternalDisplayConnected.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/OpenAppWithExternalDisplayConnected.kt
new file mode 100644
index 0000000..66d2ea9
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/OpenAppWithExternalDisplayConnected.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker
+
+import android.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.DesktopModeFlickerScenarios.Companion.OPEN_APP_WHEN_EXTERNAL_DISPLAY_CONNECTED
+import com.android.wm.shell.scenarios.OpenAppWithExternalDisplayConnected
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Open an app on the default display when an external display is connected.
+ *
+ * Assert that the app launches in desktop mode.
+ */
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class OpenAppWithExternalDisplayConnected : OpenAppWithExternalDisplayConnected() {
+    @ExpectedScenarios(["OPEN_APP_WHEN_EXTERNAL_DISPLAY_CONNECTED"])
+    @Test
+    override fun openAppWithExternalDisplayConnected() = super.openAppWithExternalDisplayConnected()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig()
+                .use(FlickerServiceConfig.DEFAULT)
+                .use(OPEN_APP_WHEN_EXTERNAL_DISPLAY_CONNECTED)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/OpenAppWithExternalDisplayConnectedTest.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/OpenAppWithExternalDisplayConnectedTest.kt
new file mode 100644
index 0000000..cc9a799
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/OpenAppWithExternalDisplayConnectedTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.OpenAppWithExternalDisplayConnected
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [OpenAppWithExternalDisplayConnected]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class OpenAppWithExternalDisplayConnectedTest : OpenAppWithExternalDisplayConnected()
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt
index 8d04749..2115f70 100644
--- a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt
@@ -50,7 +50,7 @@
     @Test
     open fun enterDesktopWithDrag() {
         // By default this method uses drag to desktop
-        testApp.enterDesktopMode(wmHelper, device)
+        testApp.enterDesktopMode(wmHelper, device, shouldUseDragToDesktop = true)
     }
 
     @After
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDragExistingWindows.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDragExistingWindows.kt
index 814478a..9a19193 100644
--- a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDragExistingWindows.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDragExistingWindows.kt
@@ -62,7 +62,7 @@
     @Test
     open fun reenterDesktopWithDrag() {
         // By default this method uses drag to desktop
-        testApp.enterDesktopMode(wmHelper, device)
+        testApp.enterDesktopMode(wmHelper, device, shouldUseDragToDesktop = true)
     }
 
     @After
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenAppWithExternalDisplayConnected.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenAppWithExternalDisplayConnected.kt
new file mode 100644
index 0000000..81c46f1
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenAppWithExternalDisplayConnected.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.scenarios
+
+import android.app.Instrumentation
+import android.content.Context
+import android.hardware.display.DisplayManager
+import android.hardware.display.VirtualDisplay
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.flicker.rules.ChangeDisplayOrientationRule
+import android.tools.traces.parsers.WindowManagerStateHelper
+import android.util.DisplayMetrics
+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.ExtendedDisplaySettingsSession
+import com.android.wm.shell.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 launching an app in desktop mode by default when an external display is
+ * connected.
+ */
+@Ignore("Test Base Class")
+abstract class OpenAppWithExternalDisplayConnected
+constructor(private val rotation: Rotation = Rotation.ROTATION_0) {
+    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))
+    private val displayManager =
+        instrumentation.getContext().getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
+    private var virtualDisplay: VirtualDisplay? = null
+
+    private val extendedDisplaySettingsSession =
+        ExtendedDisplaySettingsSession(instrumentation.context.contentResolver)
+
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
+
+    @Before
+    fun setup() {
+        Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
+        Assume.assumeTrue(Flags.enableDisplayWindowingModeSwitching())
+        tapl.setEnableRotation(true)
+        tapl.setExpectedRotation(rotation.value)
+        ChangeDisplayOrientationRule.setRotation(rotation)
+        extendedDisplaySettingsSession.open()
+        virtualDisplay = displayManager.createVirtualDisplay(
+            /* displayName= */ DISPLAY_NAME,
+            /* width= */ DISPLAY_WIDTH,
+            /* height= */ DISPLAY_HEIGHT,
+            /* densityDpi= */ DisplayMetrics.DENSITY_DEFAULT,
+            /* surface= */ null,
+            /* flags= */ DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC or
+                DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY or
+                DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED
+        )
+    }
+
+    @Test
+    open fun openAppWithExternalDisplayConnected() {
+        testApp.open()
+    }
+
+    @After
+    fun teardown() {
+        testApp.exit(wmHelper)
+        virtualDisplay?.let {
+            it.release()
+        }
+        extendedDisplaySettingsSession.close()
+    }
+
+    companion object {
+        const val DISPLAY_NAME = "testVirtualDisplay"
+        const val DISPLAY_HEIGHT = 600
+        const val DISPLAY_WIDTH = 800
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/ExtendedDisplaySettingsSession.kt b/libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/ExtendedDisplaySettingsSession.kt
new file mode 100644
index 0000000..0b2aacd
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/ExtendedDisplaySettingsSession.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell
+
+import android.content.ContentResolver
+import android.provider.Settings
+import android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS
+
+class ExtendedDisplaySettingsSession(private val contentResolver: ContentResolver) {
+    private val settingName = DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS
+    private val initialValue = Settings.Global.getInt(contentResolver, settingName, 0)
+
+    fun open() {
+        Settings.Global.putInt(contentResolver, settingName, 1)
+    }
+
+    fun close() {
+        Settings.Global.putInt(contentResolver, settingName, initialValue)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt
index 417b43a..22cc65d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt
@@ -34,7 +34,6 @@
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.TestShellExecutor
 import com.android.wm.shell.bubbles.bar.BubbleBarLayerView
-import com.android.wm.shell.bubbles.properties.BubbleProperties
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.DisplayImeController
 import com.android.wm.shell.common.DisplayInsetsController
@@ -143,7 +142,7 @@
                 mock<Transitions>(),
                 mock<SyncTransactionQueue>(),
                 mock<IWindowManager>(),
-                mock<BubbleProperties>()
+                BubbleResizabilityChecker()
             )
 
         val bubbleStackViewManager = BubbleStackViewManager.fromBubbleController(bubbleController)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/InputChannelSupplierTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/InputChannelSupplierTest.kt
new file mode 100644
index 0000000..09c2faa
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/InputChannelSupplierTest.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.testing.AndroidTestingRunner
+import android.view.InputChannel
+import androidx.test.filters.SmallTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Tests for [InputChannelSupplier].
+ *
+ * Build/Install/Run:
+ *  atest WMShellUnitTests:InputChannelSupplierTest
+ */
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class InputChannelSupplierTest {
+
+    @Test
+    fun `InputChannelSupplier supplies an InputChannel`() {
+        val supplier = InputChannelSupplier()
+        SuppliersUtilsTest.assertSupplierProvidesValue(supplier) {
+            it is InputChannel
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/SuppliersUtilsTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/SuppliersUtilsTest.kt
new file mode 100644
index 0000000..8468c63
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/SuppliersUtilsTest.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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 java.util.function.Supplier
+
+/**
+ * Utility class we can use to test a []Supplier<T>] of any parameters type [T].
+ */
+class SuppliersUtilsTest {
+
+    companion object {
+        /**
+         * Allows to check that the object supplied is asserts what in [assertion].
+         */
+        fun <T> assertSupplierProvidesValue(supplier: Supplier<T>, assertion: (Any?) -> Boolean) {
+            assert(assertion(supplier.get())) { "Supplier didn't provided what is expected" }
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/WindowSessionSupplierTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/WindowSessionSupplierTest.kt
new file mode 100644
index 0000000..33e8d78
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/WindowSessionSupplierTest.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.testing.AndroidTestingRunner
+import android.view.IWindowSession
+import androidx.test.filters.SmallTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Tests for [WindowSessionSupplier].
+ *
+ * Build/Install/Run:
+ *  atest WMShellUnitTests:WindowSessionSupplierTest
+ */
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class WindowSessionSupplierTest {
+
+    @Test
+    fun `InputChannelSupplier supplies an InputChannel`() {
+        val supplier = WindowSessionSupplier()
+        SuppliersUtilsTest.assertSupplierProvidesValue(supplier) {
+            it is IWindowSession
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDesktopStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDesktopStateTest.java
new file mode 100644
index 0000000..75ad621
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipDesktopStateTest.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.pip;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+
+import static com.android.window.flags.Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_PIP;
+import static com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.platform.test.annotations.EnableFlags;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.window.DisplayAreaInfo;
+import android.window.WindowContainerToken;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
+import com.android.wm.shell.desktopmode.DesktopRepository;
+import com.android.wm.shell.desktopmode.DesktopUserRepositories;
+import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Optional;
+
+/**
+ * Unit test against {@link PipDesktopState}.
+ */
+@SmallTest
+@TestableLooper.RunWithLooper
+@RunWith(AndroidTestingRunner.class)
+@EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
+public class PipDesktopStateTest {
+    @Mock private PipDisplayLayoutState mMockPipDisplayLayoutState;
+    @Mock private Optional<DesktopUserRepositories> mMockDesktopUserRepositoriesOptional;
+    @Mock private Optional<DesktopWallpaperActivityTokenProvider>
+            mMockDesktopWallpaperActivityTokenProviderOptional;
+    @Mock private DesktopUserRepositories mMockDesktopUserRepositories;
+    @Mock private DesktopWallpaperActivityTokenProvider mMockDesktopWallpaperActivityTokenProvider;
+    @Mock private DesktopRepository mMockDesktopRepository;
+    @Mock private RootTaskDisplayAreaOrganizer mMockRootTaskDisplayAreaOrganizer;
+    @Mock private ActivityManager.RunningTaskInfo mMockTaskInfo;
+
+    private static final int DISPLAY_ID = 1;
+    private DisplayAreaInfo mDefaultTda;
+    private PipDesktopState mPipDesktopState;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mMockDesktopUserRepositoriesOptional.get()).thenReturn(mMockDesktopUserRepositories);
+        when(mMockDesktopWallpaperActivityTokenProviderOptional.get()).thenReturn(
+                mMockDesktopWallpaperActivityTokenProvider);
+        when(mMockDesktopUserRepositories.getCurrent()).thenReturn(mMockDesktopRepository);
+        when(mMockDesktopUserRepositoriesOptional.isPresent()).thenReturn(true);
+        when(mMockDesktopWallpaperActivityTokenProviderOptional.isPresent()).thenReturn(true);
+
+        when(mMockTaskInfo.getDisplayId()).thenReturn(DISPLAY_ID);
+        when(mMockPipDisplayLayoutState.getDisplayId()).thenReturn(DISPLAY_ID);
+
+        mDefaultTda = new DisplayAreaInfo(Mockito.mock(WindowContainerToken.class), DISPLAY_ID, 0);
+        when(mMockRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DISPLAY_ID)).thenReturn(
+                mDefaultTda);
+
+        mPipDesktopState = new PipDesktopState(mMockPipDisplayLayoutState,
+                mMockDesktopUserRepositoriesOptional,
+                mMockDesktopWallpaperActivityTokenProviderOptional,
+                mMockRootTaskDisplayAreaOrganizer);
+    }
+
+    @Test
+    public void isDesktopWindowingPipEnabled_returnsTrue() {
+        assertTrue(mPipDesktopState.isDesktopWindowingPipEnabled());
+    }
+
+    @Test
+    public void isDesktopWindowingPipEnabled_desktopRepositoryEmpty_returnsFalse() {
+        when(mMockDesktopUserRepositoriesOptional.isPresent()).thenReturn(false);
+
+        assertFalse(mPipDesktopState.isDesktopWindowingPipEnabled());
+    }
+
+    @Test
+    public void isDesktopWindowingPipEnabled_desktopWallpaperEmpty_returnsFalse() {
+        when(mMockDesktopWallpaperActivityTokenProviderOptional.isPresent()).thenReturn(false);
+
+        assertFalse(mPipDesktopState.isDesktopWindowingPipEnabled());
+    }
+
+    @Test
+    @EnableFlags(FLAG_ENABLE_CONNECTED_DISPLAYS_PIP)
+    public void isConnectedDisplaysPipEnabled_returnsTrue() {
+        assertTrue(mPipDesktopState.isConnectedDisplaysPipEnabled());
+    }
+
+    @Test
+    public void isPipEnteringInDesktopMode_visibleCountZero_minimizedPipPresent_returnsTrue() {
+        when(mMockDesktopRepository.getVisibleTaskCount(DISPLAY_ID)).thenReturn(0);
+        when(mMockDesktopRepository.isMinimizedPipPresentInDisplay(DISPLAY_ID)).thenReturn(true);
+
+        assertTrue(mPipDesktopState.isPipEnteringInDesktopMode(mMockTaskInfo));
+    }
+
+    @Test
+    public void isPipEnteringInDesktopMode_visibleCountNonzero_minimizedPipAbsent_returnsTrue() {
+        when(mMockDesktopRepository.getVisibleTaskCount(DISPLAY_ID)).thenReturn(1);
+        when(mMockDesktopRepository.isMinimizedPipPresentInDisplay(DISPLAY_ID)).thenReturn(false);
+
+        assertTrue(mPipDesktopState.isPipEnteringInDesktopMode(mMockTaskInfo));
+    }
+
+    @Test
+    public void isPipEnteringInDesktopMode_visibleCountZero_minimizedPipAbsent_returnsFalse() {
+        when(mMockDesktopRepository.getVisibleTaskCount(DISPLAY_ID)).thenReturn(0);
+        when(mMockDesktopRepository.isMinimizedPipPresentInDisplay(DISPLAY_ID)).thenReturn(false);
+
+        assertFalse(mPipDesktopState.isPipEnteringInDesktopMode(mMockTaskInfo));
+    }
+
+    @Test
+    public void shouldExitPipExitDesktopMode_visibleCountZero_wallpaperInvisible_returnsFalse() {
+        when(mMockDesktopRepository.getVisibleTaskCount(DISPLAY_ID)).thenReturn(0);
+        when(mMockDesktopWallpaperActivityTokenProvider.isWallpaperActivityVisible(
+                DISPLAY_ID)).thenReturn(false);
+
+        assertFalse(mPipDesktopState.shouldExitPipExitDesktopMode());
+    }
+
+    @Test
+    public void shouldExitPipExitDesktopMode_visibleCountNonzero_wallpaperVisible_returnsFalse() {
+        when(mMockDesktopRepository.getVisibleTaskCount(DISPLAY_ID)).thenReturn(1);
+        when(mMockDesktopWallpaperActivityTokenProvider.isWallpaperActivityVisible(
+                DISPLAY_ID)).thenReturn(true);
+
+        assertFalse(mPipDesktopState.shouldExitPipExitDesktopMode());
+    }
+
+    @Test
+    public void shouldExitPipExitDesktopMode_visibleCountZero_wallpaperVisible_returnsTrue() {
+        when(mMockDesktopRepository.getVisibleTaskCount(DISPLAY_ID)).thenReturn(0);
+        when(mMockDesktopWallpaperActivityTokenProvider.isWallpaperActivityVisible(
+                DISPLAY_ID)).thenReturn(true);
+
+        assertTrue(mPipDesktopState.shouldExitPipExitDesktopMode());
+    }
+
+    @Test
+    public void getOutPipWindowingMode_exitToDesktop_displayFreeform_returnsUndefined() {
+        // Set visible task count to 1 so isPipExitingToDesktopMode returns true
+        when(mMockDesktopRepository.getVisibleTaskCount(DISPLAY_ID)).thenReturn(1);
+        setDisplayWindowingMode(WINDOWING_MODE_FREEFORM);
+
+        assertEquals(WINDOWING_MODE_UNDEFINED, mPipDesktopState.getOutPipWindowingMode());
+    }
+
+    @Test
+    public void getOutPipWindowingMode_exitToDesktop_displayFullscreen_returnsFreeform() {
+        // Set visible task count to 1 so isPipExitingToDesktopMode returns true
+        when(mMockDesktopRepository.getVisibleTaskCount(DISPLAY_ID)).thenReturn(1);
+        setDisplayWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+        assertEquals(WINDOWING_MODE_FREEFORM, mPipDesktopState.getOutPipWindowingMode());
+    }
+
+    @Test
+    public void getOutPipWindowingMode_exitToFullscreen_displayFullscreen_returnsUndefined() {
+        setDisplayWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+        assertEquals(WINDOWING_MODE_UNDEFINED, mPipDesktopState.getOutPipWindowingMode());
+    }
+
+    private void setDisplayWindowingMode(int windowingMode) {
+        mDefaultTda.configuration.windowConfiguration.setWindowingMode(windowingMode);
+    }
+}
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 fd3d3b5..8c34c19 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
@@ -36,6 +36,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.DisplayController;
@@ -66,9 +67,9 @@
     public void setup() {
         MockitoAnnotations.initMocks(this);
         Configuration configuration = getConfiguration();
-        mSplitLayout = new SplitLayout("TestSplitLayout", mContext, configuration,
+        mSplitLayout = spy(new SplitLayout("TestSplitLayout", mContext, configuration,
                 mSplitLayoutHandler, mCallbacks, mDisplayController, mDisplayImeController,
-                mTaskOrganizer, SplitLayout.PARALLAX_NONE, mSplitState, mHandler);
+                mTaskOrganizer, SplitLayout.PARALLAX_NONE, mSplitState, mHandler));
         SplitWindowManager splitWindowManager = new SplitWindowManager("TestSplitWindowManager",
                 mContext,
                 configuration, mCallbacks);
@@ -98,6 +99,14 @@
                 "false", false);
     }
 
+    @Test
+    public void swapDividerActionForA11y() {
+        mDividerView.setAccessibilityDelegate(mDividerView.mHandleDelegate);
+        mDividerView.getAccessibilityDelegate().performAccessibilityAction(mDividerView,
+                R.id.action_swap_apps, null);
+        verify(mSplitLayout, times(1)).onDoubleTappedDivider();
+    }
+
     private static MotionEvent getMotionEvent(long eventTime, int action, float x, float y) {
         MotionEvent.PointerProperties properties = new MotionEvent.PointerProperties();
         properties.id = 0;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/transition/SurfaceBuilderSupplierTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/transition/SurfaceBuilderSupplierTest.kt
new file mode 100644
index 0000000..f88f723
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/transition/SurfaceBuilderSupplierTest.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.transition
+
+import android.testing.AndroidTestingRunner
+import android.view.SurfaceControl
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.common.SuppliersUtilsTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Tests for [SurfaceBuilderSupplier].
+ *
+ * Build/Install/Run:
+ *  atest WMShellUnitTests:SurfaceBuilderSupplierTest
+ */
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class SurfaceBuilderSupplierTest {
+
+    @Test
+    fun `SurfaceBuilderSupplier supplies an SurfaceControl Builder`() {
+        val supplier = SurfaceBuilderSupplier()
+        SuppliersUtilsTest.assertSupplierProvidesValue(supplier) {
+            it is SurfaceControl.Builder
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/transition/TransactionSupplierTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/transition/TransactionSupplierTest.kt
new file mode 100644
index 0000000..12b4d8b
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/transition/TransactionSupplierTest.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.transition
+
+import android.testing.AndroidTestingRunner
+import android.view.SurfaceControl
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.common.SuppliersUtilsTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Tests for [TransactionSupplier].
+ *
+ * Build/Install/Run:
+ *  atest WMShellUnitTests:TransactionSupplierTest
+ */
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class TransactionSupplierTest {
+
+    @Test
+    fun `SurfaceBuilderSupplier supplies a Transaction`() {
+        val supplier = TransactionSupplier()
+        SuppliersUtilsTest.assertSupplierProvidesValue(supplier) {
+            it is SurfaceControl.Transaction
+        }
+    }
+}
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 b5c9fa1..2264ade 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
@@ -49,6 +49,7 @@
 
 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;
 import com.android.wm.shell.common.DisplayImeController;
 import com.android.wm.shell.common.DisplayInsetsController;
@@ -85,7 +86,7 @@
  */
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
-public class CompatUIControllerTest extends CompatUIShellTestCase {
+public class CompatUIControllerTest extends ShellTestCase {
     private static final int DISPLAY_ID = 0;
     private static final int TASK_ID = 12;
 
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 2117b06..c567b5f 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
@@ -38,6 +38,7 @@
 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;
@@ -62,7 +63,7 @@
  */
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
-public class CompatUILayoutTest extends CompatUIShellTestCase {
+public class CompatUILayoutTest extends ShellTestCase {
 
     private static final int TASK_ID = 1;
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIShellTestCase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIShellTestCase.java
deleted file mode 100644
index 979cee9..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIShellTestCase.java
+++ /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.wm.shell.compatui;
-
-import com.android.wm.shell.ShellTestCase;
-
-/**
- * Base class for CompatUI tests.
- */
-public class CompatUIShellTestCase extends ShellTestCase {
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIStatusManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIStatusManagerTest.java
index 0b37648..8fd7c0e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIStatusManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIStatusManagerTest.java
@@ -27,6 +27,8 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.wm.shell.ShellTestCase;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -42,7 +44,7 @@
  */
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
-public class CompatUIStatusManagerTest extends CompatUIShellTestCase {
+public class CompatUIStatusManagerTest extends ShellTestCase {
 
     private FakeCompatUIStatusManagerTest mTestState;
     private CompatUIStatusManager mStatusManager;
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 010474e..0562bb8 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
@@ -53,6 +53,7 @@
 
 import com.android.window.flags.Flags;
 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;
@@ -77,7 +78,7 @@
  */
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
-public class CompatUIWindowManagerTest extends CompatUIShellTestCase {
+public class CompatUIWindowManagerTest extends ShellTestCase {
 
     private static final int TASK_ID = 1;
     private static final int TASK_WIDTH = 2000;
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 e786fef..c6884ea 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
@@ -32,6 +32,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTestCase;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -47,7 +48,7 @@
  */
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
-public class LetterboxEduDialogLayoutTest extends CompatUIShellTestCase {
+public class LetterboxEduDialogLayoutTest extends ShellTestCase {
 
     @Mock
     private Runnable mDismissCallback;
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 09fc082..cbf5d1b 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
@@ -62,6 +62,7 @@
 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.TestShellExecutor;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.DockStateReader;
@@ -90,7 +91,7 @@
  */
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
-public class LetterboxEduWindowManagerTest extends CompatUIShellTestCase {
+public class LetterboxEduWindowManagerTest extends ShellTestCase {
 
     private static final int USER_ID_1 = 1;
     private static final int USER_ID_2 = 2;
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 02c099b..31ea8f7 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
@@ -34,6 +34,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTestCase;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -50,7 +51,7 @@
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-public class ReachabilityEduLayoutTest extends CompatUIShellTestCase {
+public class ReachabilityEduLayoutTest extends ShellTestCase {
 
     private ReachabilityEduLayout mLayout;
     private View mMoveUpButton;
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 fa04e07..1b2c094 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
@@ -30,6 +30,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestShellExecutor;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.SyncTransactionQueue;
@@ -52,7 +53,7 @@
  */
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
-public class ReachabilityEduWindowManagerTest extends CompatUIShellTestCase {
+public class ReachabilityEduWindowManagerTest extends ShellTestCase {
     @Mock
     private SyncTransactionQueue mSyncTransactionQueue;
     @Mock
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 2cded9d..5075453 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
@@ -34,6 +34,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTestCase;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -51,7 +52,7 @@
  */
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
-public class RestartDialogLayoutTest extends CompatUIShellTestCase  {
+public class RestartDialogLayoutTest extends ShellTestCase {
 
     @Mock private Runnable mDismissCallback;
     @Mock private Consumer<Boolean> mRestartCallback;
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 ebd0f41..779a5ca 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
@@ -28,6 +28,7 @@
 import androidx.test.filters.SmallTest;
 
 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.transition.Transitions;
@@ -50,7 +51,7 @@
  */
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
-public class RestartDialogWindowManagerTest extends CompatUIShellTestCase {
+public class RestartDialogWindowManagerTest extends ShellTestCase {
 
     @Mock
     private SyncTransactionQueue mSyncTransactionQueue;
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 c6532e1..2b4d5f12 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
@@ -38,6 +38,7 @@
 
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestShellExecutor;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.SyncTransactionQueue;
@@ -62,7 +63,7 @@
  */
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
-public class UserAspectRatioSettingsLayoutTest extends CompatUIShellTestCase {
+public class UserAspectRatioSettingsLayoutTest extends ShellTestCase {
 
     private static final int TASK_ID = 1;
 
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 096e900..af7c1f5 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
@@ -54,6 +54,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestShellExecutor;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.SyncTransactionQueue;
@@ -83,7 +84,7 @@
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 @SmallTest
-public class UserAspectRatioSettingsWindowManagerTest extends CompatUIShellTestCase {
+public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase {
 
     private static final int TASK_ID = 1;
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxControllerRobotTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxControllerRobotTest.kt
index 88cc981..e34884b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxControllerRobotTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxControllerRobotTest.kt
@@ -33,10 +33,10 @@
 
     companion object {
         @JvmStatic
-        private val DISPLAY_ID = 1
+        val DISPLAY_ID = 1
 
         @JvmStatic
-        private val TASK_ID = 20
+        val TASK_ID = 20
     }
 
     lateinit var letterboxController: LetterboxController
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxGestureDelegateTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxGestureDelegateTest.kt
new file mode 100644
index 0000000..bc3416a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxGestureDelegateTest.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.letterbox
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn
+import com.android.wm.shell.compatui.letterbox.LetterboxEvents.motionEventAt
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.verify
+
+/**
+ * Tests for [LetterboxGestureDelegate].
+ *
+ * Build/Install/Run:
+ *  atest WMShellUnitTests:LetterboxGestureDelegateTest
+ */
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class LetterboxGestureDelegateTest {
+
+    class DelegateTest : LetterboxGestureListener by LetterboxGestureDelegate
+
+    val delegate = DelegateTest()
+
+    @Before
+    fun setUp() {
+        spyOn(LetterboxGestureDelegate)
+    }
+
+    @Test
+    fun `When delegating all methods are invoked`() {
+        val event = motionEventAt(0f, 0f)
+        with(delegate) {
+            onDown(event)
+            onShowPress(event)
+            onSingleTapUp(event)
+            onScroll(event, event, 0f, 0f)
+            onFling(event, event, 0f, 0f)
+            onLongPress(event)
+            onSingleTapConfirmed(event)
+            onDoubleTap(event)
+            onDoubleTapEvent(event)
+            onContextClick(event)
+        }
+        with(LetterboxGestureDelegate) {
+            verify(this).onDown(event)
+            verify(this).onShowPress(event)
+            verify(this).onSingleTapUp(event)
+            verify(this).onScroll(event, event, 0f, 0f)
+            verify(this).onFling(event, event, 0f, 0f)
+            verify(this).onLongPress(event)
+            verify(this).onSingleTapConfirmed(event)
+            verify(this).onDoubleTap(event)
+            verify(this).onDoubleTapEvent(event)
+            verify(this).onContextClick(event)
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt
new file mode 100644
index 0000000..fa95fae
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.letterbox
+
+import android.content.Context
+import android.graphics.Rect
+import android.graphics.Region
+import android.os.Handler
+import android.os.Looper
+import android.testing.AndroidTestingRunner
+import android.view.IWindowSession
+import android.view.InputChannel
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.common.InputChannelSupplier
+import com.android.wm.shell.common.WindowSessionSupplier
+import com.android.wm.shell.compatui.letterbox.LetterboxMatchers.asAnyMode
+import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModelTestsBase.Companion.TAG
+import java.util.function.Consumer
+import java.util.function.Supplier
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+
+/**
+ * Tests for [LetterboxInputController].
+ *
+ * Build/Install/Run:
+ *  atest WMShellUnitTests:LetterboxInputControllerTest
+ */
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class LetterboxInputControllerTest : ShellTestCase() {
+
+    @Test
+    fun `When creation is requested the surface is created if not present`() {
+        runTestScenario { r ->
+            r.sendCreateSurfaceRequest()
+
+            r.checkInputSurfaceBuilderInvoked()
+        }
+    }
+
+    @Test
+    fun `When creation is requested multiple times the input surface is created once`() {
+        runTestScenario { r ->
+            r.sendCreateSurfaceRequest()
+            r.sendCreateSurfaceRequest()
+            r.sendCreateSurfaceRequest()
+            r.sendCreateSurfaceRequest()
+
+            r.checkInputSurfaceBuilderInvoked(times = 1)
+        }
+    }
+
+    @Test
+    fun `A different input surface is created for every key`() {
+        runTestScenario { r ->
+            r.sendCreateSurfaceRequest()
+            r.sendCreateSurfaceRequest()
+            r.sendCreateSurfaceRequest(displayId = 2)
+            r.sendCreateSurfaceRequest(displayId = 2, taskId = 2)
+            r.sendCreateSurfaceRequest(displayId = 2)
+            r.sendCreateSurfaceRequest(displayId = 2, taskId = 2)
+
+            r.checkInputSurfaceBuilderInvoked(times = 3)
+        }
+    }
+
+    @Test
+    fun `Created spy surface is removed once`() {
+        runTestScenario { r ->
+            r.sendCreateSurfaceRequest()
+            r.checkInputSurfaceBuilderInvoked()
+
+            r.sendDestroySurfaceRequest()
+            r.sendDestroySurfaceRequest()
+            r.sendDestroySurfaceRequest()
+
+            r.checkTransactionRemovedInvoked()
+        }
+    }
+    @Test
+    fun `Only existing surfaces receive visibility update`() {
+        runTestScenario { r ->
+            r.sendCreateSurfaceRequest()
+            r.sendUpdateSurfaceVisibilityRequest(visible = true)
+            r.sendUpdateSurfaceVisibilityRequest(visible = true, displayId = 20)
+
+            r.checkVisibilityUpdated(expectedVisibility = true)
+        }
+    }
+
+    @Test
+    fun `Only existing surfaces receive taskBounds update`() {
+        runTestScenario { r ->
+            r.sendUpdateSurfaceBoundsRequest(
+                taskBounds = Rect(0, 0, 2000, 1000),
+                activityBounds = Rect(500, 0, 1500, 1000)
+            )
+
+            r.checkUpdateSessionRegion(times = 0, region = Region(0, 0, 2000, 1000))
+            r.checkSurfaceSizeUpdated(times = 0, expectedWidth = 2000, expectedHeight = 1000)
+
+            r.resetTransitionTest()
+
+            r.sendCreateSurfaceRequest()
+            r.sendUpdateSurfaceBoundsRequest(
+                taskBounds = Rect(0, 0, 2000, 1000),
+                activityBounds = Rect(500, 0, 1500, 1000)
+            )
+            r.checkUpdateSessionRegion(region = Region(0, 0, 2000, 1000))
+            r.checkSurfaceSizeUpdated(expectedWidth = 2000, expectedHeight = 1000)
+        }
+    }
+
+    /**
+     * Runs a test scenario providing a Robot.
+     */
+    fun runTestScenario(consumer: Consumer<InputLetterboxControllerRobotTest>) {
+        consumer.accept(InputLetterboxControllerRobotTest(mContext).apply { initController() })
+    }
+
+    class InputLetterboxControllerRobotTest(private val context: Context) :
+        LetterboxControllerRobotTest() {
+
+        private val inputSurfaceBuilder: LetterboxInputSurfaceBuilder
+        private val handler = Handler(Looper.getMainLooper())
+        private val listener: LetterboxGestureListener
+        private val listenerSupplier: Supplier<LetterboxGestureListener>
+        private val windowSessionSupplier: WindowSessionSupplier
+        private val windowSession: IWindowSession
+        private val inputChannelSupplier: InputChannelSupplier
+
+        init {
+            inputSurfaceBuilder = getLetterboxInputSurfaceBuilderMock()
+            listener = mock<LetterboxGestureListener>()
+            listenerSupplier = mock<Supplier<LetterboxGestureListener>>()
+            doReturn(LetterboxGestureDelegate).`when`(listenerSupplier).get()
+            windowSessionSupplier = mock<WindowSessionSupplier>()
+            windowSession = mock<IWindowSession>()
+            doReturn(windowSession).`when`(windowSessionSupplier).get()
+            inputChannelSupplier = mock<InputChannelSupplier>()
+            val inputChannels = InputChannel.openInputChannelPair(TAG)
+            inputChannels.first().dispose()
+            doReturn(inputChannels[1]).`when`(inputChannelSupplier).get()
+        }
+
+        override fun buildController(): LetterboxController =
+            LetterboxInputController(
+                context,
+                handler,
+                inputSurfaceBuilder,
+                listenerSupplier,
+                windowSessionSupplier,
+                inputChannelSupplier
+            )
+
+        fun checkInputSurfaceBuilderInvoked(
+            times: Int = 1,
+            name: String = "",
+            callSite: String = ""
+        ) {
+            verify(inputSurfaceBuilder, times(times)).createInputSurface(
+                eq(transaction),
+                eq(parentLeash),
+                name.asAnyMode(),
+                callSite.asAnyMode()
+            )
+        }
+
+        fun checkUpdateSessionRegion(times: Int = 1, displayId: Int = DISPLAY_ID, region: Region) {
+            verify(windowSession, times(times)).updateInputChannel(
+                any(),
+                eq(displayId),
+                any(),
+                any(),
+                any(),
+                any(),
+                eq(region)
+            )
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxTestUtils.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxTestUtils.kt
index 2c06dfd..3ce1fec 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxTestUtils.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxTestUtils.kt
@@ -16,6 +16,8 @@
 
 package com.android.wm.shell.compatui.letterbox
 
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.obtain
 import android.view.SurfaceControl
 import org.mockito.kotlin.any
 import org.mockito.kotlin.anyOrNull
@@ -37,6 +39,18 @@
     doReturn(this).`when`(this).setWindowCrop(anyOrNull(), any(), any())
 }
 
+/**
+ * @return A [LetterboxInputSurfaceBuilder] mock to use in tests.
+ */
+fun getLetterboxInputSurfaceBuilderMock() = mock<LetterboxInputSurfaceBuilder>().apply {
+    doReturn(SurfaceControl()).`when`(this).createInputSurface(
+        any(),
+        any(),
+        any(),
+        any()
+    )
+}
+
 // Utility to make verification mode depending on a [Boolean].
 fun Boolean.asMode(): VerificationMode = if (this) times(1) else never()
 
@@ -47,5 +61,10 @@
     fun String.asAnyMode() = asAnyMode { this.isEmpty() }
 }
 
+object LetterboxEvents {
+    fun motionEventAt(x: Float, y: Float) =
+        obtain(0, 10, ACTION_DOWN, x, y, 0)
+}
+
 private inline fun <reified T : Any> T.asAnyMode(condition: () -> Boolean) =
     (if (condition()) any() else eq(this))
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
index 09ffd94..d6b13610 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
@@ -113,7 +113,7 @@
                 .strictness(Strictness.LENIENT)
                 .spyStatic(DesktopModeStatus::class.java)
                 .startMocking()
-        doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+        doReturn(true).`when` { DesktopModeStatus.isDeviceEligibleForDesktopMode(any()) }
 
         testScope = CoroutineScope(Dispatchers.Unconfined + SupervisorJob())
         shellInit = spy(ShellInit(testExecutor))
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt
index 470c110..403d468 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt
@@ -112,7 +112,7 @@
                 .strictness(Strictness.LENIENT)
                 .spyStatic(DesktopModeStatus::class.java)
                 .startMocking()
-        doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+        doReturn(true).`when` { DesktopModeStatus.isDeviceEligibleForDesktopMode(any()) }
 
         testScope = CoroutineScope(Dispatchers.Unconfined + SupervisorJob())
         shellInit = spy(ShellInit(testExecutor))
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
index e46d2c7..a657553 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
@@ -16,25 +16,34 @@
 
 package com.android.wm.shell.desktopmode
 
+import android.animation.AnimatorTestRule
 import android.app.ActivityManager.RunningTaskInfo
 import android.graphics.PointF
 import android.graphics.Rect
+import android.platform.test.annotations.EnableFlags
 import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
 import android.view.SurfaceControl
 import androidx.test.filters.SmallTest
 import com.android.internal.policy.SystemBarUtils
+import com.android.modules.utils.testing.ExtendedMockitoRule
+import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE
 import com.android.wm.shell.R
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.DisplayLayout
 import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
+import org.mockito.kotlin.any
 import org.mockito.kotlin.whenever
 
 /**
@@ -43,23 +52,39 @@
  * Usage: atest WMShellUnitTests:DesktopModeVisualIndicatorTest
  */
 @SmallTest
+@RunWithLooper
 @RunWith(AndroidTestingRunner::class)
+@EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
 class DesktopModeVisualIndicatorTest : ShellTestCase() {
-    @Mock private lateinit var taskInfo: RunningTaskInfo
+
+    @JvmField @Rule val animatorTestRule = AnimatorTestRule(this)
+
+    @JvmField
+    @Rule
+    val extendedMockitoRule =
+        ExtendedMockitoRule.Builder(this).mockStatic(DesktopModeStatus::class.java).build()!!
+
+    private lateinit var taskInfo: RunningTaskInfo
     @Mock private lateinit var syncQueue: SyncTransactionQueue
     @Mock private lateinit var displayController: DisplayController
     @Mock private lateinit var taskSurface: SurfaceControl
     @Mock private lateinit var taskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
     @Mock private lateinit var displayLayout: DisplayLayout
+    @Mock private lateinit var bubbleBoundsProvider: BubbleDropTargetBoundsProvider
 
     private lateinit var visualIndicator: DesktopModeVisualIndicator
 
     @Before
     fun setUp() {
+        whenever(DesktopModeStatus.canEnterDesktopMode(any())).thenReturn(true)
         whenever(displayLayout.width()).thenReturn(DISPLAY_BOUNDS.width())
         whenever(displayLayout.height()).thenReturn(DISPLAY_BOUNDS.height())
         whenever(displayLayout.stableInsets()).thenReturn(STABLE_INSETS)
         whenever(displayController.getDisplayLayout(anyInt())).thenReturn(displayLayout)
+        whenever(displayController.getDisplay(anyInt())).thenReturn(mContext.display)
+        whenever(bubbleBoundsProvider.getBubbleBarExpandedViewDropTargetBounds(any()))
+            .thenReturn(Rect())
+        taskInfo = DesktopTestHelpers.createFullscreenTask()
     }
 
     @Test
@@ -173,6 +198,40 @@
     }
 
     @Test
+    fun testBubbleLeftRegionCalculation() {
+        val bubbleRegionWidth =
+            context.resources.getDimensionPixelSize(R.dimen.bubble_transform_area_width)
+        val bubbleRegionHeight =
+            context.resources.getDimensionPixelSize(R.dimen.bubble_transform_area_height)
+        val expectedRect = Rect(0, 1600 - bubbleRegionHeight, bubbleRegionWidth, 1600)
+
+        createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
+        var testRegion = visualIndicator.calculateBubbleLeftRegion(displayLayout)
+        assertThat(testRegion.bounds).isEqualTo(expectedRect)
+
+        createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT)
+        testRegion = visualIndicator.calculateBubbleLeftRegion(displayLayout)
+        assertThat(testRegion.bounds).isEqualTo(expectedRect)
+    }
+
+    @Test
+    fun testBubbleRightRegionCalculation() {
+        val bubbleRegionWidth =
+            context.resources.getDimensionPixelSize(R.dimen.bubble_transform_area_width)
+        val bubbleRegionHeight =
+            context.resources.getDimensionPixelSize(R.dimen.bubble_transform_area_height)
+        val expectedRect = Rect(2400 - bubbleRegionWidth, 1600 - bubbleRegionHeight, 2400, 1600)
+
+        createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
+        var testRegion = visualIndicator.calculateBubbleRightRegion(displayLayout)
+        assertThat(testRegion.bounds).isEqualTo(expectedRect)
+
+        createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT)
+        testRegion = visualIndicator.calculateBubbleRightRegion(displayLayout)
+        assertThat(testRegion.bounds).isEqualTo(expectedRect)
+    }
+
+    @Test
     fun testDefaultIndicators() {
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
         var result = visualIndicator.updateIndicatorType(PointF(-10000f, 500f))
@@ -190,6 +249,87 @@
         assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)
     }
 
+    @Test
+    @EnableFlags(
+        com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN,
+        com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE,
+    )
+    fun testDefaultIndicatorWithNoDesktop() {
+        whenever(DesktopModeStatus.canEnterDesktopMode(any())).thenReturn(false)
+
+        // Fullscreen to center, no desktop indicator
+        createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
+        var result = visualIndicator.updateIndicatorType(PointF(500f, 500f))
+        assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)
+        // Fullscreen to split
+        result = visualIndicator.updateIndicatorType(PointF(10000f, 500f))
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR)
+        result = visualIndicator.updateIndicatorType(PointF(-10000f, 500f))
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR)
+        // Fullscreen to bubble
+        result = visualIndicator.updateIndicatorType(PointF(100f, 1500f))
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_LEFT_INDICATOR)
+        result = visualIndicator.updateIndicatorType(PointF(2300f, 1500f))
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR)
+        // Split to center, no desktop indicator
+        createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT)
+        result = visualIndicator.updateIndicatorType(PointF(500f, 500f))
+        assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)
+        // Split to fullscreen
+        result = visualIndicator.updateIndicatorType(PointF(500f, 0f))
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR)
+        // Split to bubble
+        result = visualIndicator.updateIndicatorType(PointF(100f, 1500f))
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_LEFT_INDICATOR)
+        result = visualIndicator.updateIndicatorType(PointF(2300f, 1500f))
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR)
+        // Drag app to center, no desktop indicator
+        createVisualIndicator(DesktopModeVisualIndicator.DragStartState.DRAGGED_INTENT)
+        result = visualIndicator.updateIndicatorType(PointF(500f, 500f))
+        assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)
+    }
+
+    @Test
+    @EnableFlags(
+        com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN,
+        com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE,
+    )
+    fun testBubbleLeftVisualIndicatorSize() {
+        val dropTargetBounds = Rect(100, 100, 500, 1500)
+        whenever(bubbleBoundsProvider.getBubbleBarExpandedViewDropTargetBounds(/* onLeft= */ true))
+            .thenReturn(dropTargetBounds)
+        createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
+        visualIndicator.updateIndicatorType(PointF(100f, 1500f))
+
+        animatorTestRule.advanceTimeBy(200)
+
+        assertThat(visualIndicator.indicatorBounds).isEqualTo(dropTargetBounds)
+    }
+
+    @Test
+    @EnableFlags(
+        com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN,
+        com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE,
+    )
+    fun testBubbleRightVisualIndicatorSize() {
+        val dropTargetBounds = Rect(1900, 100, 2300, 1500)
+        whenever(bubbleBoundsProvider.getBubbleBarExpandedViewDropTargetBounds(/* onLeft= */ false))
+            .thenReturn(dropTargetBounds)
+        createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
+        visualIndicator.updateIndicatorType(PointF(2300f, 1500f))
+
+        animatorTestRule.advanceTimeBy(200)
+
+        assertThat(visualIndicator.indicatorBounds).isEqualTo(dropTargetBounds)
+    }
+
     private fun createVisualIndicator(dragStartState: DesktopModeVisualIndicator.DragStartState) {
         visualIndicator =
             DesktopModeVisualIndicator(
@@ -200,6 +340,7 @@
                 taskSurface,
                 taskDisplayAreaOrganizer,
                 dragStartState,
+                bubbleBoundsProvider,
             )
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
index 6a343c5..8510441 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
@@ -47,6 +47,7 @@
 import kotlinx.coroutines.test.runTest
 import kotlinx.coroutines.test.setMain
 import org.junit.After
+import org.junit.Assert.assertThrows
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -163,6 +164,69 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun addTask_deskDoesNotExist_throws() {
+        repo.removeDesk(deskId = 0)
+
+        assertThrows(Exception::class.java) {
+            repo.addTask(displayId = DEFAULT_DISPLAY, taskId = 5, isVisible = true)
+        }
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun addTaskToDesk_deskDoesNotExist_throws() {
+        repo.removeDesk(deskId = 2)
+
+        assertThrows(Exception::class.java) {
+            repo.addTaskToDesk(
+                displayId = DEFAULT_DISPLAY,
+                deskId = 2,
+                taskId = 4,
+                isVisible = true,
+            )
+        }
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun addTaskToDesk_addsToZOrderList() {
+        repo.addDesk(DEFAULT_DISPLAY, deskId = 2)
+        repo.addDesk(DEFAULT_DISPLAY, deskId = 3)
+        repo.addTaskToDesk(displayId = DEFAULT_DISPLAY, deskId = 2, taskId = 5, isVisible = true)
+        repo.addTaskToDesk(displayId = DEFAULT_DISPLAY, deskId = 2, taskId = 6, isVisible = true)
+        repo.addTaskToDesk(displayId = DEFAULT_DISPLAY, deskId = 2, taskId = 7, isVisible = true)
+        repo.addTaskToDesk(displayId = DEFAULT_DISPLAY, deskId = 3, taskId = 8, isVisible = true)
+
+        val orderedTasks = repo.getFreeformTasksIdsInDeskInZOrder(deskId = 2)
+        assertThat(orderedTasks[0]).isEqualTo(7)
+        assertThat(orderedTasks[1]).isEqualTo(6)
+        assertThat(orderedTasks[2]).isEqualTo(5)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun addTaskToDesk_visible_addsToVisible() {
+        repo.addDesk(DEFAULT_DISPLAY, deskId = 2)
+
+        repo.addTaskToDesk(displayId = DEFAULT_DISPLAY, deskId = 2, taskId = 5, isVisible = true)
+
+        assertThat(repo.isVisibleTask(5)).isTrue()
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun addTaskToDesk_removesFromAllOtherDesks() {
+        repo.addDesk(DEFAULT_DISPLAY, deskId = 2)
+        repo.addDesk(DEFAULT_DISPLAY, deskId = 3)
+        repo.addTaskToDesk(displayId = DEFAULT_DISPLAY, deskId = 2, taskId = 7, isVisible = true)
+
+        repo.addTaskToDesk(displayId = DEFAULT_DISPLAY, deskId = 3, taskId = 7, isVisible = true)
+
+        assertThat(repo.getActiveTaskIdsInDesk(2)).doesNotContain(7)
+    }
+
+    @Test
     fun removeActiveTask_notifiesActiveTaskListener() {
         val listener = TestListener()
         repo.addActiveTaskListener(listener)
@@ -467,8 +531,8 @@
         val listener = TestVisibilityListener()
         val executor = TestShellExecutor()
         repo.addVisibleTasksListener(listener, executor)
-        repo.updateTask(DEFAULT_DISPLAY, taskId = 1, isVisible = true)
-        repo.updateTask(DEFAULT_DISPLAY, taskId = 2, isVisible = true)
+        repo.addTask(DEFAULT_DISPLAY, taskId = 1, isVisible = true)
+        repo.addTask(DEFAULT_DISPLAY, taskId = 2, isVisible = true)
         executor.flushAll()
 
         assertThat(listener.visibleTasksCountOnDefaultDisplay).isEqualTo(2)
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 8e7545c..aa7944c 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
@@ -66,6 +66,7 @@
 import android.window.DisplayAreaInfo
 import android.window.IWindowContainerToken
 import android.window.RemoteTransition
+import android.window.TransitionInfo
 import android.window.TransitionRequestInfo
 import android.window.WindowContainerToken
 import android.window.WindowContainerTransaction
@@ -290,7 +291,7 @@
                 .spyStatic(DesktopModeStatus::class.java)
                 .spyStatic(Toast::class.java)
                 .startMocking()
-        doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+        doReturn(true).`when` { DesktopModeStatus.isDeviceEligibleForDesktopMode(any()) }
 
         testScope = CoroutineScope(Dispatchers.Unconfined + SupervisorJob())
         shellInit = spy(ShellInit(testExecutor))
@@ -519,7 +520,10 @@
     }
 
     @Test
-    @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    @DisableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
     fun showDesktopApps_allAppsInvisible_bringsToFront_desktopWallpaperDisabled() {
         val homeTask = setUpHomeTask()
         val task1 = setUpFreeformTask()
@@ -540,8 +544,8 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
     fun showDesktopApps_allAppsInvisible_bringsToFront_desktopWallpaperEnabled() {
-        whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(null)
         val task1 = setUpFreeformTask()
         val task2 = setUpFreeformTask()
         markTaskHidden(task1)
@@ -559,6 +563,29 @@
     }
 
     @Test
+    @EnableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
+    fun showDesktopApps_deskInactive_bringsToFront_multipleDesksEnabled() {
+        whenever(transitions.startTransition(eq(TRANSIT_TO_FRONT), any(), anyOrNull()))
+            .thenReturn(Binder())
+        val deskId = 0
+        // Make desk inactive by activating another desk.
+        taskRepository.addDesk(DEFAULT_DISPLAY, deskId = 1)
+        taskRepository.setActiveDesk(DEFAULT_DISPLAY, deskId = 1)
+
+        controller.activateDesk(deskId, RemoteTransition(TestRemoteTransition()))
+
+        val wct =
+            getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
+        // Wallpaper is moved to front.
+        wct.assertPendingIntentAt(index = 0, desktopWallpaperIntent)
+        // Desk is activated.
+        verify(desksOrganizer).activateDesk(wct, deskId)
+    }
+
+    @Test
     fun isDesktopModeShowing_noTasks_returnsFalse() {
         assertThat(controller.isDesktopModeShowing(displayId = 0)).isFalse()
     }
@@ -632,58 +659,83 @@
         Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
         Flags.FLAG_ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY,
     )
-    @DisableFlags(
-        /** TODO: b/362720497 - re-enable when activation is implemented. */
-        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND
-    )
-    fun showDesktopApps_onSecondaryDisplay_desktopWallpaperEnabled_perDisplayWallpaperEnabled_shouldShowWallpaper() {
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun showDesktopApps_onSecondaryDisplay_desktopWallpaperEnabled_perDisplayWallpaperEnabled_bringsTasksToFront() {
         taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY)
-        val homeTask = setUpHomeTask(SECOND_DISPLAY)
+        setUpHomeTask(SECOND_DISPLAY)
         val task1 = setUpFreeformTask(SECOND_DISPLAY)
         val task2 = setUpFreeformTask(SECOND_DISPLAY)
         markTaskHidden(task1)
         markTaskHidden(task2)
 
+        assertThat(taskRepository.getExpandedTasksOrdered(SECOND_DISPLAY)).contains(task1.taskId)
+        assertThat(taskRepository.getExpandedTasksOrdered(SECOND_DISPLAY)).contains(task2.taskId)
         controller.showDesktopApps(SECOND_DISPLAY, RemoteTransition(TestRemoteTransition()))
 
         val wct =
             getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
-        assertThat(wct.hierarchyOps).hasSize(4)
-        // Expect order to be from bottom: home, wallpaperIntent, task1, task2
-        wct.assertReorderAt(index = 0, homeTask)
-        wct.assertPendingIntentAt(index = 1, desktopWallpaperIntent)
-        wct.assertReorderAt(index = 2, task1)
-        wct.assertReorderAt(index = 3, task2)
+        wct.assertReorder(task1)
+        wct.assertReorder(task2)
+    }
+
+    @Test
+    @EnableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+        Flags.FLAG_ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
+    fun showDesktopApps_onSecondaryDisplay_desktopWallpaperEnabled_perDisplayWallpaperEnabled_multipleDesksEnabled_bringsDeskToFront() {
+        whenever(transitions.startTransition(eq(TRANSIT_TO_FRONT), any(), anyOrNull()))
+            .thenReturn(Binder())
+        taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = 2)
+        setUpHomeTask(SECOND_DISPLAY)
+
+        controller.showDesktopApps(SECOND_DISPLAY, RemoteTransition(TestRemoteTransition()))
+
+        val wct =
+            getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
+        verify(desksOrganizer).activateDesk(wct, deskId = 2)
+    }
+
+    @Test
+    @EnableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+        Flags.FLAG_ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY,
+    )
+    fun showDesktopApps_onSecondaryDisplay_desktopWallpaperEnabled_perDisplayWallpaperEnabled_shouldShowWallpaper() {
+        whenever(transitions.startTransition(eq(TRANSIT_TO_FRONT), any(), anyOrNull()))
+            .thenReturn(Binder())
+        taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY)
+        setUpHomeTask(SECOND_DISPLAY)
+
+        controller.showDesktopApps(SECOND_DISPLAY, RemoteTransition(TestRemoteTransition()))
+
+        val wct =
+            getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
+        wct.assertPendingIntent(desktopWallpaperIntent)
     }
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
-    @DisableFlags(
-        Flags.FLAG_ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY,
-        /** TODO: b/362720497 - re-enable when activation is implemented. */
-        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
-    )
+    @DisableFlags(Flags.FLAG_ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY)
     fun showDesktopApps_onSecondaryDisplay_desktopWallpaperEnabled_shouldNotShowWallpaper() {
+        whenever(transitions.startTransition(eq(TRANSIT_TO_FRONT), any(), anyOrNull()))
+            .thenReturn(Binder())
         taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY)
         val homeTask = setUpHomeTask(SECOND_DISPLAY)
-        val task1 = setUpFreeformTask(SECOND_DISPLAY)
-        val task2 = setUpFreeformTask(SECOND_DISPLAY)
-        markTaskHidden(task1)
-        markTaskHidden(task2)
 
         controller.showDesktopApps(SECOND_DISPLAY, RemoteTransition(TestRemoteTransition()))
 
         val wct =
             getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
-        assertThat(wct.hierarchyOps).hasSize(3)
-        // Expect order to be from bottom: home, task1, task2 (no wallpaper intent)
-        wct.assertReorderAt(index = 0, homeTask)
-        wct.assertReorderAt(index = 1, task1)
-        wct.assertReorderAt(index = 2, task2)
+        wct.assertWithoutPendingIntent(desktopWallpaperIntent)
     }
 
     @Test
-    @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    @DisableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
     fun showDesktopApps_appsAlreadyVisible_bringsToFront_desktopWallpaperDisabled() {
         val homeTask = setUpHomeTask()
         val task1 = setUpFreeformTask()
@@ -705,7 +757,6 @@
     @Test
     @DisableFlags(
         Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
-        /** TODO: b/362720497 - re-enable when activation is implemented. */
         Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
     )
     fun showDesktopApps_onSecondaryDisplay_desktopWallpaperDisabled_shouldNotMoveLauncher() {
@@ -729,8 +780,8 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
     fun showDesktopApps_appsAlreadyVisible_bringsToFront_desktopWallpaperEnabled() {
-        whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(null)
         val task1 = setUpFreeformTask()
         val task2 = setUpFreeformTask()
         markTaskVisible(task1)
@@ -748,7 +799,10 @@
     }
 
     @Test
-    @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    @DisableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
     fun showDesktopApps_someAppsInvisible_reordersAll_desktopWallpaperDisabled() {
         val homeTask = setUpHomeTask()
         val task1 = setUpFreeformTask()
@@ -769,8 +823,8 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
-    fun showDesktopApps_someAppsInvisible_desktopWallpaperEnabled_reordersOnlyFreeformTasks() {
-        whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(null)
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun showDesktopApps_someAppsInvisible_reordersAll_desktopWallpaperEnabled() {
         val task1 = setUpFreeformTask()
         val task2 = setUpFreeformTask()
         markTaskHidden(task1)
@@ -787,26 +841,11 @@
         wct.assertReorderAt(index = 2, task2)
     }
 
-    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
-    fun showDesktopApps_someAppsInvisible_desktopWallpaperEnabled_reordersAll() {
-        val task1 = setUpFreeformTask()
-        val task2 = setUpFreeformTask()
-        markTaskHidden(task1)
-        markTaskVisible(task2)
-
-        controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition()))
-
-        val wct =
-            getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
-        assertThat(wct.hierarchyOps).hasSize(3)
-        // Expect order to be from bottom: wallpaper intent, task1, task2
-        wct.assertReorderAt(index = 0, wallpaperToken)
-        wct.assertReorderAt(index = 1, task1)
-        wct.assertReorderAt(index = 2, task2)
-    }
-
     @Test
-    @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    @DisableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
     fun showDesktopApps_noActiveTasks_reorderHomeToTop_desktopWallpaperDisabled() {
         val homeTask = setUpHomeTask()
 
@@ -820,9 +859,9 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
-    fun showDesktopApps_noActiveTasks_desktopWallpaperEnabled_addsDesktopWallpaper() {
-        whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(null)
-
+    fun showDesktopApps_noActiveTasks_addDesktopWallpaper_desktopWallpaperEnabled() {
+        whenever(transitions.startTransition(eq(TRANSIT_TO_FRONT), any(), anyOrNull()))
+            .thenReturn(Binder())
         controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition()))
 
         val wct =
@@ -831,17 +870,10 @@
     }
 
     @Test
-    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
-    fun showDesktopApps_noActiveTasks_desktopWallpaperEnabled_reordersDesktopWallpaper() {
-        controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition()))
-
-        val wct =
-            getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
-        wct.assertReorderAt(index = 0, wallpaperToken)
-    }
-
-    @Test
-    @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    @DisableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
     fun showDesktopApps_twoDisplays_bringsToFrontOnlyOneDisplay_desktopWallpaperDisabled() {
         taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY)
         val homeTaskDefaultDisplay = setUpHomeTask(DEFAULT_DISPLAY)
@@ -864,7 +896,8 @@
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
     fun showDesktopApps_twoDisplays_bringsToFrontOnlyOneDisplay_desktopWallpaperEnabled() {
-        whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(null)
+        whenever(transitions.startTransition(eq(TRANSIT_TO_FRONT), any(), anyOrNull()))
+            .thenReturn(Binder())
         taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY)
         val homeTaskDefaultDisplay = setUpHomeTask(DEFAULT_DISPLAY)
         val taskDefaultDisplay = setUpFreeformTask(DEFAULT_DISPLAY)
@@ -877,17 +910,63 @@
 
         val wct =
             getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
-        assertThat(wct.hierarchyOps).hasSize(3)
         // Move home to front
         wct.assertReorderAt(index = 0, homeTaskDefaultDisplay)
         // Add desktop wallpaper activity
         wct.assertPendingIntentAt(index = 1, desktopWallpaperIntent)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun showDesktopApps_twoDisplays_bringsToFrontOnlyOneDisplayTasks_desktopWallpaperEnabled_multiDesksDisabled() {
+        whenever(transitions.startTransition(eq(TRANSIT_TO_FRONT), any(), anyOrNull()))
+            .thenReturn(Binder())
+        taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY)
+        val homeTaskDefaultDisplay = setUpHomeTask(DEFAULT_DISPLAY)
+        val taskDefaultDisplay = setUpFreeformTask(DEFAULT_DISPLAY)
+        setUpHomeTask(SECOND_DISPLAY)
+        val taskSecondDisplay = setUpFreeformTask(SECOND_DISPLAY)
+        markTaskHidden(taskDefaultDisplay)
+        markTaskHidden(taskSecondDisplay)
+
+        controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition()))
+
+        val wct =
+            getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
         // Move freeform task to front
         wct.assertReorderAt(index = 2, taskDefaultDisplay)
     }
 
     @Test
-    @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    @EnableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
+    fun showDesktopApps_twoDisplays_bringsToFrontOnlyOneDisplayTasks_desktopWallpaperEnabled_multiDesksEnabled() {
+        whenever(transitions.startTransition(eq(TRANSIT_TO_FRONT), any(), anyOrNull()))
+            .thenReturn(Binder())
+        taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY)
+        val homeTaskDefaultDisplay = setUpHomeTask(DEFAULT_DISPLAY)
+        val taskDefaultDisplay = setUpFreeformTask(DEFAULT_DISPLAY)
+        setUpHomeTask(SECOND_DISPLAY)
+        val taskSecondDisplay = setUpFreeformTask(SECOND_DISPLAY)
+        markTaskHidden(taskDefaultDisplay)
+        markTaskHidden(taskSecondDisplay)
+
+        controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition()))
+
+        val wct =
+            getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
+        // Move desktop tasks to front
+        verify(desksOrganizer).activateDesk(wct, deskId = DEFAULT_DISPLAY)
+    }
+
+    @Test
+    @DisableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
     fun showDesktopApps_desktopWallpaperDisabled_dontReorderMinimizedTask() {
         val homeTask = setUpHomeTask()
         val freeformTask = setUpFreeformTask()
@@ -908,8 +987,9 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    /** TODO: b/362720497 - add multi-desk version when minimization is implemented. */
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
     fun showDesktopApps_desktopWallpaperEnabled_dontReorderMinimizedTask() {
-        whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(null)
         val homeTask = setUpHomeTask()
         val freeformTask = setUpFreeformTask()
         val minimizedTask = setUpFreeformTask()
@@ -1325,11 +1405,12 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
     fun moveToDesktop_tdaFullscreen_windowingModeSetToFreeform() {
         val task = setUpFullscreenTask()
         val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!!
         tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN
-        controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
         val wct = getLatestEnterDesktopWct()
         assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
             .isEqualTo(WINDOWING_MODE_FREEFORM)
@@ -1338,11 +1419,12 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
     fun moveRunningTaskToDesktop_tdaFreeform_windowingModeSetToUndefined() {
         val task = setUpFullscreenTask()
         val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!!
         tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FREEFORM
-        controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
         val wct = getLatestEnterDesktopWct()
         assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
             .isEqualTo(WINDOWING_MODE_UNDEFINED)
@@ -1351,11 +1433,78 @@
     }
 
     @Test
-    fun moveTaskToDesktop_nonExistentTask_doesNothing() {
-        controller.moveTaskToDesktop(999, transitionSource = UNKNOWN)
-        verifyEnterDesktopWCTNotExecuted()
-        verify(desktopModeEnterExitTransitionListener, times(0))
-            .onEnterDesktopModeTransitionStarted(anyInt())
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun moveRunningTaskToDesktop_movesTaskToDefaultDesk() {
+        val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY)
+
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
+
+        val wct = getLatestEnterDesktopWct()
+        verify(desksOrganizer).moveTaskToDesk(wct, deskId = 0, task)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun moveRunningTaskToDesktop_activatesDesk() {
+        val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY)
+
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
+
+        val wct = getLatestEnterDesktopWct()
+        verify(desksOrganizer).activateDesk(wct, deskId = 0)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun moveRunningTaskToDesktop_triggersEnterDesktopListener() {
+        val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY)
+
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
+
+        verify(desktopModeEnterExitTransitionListener)
+            .onEnterDesktopModeTransitionStarted(FREEFORM_ANIMATION_DURATION)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun moveTaskToDesk_nonDefaultDesk_movesTaskToDesk() {
+        val transition = Binder()
+        whenever(enterDesktopTransitionHandler.moveToDesktop(any(), any())).thenReturn(transition)
+        taskRepository.addDesk(DEFAULT_DISPLAY, deskId = 3)
+        val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY)
+        task.isVisible = true
+
+        controller.moveTaskToDesk(taskId = task.taskId, deskId = 3, transitionSource = UNKNOWN)
+
+        val wct = getLatestEnterDesktopWct()
+        verify(desksOrganizer).moveTaskToDesk(wct, deskId = 3, task)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun moveTaskToDesk_nonDefaultDesk_activatesDesk() {
+        val transition = Binder()
+        whenever(enterDesktopTransitionHandler.moveToDesktop(any(), any())).thenReturn(transition)
+        taskRepository.addDesk(DEFAULT_DISPLAY, deskId = 3)
+        val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY)
+        task.isVisible = true
+
+        controller.moveTaskToDesk(taskId = task.taskId, deskId = 3, transitionSource = UNKNOWN)
+
+        val wct = getLatestEnterDesktopWct()
+        verify(desksOrganizer).activateDesk(wct, deskId = 3)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun moveTaskToDesk_nonDefaultDesk_triggersEnterDesktopListener() {
+        taskRepository.addDesk(DEFAULT_DISPLAY, deskId = 3)
+        val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY)
+
+        controller.moveTaskToDesk(taskId = task.taskId, deskId = 3, transitionSource = UNKNOWN)
+
+        verify(desktopModeEnterExitTransitionListener)
+            .onEnterDesktopModeTransitionStarted(FREEFORM_ANIMATION_DURATION)
     }
 
     @Test
@@ -1365,7 +1514,7 @@
         whenever(shellTaskOrganizer.getRunningTaskInfo(anyInt())).thenReturn(null)
         whenever(recentTasksController.findTaskInBackground(anyInt())).thenReturn(task)
 
-        controller.moveTaskToDesktop(task.taskId, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
 
         with(getLatestEnterDesktopWct()) {
             assertLaunchTaskAt(0, task.taskId, WINDOWING_MODE_FREEFORM)
@@ -1375,12 +1524,11 @@
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
     fun moveTaskToDesktop_desktopWallpaperEnabled_nonRunningTask_launchesInFreeform() {
-        whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(null)
         val task = createTaskInfo(1)
         whenever(shellTaskOrganizer.getRunningTaskInfo(anyInt())).thenReturn(null)
         whenever(recentTasksController.findTaskInBackground(anyInt())).thenReturn(task)
 
-        controller.moveTaskToDesktop(task.taskId, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
 
         with(getLatestEnterDesktopWct()) {
             // Add desktop wallpaper activity
@@ -1392,7 +1540,8 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
-    fun moveRunningTaskToDesktop_topActivityTranslucentWithoutDisplay_taskIsMovedToDesktop() {
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun moveRunningTaskToDesktop_topActivityTranslucentWithoutDisplay_taskIsMovedToDesktop_multiDesksDisabled() {
         val task =
             setUpFullscreenTask().apply {
                 isActivityStackTransparent = true
@@ -1400,7 +1549,7 @@
                 numActivities = 1
             }
 
-        controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
         val wct = getLatestEnterDesktopWct()
         assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
             .isEqualTo(WINDOWING_MODE_FREEFORM)
@@ -1409,6 +1558,26 @@
     }
 
     @Test
+    @EnableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
+    fun moveRunningTaskToDesktop_topActivityTranslucentWithoutDisplay_taskIsMovedToDesktop_multiDesksEnabled() {
+        val task =
+            setUpFullscreenTask().apply {
+                isActivityStackTransparent = true
+                isTopActivityNoDisplay = true
+                numActivities = 1
+            }
+
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
+        val wct = getLatestEnterDesktopWct()
+        verify(desksOrganizer).moveTaskToDesk(wct, deskId = 0, task = task)
+        verify(desktopModeEnterExitTransitionListener)
+            .onEnterDesktopModeTransitionStarted(FREEFORM_ANIMATION_DURATION)
+    }
+
+    @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
     fun moveRunningTaskToDesktop_topActivityTranslucentWithDisplay_doesNothing() {
         val task =
@@ -1418,7 +1587,7 @@
                 numActivities = 1
             }
 
-        controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
         verifyEnterDesktopWCTNotExecuted()
         verify(desktopModeEnterExitTransitionListener, times(0))
             .onEnterDesktopModeTransitionStarted(FREEFORM_ANIMATION_DURATION)
@@ -1437,13 +1606,14 @@
                 isTopActivityNoDisplay = false
             }
 
-        controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
         verifyEnterDesktopWCTNotExecuted()
     }
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
-    fun moveRunningTaskToDesktop_systemUIActivityWithoutDisplay_doesNothing() {
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun moveRunningTaskToDesktop_systemUIActivityWithoutDisplay_doesNothing_multiDesksDisabled() {
         // Set task as systemUI package
         val systemUIPackageName =
             context.resources.getString(com.android.internal.R.string.config_systemUi)
@@ -1454,7 +1624,7 @@
                 isTopActivityNoDisplay = true
             }
 
-        controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
 
         val wct = getLatestEnterDesktopWct()
         assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
@@ -1473,7 +1643,7 @@
         mContext.setMockPackageManager(packageManager)
         whenever(packageManager.getHomeActivities(any())).thenReturn(homeActivities)
 
-        controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
         verifyEnterDesktopWCTNotExecuted()
     }
 
@@ -1489,7 +1659,7 @@
         mContext.setMockPackageManager(packageManager)
         whenever(packageManager.getHomeActivities(any())).thenReturn(homeActivities)
 
-        controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
 
         val wct = getLatestEnterDesktopWct()
         assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
@@ -1497,6 +1667,28 @@
     }
 
     @Test
+    @EnableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
+    fun moveRunningTaskToDesktop_systemUIActivityWithoutDisplay_doesNothing_multiDesksEnabled() {
+        // Set task as systemUI package
+        val systemUIPackageName =
+            context.resources.getString(com.android.internal.R.string.config_systemUi)
+        val baseComponent = ComponentName(systemUIPackageName, /* cls= */ "")
+        val task =
+            setUpFullscreenTask().apply {
+                baseActivity = baseComponent
+                isTopActivityNoDisplay = true
+            }
+
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
+
+        val wct = getLatestEnterDesktopWct()
+        verify(desksOrganizer).moveTaskToDesk(wct, deskId = 0, task = task)
+    }
+
+    @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
     fun moveBackgroundTaskToDesktop_remoteTransition_usesOneShotHandler() {
         val transitionHandlerArgCaptor = ArgumentCaptor.forClass(TransitionHandler::class.java)
@@ -1506,7 +1698,7 @@
         val task = createTaskInfo(1)
         whenever(shellTaskOrganizer.getRunningTaskInfo(anyInt())).thenReturn(null)
         whenever(recentTasksController.findTaskInBackground(anyInt())).thenReturn(task)
-        controller.moveTaskToDesktop(
+        controller.moveTaskToDefaultDeskAndActivate(
             taskId = task.taskId,
             transitionSource = UNKNOWN,
             remoteTransition = RemoteTransition(spy(TestRemoteTransition())),
@@ -1523,8 +1715,8 @@
         whenever(transitions.startTransition(anyInt(), any(), transitionHandlerArgCaptor.capture()))
             .thenReturn(Binder())
 
-        controller.moveRunningTaskToDesktop(
-            task = setUpFullscreenTask(),
+        controller.moveTaskToDefaultDeskAndActivate(
+            taskId = setUpFullscreenTask().taskId,
             transitionSource = UNKNOWN,
             remoteTransition = RemoteTransition(spy(TestRemoteTransition())),
         )
@@ -1535,14 +1727,20 @@
     }
 
     @Test
-    @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    @DisableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
     fun moveRunningTaskToDesktop_otherFreeformTasksBroughtToFront_desktopWallpaperDisabled() {
         val homeTask = setUpHomeTask()
         val freeformTask = setUpFreeformTask()
         val fullscreenTask = setUpFullscreenTask()
         markTaskHidden(freeformTask)
 
-        controller.moveRunningTaskToDesktop(fullscreenTask, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(
+            fullscreenTask.taskId,
+            transitionSource = UNKNOWN,
+        )
 
         with(getLatestEnterDesktopWct()) {
             // Operations should include home task, freeform task
@@ -1557,13 +1755,16 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
     fun moveRunningTaskToDesktop_otherFreeformTasksBroughtToFront_desktopWallpaperEnabled() {
-        whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(null)
         val freeformTask = setUpFreeformTask()
         val fullscreenTask = setUpFullscreenTask()
         markTaskHidden(freeformTask)
 
-        controller.moveRunningTaskToDesktop(fullscreenTask, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(
+            fullscreenTask.taskId,
+            transitionSource = UNKNOWN,
+        )
 
         with(getLatestEnterDesktopWct()) {
             // Operations should include wallpaper intent, freeform task, fullscreen task
@@ -1579,6 +1780,43 @@
     }
 
     @Test
+    @EnableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
+    fun moveRunningTaskToDesktop_desktopWallpaperEnabled_multiDesksEnabled() {
+        val freeformTask = setUpFreeformTask()
+        val fullscreenTask = setUpFullscreenTask()
+        markTaskHidden(freeformTask)
+
+        controller.moveTaskToDefaultDeskAndActivate(
+            fullscreenTask.taskId,
+            transitionSource = UNKNOWN,
+        )
+
+        val wct = getLatestEnterDesktopWct()
+        wct.assertPendingIntentAt(index = 0, desktopWallpaperIntent)
+        verify(desksOrganizer).moveTaskToDesk(wct, deskId = 0, fullscreenTask)
+        verify(desksOrganizer).activateDesk(wct, deskId = 0)
+        verify(desktopModeEnterExitTransitionListener)
+            .onEnterDesktopModeTransitionStarted(FREEFORM_ANIMATION_DURATION)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun moveRunningTaskToDesktop_activatesDesk_desktopWallpaperEnabled_multiDesksDisabled() {
+        val fullscreenTask = setUpFullscreenTask()
+
+        controller.moveTaskToDefaultDeskAndActivate(
+            fullscreenTask.taskId,
+            transitionSource = UNKNOWN,
+        )
+
+        assertThat(taskRepository.getActiveDeskId(DEFAULT_DISPLAY)).isEqualTo(DEFAULT_DISPLAY)
+    }
+
+    @Test
     fun moveRunningTaskToDesktop_onlyFreeformTasksFromCurrentDisplayBroughtToFront() {
         setUpHomeTask(displayId = DEFAULT_DISPLAY)
         val freeformTaskDefault = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
@@ -1590,7 +1828,10 @@
         val freeformTaskSecond = setUpFreeformTask(displayId = SECOND_DISPLAY)
         markTaskHidden(freeformTaskSecond)
 
-        controller.moveRunningTaskToDesktop(fullscreenTaskDefault, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(
+            fullscreenTaskDefault.taskId,
+            transitionSource = UNKNOWN,
+        )
 
         with(getLatestEnterDesktopWct()) {
             // Check that hierarchy operations do not include tasks from second display
@@ -1604,9 +1845,10 @@
     }
 
     @Test
-    fun moveRunningTaskToDesktop_splitTaskExitsSplit() {
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun moveRunningTaskToDesktop_splitTaskExitsSplit_multiDesksDisabled() {
         val task = setUpSplitScreenTask()
-        controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
         val wct = getLatestEnterDesktopWct()
         assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
             .isEqualTo(WINDOWING_MODE_FREEFORM)
@@ -1621,12 +1863,27 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun moveRunningTaskToDesktop_splitTaskExitsSplit_multiDesksEnabled() {
+        val task = setUpSplitScreenTask()
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
+        val wct = getLatestEnterDesktopWct()
+        verify(desksOrganizer).moveTaskToDesk(wct, deskId = 0, task)
+        verify(desktopModeEnterExitTransitionListener)
+            .onEnterDesktopModeTransitionStarted(FREEFORM_ANIMATION_DURATION)
+        verify(splitScreenController)
+            .prepareExitSplitScreen(
+                any(),
+                anyInt(),
+                eq(SplitScreenController.EXIT_REASON_DESKTOP_MODE),
+            )
+    }
+
+    @Test
     fun moveRunningTaskToDesktop_fullscreenTaskDoesNotExitSplit() {
         val task = setUpFullscreenTask()
-        controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(task.taskId, transitionSource = UNKNOWN)
         val wct = getLatestEnterDesktopWct()
-        assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
-            .isEqualTo(WINDOWING_MODE_FREEFORM)
         verify(desktopModeEnterExitTransitionListener)
             .onEnterDesktopModeTransitionStarted(FREEFORM_ANIMATION_DURATION)
         verify(splitScreenController, never())
@@ -1638,13 +1895,16 @@
     }
 
     @Test
-    @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    @DisableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
     fun moveRunningTaskToDesktop_desktopWallpaperDisabled_bringsTasksOver_dontShowBackTask() {
         val freeformTasks = (1..MAX_TASK_LIMIT).map { _ -> setUpFreeformTask() }
         val newTask = setUpFullscreenTask()
         val homeTask = setUpHomeTask()
 
-        controller.moveRunningTaskToDesktop(newTask, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(newTask.taskId, transitionSource = UNKNOWN)
 
         val wct = getLatestEnterDesktopWct()
         verify(desktopModeEnterExitTransitionListener)
@@ -1660,13 +1920,13 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
     fun moveRunningTaskToDesktop_desktopWallpaperEnabled_bringsTasksOverLimit_dontShowBackTask() {
-        whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(null)
         val freeformTasks = (1..MAX_TASK_LIMIT).map { _ -> setUpFreeformTask() }
         val newTask = setUpFullscreenTask()
         val homeTask = setUpHomeTask()
 
-        controller.moveRunningTaskToDesktop(newTask, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(newTask.taskId, transitionSource = UNKNOWN)
 
         val wct = getLatestEnterDesktopWct()
         verify(desktopModeEnterExitTransitionListener)
@@ -2682,7 +2942,6 @@
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
     fun handleRequest_fullscreenTask_noTasks_enforceDesktop_freeformDisplay_returnFreeformWCT() {
-        whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(null)
         whenever(DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context)).thenReturn(true)
         val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!!
         tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FREEFORM
@@ -2814,7 +3073,6 @@
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
     fun handleRequest_freeformTask_desktopWallpaperEnabled_freeformNotVisible_reorderedToTop() {
-        whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(null)
         val freeformTask1 = setUpFreeformTask()
         val freeformTask2 = createFreeformTask()
 
@@ -2849,9 +3107,7 @@
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
     fun handleRequest_freeformTask_desktopWallpaperEnabled_noOtherTasks_reorderedToTop() {
-        whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(null)
         val task = createFreeformTask()
-
         val result = controller.handleRequest(Binder(), createTransition(task))
 
         assertNotNull(result, "Should handle request")
@@ -2879,7 +3135,6 @@
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
     fun handleRequest_freeformTask_dskWallpaperEnabled_freeformOnOtherDisplayOnly_reorderedToTop() {
-        whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(null)
         val taskDefaultDisplay = createFreeformTask(displayId = DEFAULT_DISPLAY)
         // Second display task
         createFreeformTask(displayId = SECOND_DISPLAY)
@@ -3492,7 +3747,8 @@
     }
 
     @Test
-    fun moveFocusedTaskToDesktop_fullscreenTaskIsMovedToDesktop() {
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun moveFocusedTaskToDesktop_fullscreenTaskIsMovedToDesktop_multiDesksDisabled() {
         val task1 = setUpFullscreenTask()
         val task2 = setUpFullscreenTask()
         val task3 = setUpFullscreenTask()
@@ -3509,7 +3765,25 @@
     }
 
     @Test
-    fun moveFocusedTaskToDesktop_splitScreenTaskIsMovedToDesktop() {
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun moveFocusedTaskToDesktop_fullscreenTaskIsMovedToDesktop_multiDesksEnabled() {
+        val task1 = setUpFullscreenTask()
+        val task2 = setUpFullscreenTask()
+        val task3 = setUpFullscreenTask()
+
+        task1.isFocused = true
+        task2.isFocused = false
+        task3.isFocused = false
+
+        controller.moveFocusedTaskToDesktop(DEFAULT_DISPLAY, transitionSource = UNKNOWN)
+
+        val wct = getLatestEnterDesktopWct()
+        verify(desksOrganizer).moveTaskToDesk(wct, deskId = 0, task1)
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun moveFocusedTaskToDesktop_splitScreenTaskIsMovedToDesktop_multiDesksDisabled() {
         val task1 = setUpSplitScreenTask()
         val task2 = setUpFullscreenTask()
         val task3 = setUpFullscreenTask()
@@ -3536,6 +3810,33 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun moveFocusedTaskToDesktop_splitScreenTaskIsMovedToDesktop_multiDesksEnabled() {
+        val task1 = setUpSplitScreenTask()
+        val task2 = setUpFullscreenTask()
+        val task3 = setUpFullscreenTask()
+        val task4 = setUpSplitScreenTask()
+
+        task1.isFocused = true
+        task2.isFocused = false
+        task3.isFocused = false
+        task4.isFocused = true
+
+        task4.parentTaskId = task1.taskId
+
+        controller.moveFocusedTaskToDesktop(DEFAULT_DISPLAY, transitionSource = UNKNOWN)
+
+        val wct = getLatestEnterDesktopWct()
+        verify(desksOrganizer).moveTaskToDesk(wct, deskId = 0, task4)
+        verify(splitScreenController)
+            .prepareExitSplitScreen(
+                any(),
+                anyInt(),
+                eq(SplitScreenController.EXIT_REASON_DESKTOP_MODE),
+            )
+    }
+
+    @Test
     fun moveFocusedTaskToFullscreen() {
         val task1 = setUpFreeformTask()
         val task2 = setUpFreeformTask()
@@ -3684,6 +3985,59 @@
     }
 
     @Test
+    @EnableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
+    fun activateDesk_multipleDesks_addsPendingTransition() {
+        val deskId = 0
+        val transition = Binder()
+        val deskChange = mock(TransitionInfo.Change::class.java)
+        whenever(transitions.startTransition(eq(TRANSIT_TO_FRONT), any(), anyOrNull()))
+            .thenReturn(transition)
+        whenever(desksOrganizer.isDeskActiveAtEnd(deskChange, deskId)).thenReturn(true)
+        // Make desk inactive by activating another desk.
+        taskRepository.addDesk(DEFAULT_DISPLAY, deskId = 1)
+        taskRepository.setActiveDesk(DEFAULT_DISPLAY, deskId = 1)
+
+        controller.activateDesk(deskId, RemoteTransition(TestRemoteTransition()))
+
+        verify(desksTransitionsObserver)
+            .addPendingTransition(
+                argThat {
+                    this is DeskTransition.ActivateDesk &&
+                        this.token == transition &&
+                        this.deskId == 0
+                }
+            )
+    }
+
+    @Test
+    @EnableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
+    fun moveTaskToDesk_multipleDesks_addsPendingTransition() {
+        val transition = Binder()
+        whenever(enterDesktopTransitionHandler.moveToDesktop(any(), any())).thenReturn(transition)
+        taskRepository.addDesk(DEFAULT_DISPLAY, deskId = 3)
+        val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY)
+        task.isVisible = true
+
+        controller.moveTaskToDesk(taskId = task.taskId, deskId = 3, transitionSource = UNKNOWN)
+
+        verify(desksTransitionsObserver)
+            .addPendingTransition(
+                argThat {
+                    this is DeskTransition.ActiveDeskWithTask &&
+                        this.token == transition &&
+                        this.deskId == 3 &&
+                        this.enterTaskId == task.taskId
+                }
+            )
+    }
+
+    @Test
     @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS)
     fun dragToDesktop_landscapeDevice_resizable_undefinedOrientation_defaultLandscapeBounds() {
         val spyController = spy(controller)
@@ -5054,7 +5408,11 @@
             .thenReturn(ExitResult.Exit(exitingTask = 5, runOnTransitionStart = runOnStartTransit))
         whenever(enterDesktopTransitionHandler.moveToDesktop(wct, UNKNOWN)).thenReturn(transition)
 
-        controller.moveTaskToDesktop(taskId = task.taskId, wct = wct, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(
+            taskId = task.taskId,
+            wct = wct,
+            transitionSource = UNKNOWN,
+        )
 
         verify(mMockDesktopImmersiveController)
             .exitImmersiveIfApplicable(eq(wct), eq(task.displayId), eq(task.taskId), any())
@@ -5078,7 +5436,11 @@
             .thenReturn(ExitResult.Exit(exitingTask = 5, runOnTransitionStart = runOnStartTransit))
         whenever(enterDesktopTransitionHandler.moveToDesktop(wct, UNKNOWN)).thenReturn(transition)
 
-        controller.moveTaskToDesktop(taskId = task.taskId, wct = wct, transitionSource = UNKNOWN)
+        controller.moveTaskToDefaultDeskAndActivate(
+            taskId = task.taskId,
+            wct = wct,
+            transitionSource = UNKNOWN,
+        )
 
         verify(mMockDesktopImmersiveController)
             .exitImmersiveIfApplicable(eq(wct), eq(task.displayId), eq(task.taskId), any())
@@ -5660,6 +6022,29 @@
         .isGreaterThan(index)
 }
 
+private fun WindowContainerTransaction.assertHop(
+    predicate: (WindowContainerTransaction.HierarchyOp) -> Boolean
+) {
+    assertThat(hierarchyOps.any(predicate)).isTrue()
+}
+
+private fun WindowContainerTransaction.assertWithoutHop(
+    predicate: (WindowContainerTransaction.HierarchyOp) -> Boolean
+) {
+    assertThat(hierarchyOps.none(predicate)).isTrue()
+}
+
+private fun WindowContainerTransaction.assertReorder(
+    task: RunningTaskInfo,
+    toTop: Boolean? = null,
+) {
+    assertHop { hop ->
+        hop.type == HIERARCHY_OP_TYPE_REORDER &&
+            (toTop == null || hop.toTop == toTop) &&
+            hop.container == task.token.asBinder()
+    }
+}
+
 private fun WindowContainerTransaction.assertReorderAt(
     index: Int,
     task: RunningTaskInfo,
@@ -5721,6 +6106,20 @@
     assertThat(op.container).isEqualTo(token.asBinder())
 }
 
+private fun WindowContainerTransaction.assertPendingIntent(intent: Intent) {
+    assertHop { hop ->
+        hop.type == HIERARCHY_OP_TYPE_PENDING_INTENT &&
+            hop.pendingIntent?.intent?.component == intent.component
+    }
+}
+
+private fun WindowContainerTransaction.assertWithoutPendingIntent(intent: Intent) {
+    assertWithoutHop { hop ->
+        hop.type == HIERARCHY_OP_TYPE_PENDING_INTENT &&
+            hop.pendingIntent?.intent?.component == intent.component
+    }
+}
+
 private fun WindowContainerTransaction.assertPendingIntentAt(index: Int, intent: Intent) {
     assertIndexInBounds(index)
     val op = hierarchyOps[index]
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
index 33dc1aa..25246d9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
@@ -477,6 +477,40 @@
     }
 
     @Test
+    fun mergeAnimation_endTransition_springHandler_noStartHomeChange_doesntCrash() {
+        whenever(dragAnimator.computeCurrentVelocity()).thenReturn(PointF())
+        val playingFinishTransaction = mock<SurfaceControl.Transaction>()
+        val mergedStartTransaction = mock<SurfaceControl.Transaction>()
+        val mergedFinishTransaction = mock<SurfaceControl.Transaction>()
+        val finishCallback = mock<Transitions.TransitionFinishCallback>()
+        val task = createTask()
+        val startTransition = startDrag(
+            springHandler, task, finishTransaction = playingFinishTransaction, homeChange = null)
+        springHandler.onTaskResizeAnimationListener = mock()
+
+        springHandler.mergeAnimation(
+            transition = mock<IBinder>(),
+            info =
+            createTransitionInfo(
+                type = TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP,
+                draggedTask = task,
+            ),
+            startT = mergedStartTransaction,
+            finishT = mergedFinishTransaction,
+            mergeTarget = startTransition,
+            finishCallback = finishCallback,
+        )
+
+        // Should show dragged task layer in start and finish transaction
+        verify(mergedStartTransaction).show(draggedTaskLeash)
+        verify(playingFinishTransaction).show(draggedTaskLeash)
+        // Should update the dragged task layer
+        verify(mergedStartTransaction).setLayer(eq(draggedTaskLeash), anyInt())
+        // Should merge animation
+        verify(finishCallback).onTransitionFinished(null)
+    }
+
+    @Test
     fun propertyValue_returnsSystemPropertyValue() {
         val name = "property_name"
         val value = 10f
@@ -589,6 +623,7 @@
         handler: DragToDesktopTransitionHandler,
         task: RunningTaskInfo = createTask(),
         finishTransaction: SurfaceControl.Transaction = mock(),
+        homeChange: TransitionInfo.Change? = createHomeChange(),
     ): IBinder {
         whenever(dragAnimator.position).thenReturn(PointF())
         // Simulate transition is started and is ready to animate.
@@ -599,6 +634,7 @@
                 createTransitionInfo(
                     type = TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP,
                     draggedTask = task,
+                    homeChange = homeChange,
                 ),
             startTransaction = mock(),
             finishTransaction = finishTransaction,
@@ -684,16 +720,12 @@
             }
     }
 
-    private fun createTransitionInfo(type: Int, draggedTask: RunningTaskInfo) =
+    private fun createTransitionInfo(
+        type: Int,
+        draggedTask: RunningTaskInfo,
+        homeChange: TransitionInfo.Change? = createHomeChange()) =
         TransitionInfo(type, /* flags= */ 0).apply {
-            addChange( // Home.
-                TransitionInfo.Change(mock(), homeTaskLeash).apply {
-                    parent = null
-                    taskInfo =
-                        TestRunningTaskInfoBuilder().setActivityType(ACTIVITY_TYPE_HOME).build()
-                    flags = flags or FLAG_IS_WALLPAPER
-                }
-            )
+            homeChange?.let { addChange(it) }
             addChange( // Dragged Task.
                 TransitionInfo.Change(mock(), draggedTaskLeash).apply {
                     parent = null
@@ -709,6 +741,12 @@
             )
         }
 
+    private fun createHomeChange() = TransitionInfo.Change(mock(), homeTaskLeash).apply {
+        parent = null
+        taskInfo = TestRunningTaskInfoBuilder().setActivityType(ACTIVITY_TYPE_HOME).build()
+        flags = flags or FLAG_IS_WALLPAPER
+    }
+
     private fun systemPropertiesKey(name: String) =
         "${SpringDragToDesktopTransitionHandler.SYSTEM_PROPERTIES_GROUP}.$name"
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserverTest.kt
index bfbaa84..9f09e3f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserverTest.kt
@@ -21,20 +21,26 @@
 import android.testing.AndroidTestingRunner
 import android.view.Display.DEFAULT_DISPLAY
 import android.view.WindowManager.TRANSIT_CLOSE
+import android.view.WindowManager.TRANSIT_TO_FRONT
 import android.window.TransitionInfo
+import android.window.TransitionInfo.Change
 import androidx.test.filters.SmallTest
 import com.android.window.flags.Flags
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.TestShellExecutor
 import com.android.wm.shell.desktopmode.DesktopRepository
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
 import com.android.wm.shell.desktopmode.DesktopUserRepositories
 import com.android.wm.shell.sysui.ShellInit
 import com.google.common.truth.Truth.assertThat
+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.runner.RunWith
 import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 
 /**
  * Tests for [DesksTransitionObserver].
@@ -47,6 +53,9 @@
 
     @JvmField @Rule val setFlagsRule = SetFlagsRule()
 
+    private val mockDesksOrganizer = mock<DesksOrganizer>()
+    val testScope = TestScope()
+
     private lateinit var desktopUserRepositories: DesktopUserRepositories
     private lateinit var observer: DesksTransitionObserver
 
@@ -62,10 +71,10 @@
                 /* shellController= */ mock(),
                 /* persistentRepository= */ mock(),
                 /* repositoryInitializer= */ mock(),
-                /* mainCoroutineScope= */ mock(),
+                testScope,
                 /* userManager= */ mock(),
             )
-        observer = DesksTransitionObserver(desktopUserRepositories)
+        observer = DesksTransitionObserver(desktopUserRepositories, mockDesksOrganizer)
     }
 
     @Test
@@ -121,4 +130,51 @@
 
         assertThat(removeListener.lastDeskRemoved).isEqualTo(5)
     }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun onTransitionReady_activateDesk_updatesRepository() {
+        val transition = Binder()
+        val change = Change(mock(), mock())
+        whenever(mockDesksOrganizer.isDeskActiveAtEnd(change, deskId = 5)).thenReturn(true)
+        val activateTransition =
+            DeskTransition.ActivateDesk(transition, displayId = DEFAULT_DISPLAY, deskId = 5)
+        repository.addDesk(DEFAULT_DISPLAY, deskId = 5)
+
+        observer.addPendingTransition(activateTransition)
+        observer.onTransitionReady(
+            transition = transition,
+            info = TransitionInfo(TRANSIT_TO_FRONT, /* flags= */ 0).apply { addChange(change) },
+        )
+
+        assertThat(repository.getActiveDeskId(DEFAULT_DISPLAY)).isEqualTo(5)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun onTransitionReady_activateDeskWithTask_updatesRepository() =
+        testScope.runTest {
+            val deskId = 5
+            val task = createFreeformTask(DEFAULT_DISPLAY).apply { isVisibleRequested = true }
+            val transition = Binder()
+            val change = Change(mock(), mock()).apply { taskInfo = task }
+            whenever(mockDesksOrganizer.getDeskAtEnd(change)).thenReturn(deskId)
+            val activateTransition =
+                DeskTransition.ActiveDeskWithTask(
+                    transition,
+                    displayId = DEFAULT_DISPLAY,
+                    deskId = deskId,
+                    enterTaskId = task.taskId,
+                )
+            repository.addDesk(DEFAULT_DISPLAY, deskId = deskId)
+
+            observer.addPendingTransition(activateTransition)
+            observer.onTransitionReady(
+                transition = transition,
+                info = TransitionInfo(TRANSIT_TO_FRONT, /* flags= */ 0).apply { addChange(change) },
+            )
+
+            assertThat(repository.getActiveDeskId(DEFAULT_DISPLAY)).isEqualTo(deskId)
+            assertThat(repository.getActiveTaskIdsInDesk(deskId)).contains(task.taskId)
+        }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt
index a07203d..4d4b153 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt
@@ -15,9 +15,11 @@
  */
 package com.android.wm.shell.desktopmode.multidesks
 
+import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
 import android.testing.AndroidTestingRunner
 import android.view.Display
 import android.view.SurfaceControl
+import android.view.WindowManager.TRANSIT_TO_FRONT
 import android.window.TransitionInfo
 import android.window.WindowContainerTransaction
 import android.window.WindowContainerTransaction.HierarchyOp
@@ -216,6 +218,13 @@
                 }
             )
             .isTrue()
+        assertThat(
+                wct.changes.any { change ->
+                    change.key == desktopTask.token.asBinder() &&
+                        change.value.windowingMode == WINDOWING_MODE_UNDEFINED
+                }
+            )
+            .isTrue()
     }
 
     @Test
@@ -244,6 +253,26 @@
         assertThat(endDesk).isEqualTo(freeformRoot.taskId)
     }
 
+    @Test
+    fun testIsDeskActiveAtEnd() {
+        organizer.createDesk(Display.DEFAULT_DISPLAY, FakeOnCreateCallback())
+        val freeformRoot = createFreeformTask().apply { parentTaskId = -1 }
+        freeformRoot.isVisibleRequested = true
+        organizer.onTaskAppeared(freeformRoot, SurfaceControl())
+
+        val isActive =
+            organizer.isDeskActiveAtEnd(
+                change =
+                    TransitionInfo.Change(freeformRoot.token, SurfaceControl()).apply {
+                        taskInfo = freeformRoot
+                        mode = TRANSIT_TO_FRONT
+                    },
+                deskId = freeformRoot.taskId,
+            )
+
+        assertThat(isActive).isTrue()
+    }
+
     private class FakeOnCreateCallback : DesksOrganizer.OnCreateCallback {
         var deskId: Int? = null
         val created: Boolean
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 1b1a5a9..06dcd88 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
@@ -47,6 +47,7 @@
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.bubbles.bar.BubbleBarDragListener;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.sysui.ShellCommandHandler;
@@ -60,6 +61,8 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import dagger.Lazy;
+
 /**
  * Tests for the drag and drop controller.
  */
@@ -91,6 +94,8 @@
     private Transitions mTransitions;
     @Mock
     private GlobalDragListener mGlobalDragListener;
+    @Mock
+    private Lazy<BubbleBarDragListener> mBubbleBarDragControllerLazy;
 
     private DragAndDropController mController;
 
@@ -99,7 +104,8 @@
         MockitoAnnotations.initMocks(this);
         mController = new DragAndDropController(mContext, mShellInit, mShellController,
                 mShellCommandHandler, mShellTaskOrganizer, mDisplayController, mUiEventLogger,
-                mIconProvider, mGlobalDragListener, mTransitions, mMainExecutor);
+                mIconProvider, mGlobalDragListener, mTransitions, mBubbleBarDragControllerLazy,
+                mMainExecutor);
         mController.onInit();
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java
index bd857c7..8e0381e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java
@@ -26,7 +26,6 @@
 import static org.mockito.kotlin.VerificationKt.times;
 import static org.mockito.kotlin.VerificationKt.verify;
 
-import android.app.TaskInfo;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Matrix;
@@ -39,12 +38,9 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.pip.PipBoundsState;
-import com.android.wm.shell.desktopmode.DesktopRepository;
-import com.android.wm.shell.desktopmode.DesktopUserRepositories;
-import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider;
+import com.android.wm.shell.common.pip.PipDesktopState;
 import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
 import com.android.wm.shell.pip2.animation.PipAlphaAnimator;
@@ -55,11 +51,8 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
-import java.util.Optional;
-
 /**
  * Unit test against {@link PipScheduler}
  */
@@ -77,16 +70,13 @@
     @Mock private PipBoundsState mMockPipBoundsState;
     @Mock private ShellExecutor mMockMainExecutor;
     @Mock private PipTransitionState mMockPipTransitionState;
+    @Mock private PipDesktopState mMockPipDesktopState;
     @Mock private PipTransitionController mMockPipTransitionController;
     @Mock private Runnable mMockUpdateMovementBoundsRunnable;
     @Mock private WindowContainerToken mMockPipTaskToken;
     @Mock private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mMockFactory;
     @Mock private SurfaceControl.Transaction mMockTransaction;
     @Mock private PipAlphaAnimator mMockAlphaAnimator;
-    @Mock private DesktopUserRepositories mMockDesktopUserRepositories;
-    @Mock private DesktopWallpaperActivityTokenProvider mMockDesktopWallpaperActivityTokenProvider;
-    @Mock private RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
-
     @Captor private ArgumentCaptor<Runnable> mRunnableArgumentCaptor;
     @Captor private ArgumentCaptor<WindowContainerTransaction> mWctArgumentCaptor;
 
@@ -101,14 +91,9 @@
         when(mMockFactory.getTransaction()).thenReturn(mMockTransaction);
         when(mMockTransaction.setMatrix(any(SurfaceControl.class), any(Matrix.class), any()))
                 .thenReturn(mMockTransaction);
-        when(mMockDesktopUserRepositories.getCurrent())
-                .thenReturn(Mockito.mock(DesktopRepository.class));
-        when(mMockPipTransitionState.getPipTaskInfo()).thenReturn(Mockito.mock(TaskInfo.class));
 
         mPipScheduler = new PipScheduler(mMockContext, mMockPipBoundsState, mMockMainExecutor,
-                mMockPipTransitionState, Optional.of(mMockDesktopUserRepositories),
-                Optional.of(mMockDesktopWallpaperActivityTokenProvider),
-                mRootTaskDisplayAreaOrganizer);
+                mMockPipTransitionState, mMockPipDesktopState);
         mPipScheduler.setPipTransitionController(mMockPipTransitionController);
         mPipScheduler.setSurfaceControlTransactionFactory(mMockFactory);
         mPipScheduler.setPipAlphaAnimatorSupplier((context, leash, startTx, finishTx, direction) ->
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java
index 3923a1e..1b462c3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java
@@ -165,6 +165,25 @@
     }
 
     @Test
+    public void onTaskInfoChanged_withNullPipParams_doNothing() {
+        mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
+                mMockPipTransitionState, mMockPipScheduler, mMockPipBoundsState,
+                mMockPipBoundsAlgorithm, mMockShellExecutor);
+        mPipTaskListener.addParamsChangedListener(mMockPipParamsChangedCallback);
+        Rational aspectRatio = new Rational(4, 3);
+        when(mMockPipBoundsState.getAspectRatio()).thenReturn(aspectRatio.toFloat());
+        String action1 = "action1";
+        mPipTaskListener.onTaskInfoChanged(getTaskInfo(aspectRatio, action1));
+
+        clearInvocations(mMockPipParamsChangedCallback);
+        mPipTaskListener.onTaskInfoChanged(new ActivityManager.RunningTaskInfo());
+
+        verifyZeroInteractions(mMockPipParamsChangedCallback);
+        verify(mMockPipTransitionState, times(0))
+                .setOnIdlePipTransitionStateRunnable(any(Runnable.class));
+    }
+
+    @Test
     public void onTaskInfoChanged_withActionsChanged_callbackActionsChanged() {
         mPipTaskListener = new PipTaskListener(mMockContext, mMockShellTaskOrganizer,
                 mMockPipTransitionState, mMockPipScheduler, mMockPipBoundsState,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/DragZoneFactoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/DragZoneFactoryTest.kt
new file mode 100644
index 0000000..e28d6ff
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/bubbles/DragZoneFactoryTest.kt
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.bubbles
+
+import android.graphics.Insets
+import android.graphics.Rect
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.shared.bubbles.DragZoneFactory.DesktopWindowModeChecker
+import com.android.wm.shell.shared.bubbles.DragZoneFactory.SplitScreenModeChecker
+import com.android.wm.shell.shared.bubbles.DragZoneFactory.SplitScreenModeChecker.SplitScreenMode
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+/** Unit tests for [DragZoneFactory]. */
+class DragZoneFactoryTest {
+
+    private lateinit var dragZoneFactory: DragZoneFactory
+    private val tabletPortrait =
+        DeviceConfig(
+            windowBounds = Rect(0, 0, 1000, 2000),
+            isLargeScreen = true,
+            isSmallTablet = false,
+            isLandscape = false,
+            isRtl = false,
+            insets = Insets.of(0, 0, 0, 0)
+        )
+    private val tabletLandscape =
+        tabletPortrait.copy(windowBounds = Rect(0, 0, 2000, 1000), isLandscape = true)
+    private val foldablePortrait =
+        tabletPortrait.copy(windowBounds = Rect(0, 0, 800, 900), isSmallTablet = true)
+    private val foldableLandscape =
+        foldablePortrait.copy(windowBounds = Rect(0, 0, 900, 800), isLandscape = true)
+    private val splitScreenModeChecker = SplitScreenModeChecker { SplitScreenMode.NONE }
+    private var isDesktopWindowModeSupported = true
+    private val desktopWindowModeChecker = DesktopWindowModeChecker { isDesktopWindowModeSupported }
+
+    @Test
+    fun dragZonesForBubbleBar_tablet() {
+        dragZoneFactory =
+            DragZoneFactory(tabletPortrait, splitScreenModeChecker, desktopWindowModeChecker)
+        val dragZones =
+            dragZoneFactory.createSortedDragZones(DraggedObject.BubbleBar(BubbleBarLocation.LEFT))
+        val expectedZones: List<Class<out DragZone>> =
+            listOf(
+                DragZone.Dismiss::class.java,
+                DragZone.Bubble::class.java,
+                DragZone.Bubble::class.java,
+            )
+        dragZones.zip(expectedZones).forEach { (zone, expectedType) ->
+            assertThat(zone).isInstanceOf(expectedType)
+        }
+    }
+
+    @Test
+    fun dragZonesForBubble_tablet_portrait() {
+        dragZoneFactory =
+            DragZoneFactory(tabletPortrait, splitScreenModeChecker, desktopWindowModeChecker)
+        val dragZones =
+            dragZoneFactory.createSortedDragZones(DraggedObject.Bubble(BubbleBarLocation.LEFT))
+        val expectedZones: List<Class<out DragZone>> =
+            listOf(
+                DragZone.Dismiss::class.java,
+                DragZone.Bubble.Left::class.java,
+                DragZone.Bubble.Right::class.java,
+                DragZone.FullScreen::class.java,
+                DragZone.DesktopWindow::class.java,
+                DragZone.Split.Top::class.java,
+                DragZone.Split.Bottom::class.java,
+            )
+        dragZones.zip(expectedZones).forEach { (zone, expectedType) ->
+            assertThat(zone).isInstanceOf(expectedType)
+        }
+    }
+
+    @Test
+    fun dragZonesForBubble_tablet_landscape() {
+        dragZoneFactory = DragZoneFactory(tabletLandscape, splitScreenModeChecker, desktopWindowModeChecker)
+        val dragZones =
+            dragZoneFactory.createSortedDragZones(DraggedObject.Bubble(BubbleBarLocation.LEFT))
+        val expectedZones: List<Class<out DragZone>> =
+            listOf(
+                DragZone.Dismiss::class.java,
+                DragZone.Bubble.Left::class.java,
+                DragZone.Bubble.Right::class.java,
+                DragZone.FullScreen::class.java,
+                DragZone.DesktopWindow::class.java,
+                DragZone.Split.Left::class.java,
+                DragZone.Split.Right::class.java,
+            )
+        dragZones.zip(expectedZones).forEach { (zone, expectedType) ->
+            assertThat(zone).isInstanceOf(expectedType)
+        }
+    }
+
+    @Test
+    fun dragZonesForBubble_foldable_portrait() {
+        dragZoneFactory = DragZoneFactory(foldablePortrait, splitScreenModeChecker, desktopWindowModeChecker)
+        val dragZones =
+            dragZoneFactory.createSortedDragZones(DraggedObject.Bubble(BubbleBarLocation.LEFT))
+        val expectedZones: List<Class<out DragZone>> =
+            listOf(
+                DragZone.Dismiss::class.java,
+                DragZone.Bubble.Left::class.java,
+                DragZone.Bubble.Right::class.java,
+                DragZone.FullScreen::class.java,
+                DragZone.Split.Left::class.java,
+                DragZone.Split.Right::class.java,
+            )
+        dragZones.zip(expectedZones).forEach { (zone, expectedType) ->
+            assertThat(zone).isInstanceOf(expectedType)
+        }
+    }
+
+    @Test
+    fun dragZonesForBubble_foldable_landscape() {
+        dragZoneFactory = DragZoneFactory(foldableLandscape, splitScreenModeChecker, desktopWindowModeChecker)
+        val dragZones =
+            dragZoneFactory.createSortedDragZones(DraggedObject.Bubble(BubbleBarLocation.LEFT))
+        val expectedZones: List<Class<out DragZone>> =
+            listOf(
+                DragZone.Dismiss::class.java,
+                DragZone.Bubble.Left::class.java,
+                DragZone.Bubble.Right::class.java,
+                DragZone.FullScreen::class.java,
+                DragZone.Split.Top::class.java,
+                DragZone.Split.Bottom::class.java,
+            )
+        dragZones.zip(expectedZones).forEach { (zone, expectedType) ->
+            assertThat(zone).isInstanceOf(expectedType)
+        }
+    }
+
+    @Test
+    fun dragZonesForExpandedView_tablet_portrait() {
+        dragZoneFactory =
+            DragZoneFactory(tabletPortrait, splitScreenModeChecker, desktopWindowModeChecker)
+        val dragZones =
+            dragZoneFactory.createSortedDragZones(
+                DraggedObject.ExpandedView(BubbleBarLocation.LEFT)
+            )
+        val expectedZones: List<Class<out DragZone>> =
+            listOf(
+                DragZone.Dismiss::class.java,
+                DragZone.FullScreen::class.java,
+                DragZone.DesktopWindow::class.java,
+                DragZone.Split.Top::class.java,
+                DragZone.Split.Bottom::class.java,
+                DragZone.Bubble.Left::class.java,
+                DragZone.Bubble.Right::class.java,
+            )
+        dragZones.zip(expectedZones).forEach { (zone, expectedType) ->
+            assertThat(zone).isInstanceOf(expectedType)
+        }
+    }
+
+    @Test
+    fun dragZonesForExpandedView_tablet_landscape() {
+        dragZoneFactory = DragZoneFactory(tabletLandscape, splitScreenModeChecker, desktopWindowModeChecker)
+        val dragZones =
+            dragZoneFactory.createSortedDragZones(DraggedObject.ExpandedView(BubbleBarLocation.LEFT))
+        val expectedZones: List<Class<out DragZone>> =
+            listOf(
+                DragZone.Dismiss::class.java,
+                DragZone.FullScreen::class.java,
+                DragZone.DesktopWindow::class.java,
+                DragZone.Split.Left::class.java,
+                DragZone.Split.Right::class.java,
+                DragZone.Bubble.Left::class.java,
+                DragZone.Bubble.Right::class.java,
+            )
+        dragZones.zip(expectedZones).forEach { (zone, expectedType) ->
+            assertThat(zone).isInstanceOf(expectedType)
+        }
+    }
+
+    @Test
+    fun dragZonesForExpandedView_foldable_portrait() {
+        dragZoneFactory = DragZoneFactory(foldablePortrait, splitScreenModeChecker, desktopWindowModeChecker)
+        val dragZones =
+            dragZoneFactory.createSortedDragZones(DraggedObject.ExpandedView(BubbleBarLocation.LEFT))
+        val expectedZones: List<Class<out DragZone>> =
+            listOf(
+                DragZone.Dismiss::class.java,
+                DragZone.FullScreen::class.java,
+                DragZone.Split.Left::class.java,
+                DragZone.Split.Right::class.java,
+                DragZone.Bubble.Left::class.java,
+                DragZone.Bubble.Right::class.java,
+            )
+        dragZones.zip(expectedZones).forEach { (zone, expectedType) ->
+            assertThat(zone).isInstanceOf(expectedType)
+        }
+    }
+
+    @Test
+    fun dragZonesForExpandedView_foldable_landscape() {
+        dragZoneFactory = DragZoneFactory(foldableLandscape, splitScreenModeChecker, desktopWindowModeChecker)
+        val dragZones =
+            dragZoneFactory.createSortedDragZones(DraggedObject.ExpandedView(BubbleBarLocation.LEFT))
+        val expectedZones: List<Class<out DragZone>> =
+            listOf(
+                DragZone.Dismiss::class.java,
+                DragZone.FullScreen::class.java,
+                DragZone.Split.Top::class.java,
+                DragZone.Split.Bottom::class.java,
+                DragZone.Bubble.Left::class.java,
+                DragZone.Bubble.Right::class.java,
+            )
+        dragZones.zip(expectedZones).forEach { (zone, expectedType) ->
+            assertThat(zone).isInstanceOf(expectedType)
+        }
+    }
+
+    @Test
+    fun dragZonesForBubble_tablet_desktopModeDisabled() {
+        isDesktopWindowModeSupported = false
+        dragZoneFactory = DragZoneFactory(foldableLandscape, splitScreenModeChecker, desktopWindowModeChecker)
+        val dragZones =
+            dragZoneFactory.createSortedDragZones(DraggedObject.Bubble(BubbleBarLocation.LEFT))
+        assertThat(dragZones.filterIsInstance<DragZone.DesktopWindow>()).isEmpty()
+    }
+
+    @Test
+    fun dragZonesForExpandedView_tablet_desktopModeDisabled() {
+        isDesktopWindowModeSupported = false
+        dragZoneFactory = DragZoneFactory(foldableLandscape, splitScreenModeChecker, desktopWindowModeChecker)
+        val dragZones =
+            dragZoneFactory.createSortedDragZones(DraggedObject.ExpandedView(BubbleBarLocation.LEFT))
+        assertThat(dragZones.filterIsInstance<DragZone.DesktopWindow>()).isEmpty()
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicyTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicyTest.kt
index a8a7be8..d9791bb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicyTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicyTest.kt
@@ -21,7 +21,7 @@
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
 import com.android.internal.R
-import com.android.wm.shell.compatui.CompatUIShellTestCase
+import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
@@ -39,7 +39,7 @@
  */
 @RunWith(AndroidTestingRunner::class)
 @SmallTest
-class DesktopModeCompatPolicyTest : CompatUIShellTestCase() {
+class DesktopModeCompatPolicyTest : ShellTestCase() {
     private lateinit var desktopModeCompatPolicy: DesktopModeCompatPolicy
 
     @Before
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt
index 4dac99b..33f14ac 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt
@@ -39,6 +39,9 @@
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.whenever
 
+/**
+ * Test class for [DesktopModeStatus].
+ */
 @SmallTest
 @Presubmit
 @EnableFlags(Flags.FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
@@ -56,6 +59,7 @@
         doReturn(false).whenever(mockResources).getBoolean(
             eq(R.bool.config_isDesktopModeDevOptionSupported)
         )
+        setDeviceEligibleForDesktopMode(false)
         doReturn(context.contentResolver).whenever(mockContext).contentResolver
         resetDesktopModeFlagsCache()
         resetEnforceDeviceRestriction()
@@ -74,7 +78,7 @@
         Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION
     )
     @Test
-    fun canEnterDesktopMode_DWFlagDisabled_configsOff_returnsFalse() {
+    fun canEnterDesktopMode_DWFlagDisabled_deviceNotEligible_returnsFalse() {
         assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isFalse()
     }
 
@@ -83,8 +87,8 @@
         Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION
     )
     @Test
-    fun canEnterDesktopMode_DWFlagDisabled_configsOn_disableDeviceRestrictions_returnsFalse() {
-        doReturn(true).whenever(mockResources).getBoolean(eq(R.bool.config_isDesktopModeSupported))
+    fun canEnterDesktopMode_DWFlagDisabled_deviceEligible_configDevOptionOn_returnsFalse() {
+        setDeviceEligibleForDesktopMode(true)
         doReturn(true).whenever(mockResources).getBoolean(
             eq(R.bool.config_isDesktopModeDevOptionSupported)
         )
@@ -98,7 +102,7 @@
         Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION
     )
     @Test
-    fun canEnterDesktopMode_DWFlagDisabled_configDevOptionOn_returnsFalse() {
+    fun canEnterDesktopMode_DWFlagDisabled_deviceNotEligible_configDevOptionOn_returnsFalse() {
         doReturn(true).whenever(mockResources).getBoolean(
             eq(R.bool.config_isDesktopModeDevOptionSupported)
         )
@@ -111,7 +115,7 @@
         Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION
     )
     @Test
-    fun canEnterDesktopMode_DWFlagDisabled_configDevOptionOn_flagOverrideOn_returnsTrue() {
+    fun canEnterDesktopMode_DWFlagDisabled_deviceNotEligible_forceUsingDevOption_returnsTrue() {
         doReturn(true).whenever(mockResources).getBoolean(
             eq(R.bool.config_isDesktopModeDevOptionSupported)
         )
@@ -123,14 +127,7 @@
     @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
     @Test
-    fun canEnterDesktopMode_DWFlagEnabled_configsOff_returnsFalse() {
-        assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isFalse()
-    }
-
-    @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
-    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
-    @Test
-    fun canEnterDesktopMode_DWFlagEnabled_configDesktopModeOff_returnsFalse() {
+    fun canEnterDesktopMode_DWFlagEnabled_deviceNotEligible_returnsFalse() {
         doReturn(true).whenever(mockResources).getBoolean(
             eq(R.bool.config_isDesktopModeDevOptionSupported)
         )
@@ -141,8 +138,8 @@
     @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
     @Test
-    fun canEnterDesktopMode_DWFlagEnabled_configDesktopModeOn_returnsTrue() {
-        doReturn(true).whenever(mockResources).getBoolean(eq(R.bool.config_isDesktopModeSupported))
+    fun canEnterDesktopMode_DWFlagEnabled_deviceEligible_returnsTrue() {
+        setDeviceEligibleForDesktopMode(true)
 
         assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isTrue()
     }
@@ -150,16 +147,7 @@
     @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
     @Test
-    fun canEnterDesktopMode_DWFlagEnabled_configsOff_disableDeviceRestrictions_returnsTrue() {
-        disableEnforceDeviceRestriction()
-
-        assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isTrue()
-    }
-
-    @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_MODE_THROUGH_DEV_OPTION)
-    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
-    @Test
-    fun canEnterDesktopMode_DWFlagEnabled_configDevOptionOn_flagOverrideOn_returnsTrue() {
+    fun canEnterDesktopMode_DWFlagEnabled_deviceNotEligible_forceUsingDevOption_returnsTrue() {
         doReturn(true).whenever(mockResources).getBoolean(
             eq(R.bool.config_isDesktopModeDevOptionSupported)
         )
@@ -198,6 +186,28 @@
         assertThat(DesktopModeStatus.isDeviceEligibleForDesktopMode(mockContext)).isTrue()
     }
 
+    @DisableFlags(Flags.FLAG_SHOW_DESKTOP_EXPERIENCE_DEV_OPTION)
+    @Test
+    fun canShowDesktopExperienceDevOption_flagDisabled_returnsFalse() {
+        setDeviceEligibleForDesktopMode(true)
+
+        assertThat(DesktopModeStatus.canShowDesktopExperienceDevOption(mockContext)).isFalse()
+    }
+
+    @EnableFlags(Flags.FLAG_SHOW_DESKTOP_EXPERIENCE_DEV_OPTION)
+    @Test
+    fun canShowDesktopExperienceDevOption_flagEnabled_deviceNotEligible_returnsFalse() {
+        assertThat(DesktopModeStatus.canShowDesktopExperienceDevOption(mockContext)).isFalse()
+    }
+
+    @EnableFlags(Flags.FLAG_SHOW_DESKTOP_EXPERIENCE_DEV_OPTION)
+    @Test
+    fun canShowDesktopExperienceDevOption_flagEnabled_deviceEligible_returnsTrue() {
+        setDeviceEligibleForDesktopMode(true)
+
+        assertThat(DesktopModeStatus.canShowDesktopExperienceDevOption(mockContext)).isTrue()
+    }
+
     private fun resetEnforceDeviceRestriction() {
         setEnforceDeviceRestriction(true)
     }
@@ -232,4 +242,10 @@
             DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES, override.setting
         )
     }
+
+    private fun setDeviceEligibleForDesktopMode(eligible: Boolean) {
+        val deviceRestrictions = DesktopModeStatus::class.java.getDeclaredField("ENFORCE_DEVICE_RESTRICTIONS")
+        deviceRestrictions.isAccessible = true
+        deviceRestrictions.setBoolean(/* obj= */ null, /* z= */ !eligible)
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt
index 8b4cf6d..53ae967 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt
@@ -25,6 +25,7 @@
 import android.platform.test.annotations.EnableFlags
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
+import android.view.Display
 import android.view.Display.DEFAULT_DISPLAY
 import android.view.SurfaceControl
 import androidx.test.filters.SmallTest
@@ -38,10 +39,13 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mockito.times
 import org.mockito.kotlin.any
 import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.mock
 import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
 import org.mockito.quality.Strictness
 
 /**
@@ -59,6 +63,8 @@
 class DesktopModeWindowDecorViewModelAppHandleOnlyTest :
     DesktopModeWindowDecorViewModelTestsBase() {
 
+    protected val mockDisplay = mock<Display>()
+
     @Before
     fun setUp() {
         mockitoSession =
@@ -67,9 +73,10 @@
                 .spyStatic(DesktopModeStatus::class.java)
                 .spyStatic(DragPositioningCallbackUtility::class.java)
                 .startMocking()
-        doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+        doReturn(false).`when` { DesktopModeStatus.isDeviceEligibleForDesktopMode(any()) }
         doReturn(true).`when` { DesktopModeStatus.overridesShowAppHandle(any())}
         setUpCommon()
+        whenever(mockDisplayController.getDisplay(anyInt())).thenReturn(mockDisplay)
     }
 
     @Test
@@ -156,7 +163,7 @@
         assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
 
 
-        task.setOnLargeScreen(false)
+        setLargeScreen(false)
         setUpMockDecorationForTask(task)
         onTaskChanging(task, taskSurface)
         assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
@@ -172,11 +179,12 @@
     ): RunningTaskInfo {
         val task = createTask(
             displayId, windowingMode, activityType, activityInfo, requestingImmersive)
-        task.setOnLargeScreen(shouldShowAspectRatioButton)
+        setLargeScreen(shouldShowAspectRatioButton)
         return task
     }
 
-    private fun RunningTaskInfo.setOnLargeScreen(large: Boolean) {
-        configuration.smallestScreenWidthDp = if (large) 1000 else 100
+    private fun setLargeScreen(large: Boolean) {
+        val size: Float = if (large) 1000f else 100f
+        whenever(mockDisplay.getMinSizeDimensionDp()).thenReturn(size)
     }
 }
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 737780e..f15418ad 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
@@ -116,7 +116,7 @@
                 .spyStatic(DragPositioningCallbackUtility::class.java)
                 .startMocking()
 
-        doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(Mockito.any()) }
+        doReturn(true).`when` { DesktopModeStatus.isDeviceEligibleForDesktopMode(Mockito.any()) }
         doReturn(false).`when` { DesktopModeStatus.overridesShowAppHandle(Mockito.any()) }
 
         setUpCommon()
@@ -379,37 +379,21 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
-    fun testWindowDecor_desktopModeUnsupportedOnDevice_deviceRestrictionsOverridden_decorCreated() {
-        // Simulate enforce device restrictions system property overridden to false
-        whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(false)
-        // Simulate device that doesn't support desktop mode
-        doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
-
-        val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN)
-        setUpMockDecorationsForTasks(task)
-
-        onTaskOpening(task)
-        assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
-    }
-
-    @Test
-    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
-    fun testWindowDecor_deviceSupportsDesktopMode_decorCreated() {
+    fun testWindowDecor_deviceEligibleForDesktopMode_decorCreated() {
         // Simulate default enforce device restrictions system property
         whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(true)
 
         val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN)
-        doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+        doReturn(true).`when` { DesktopModeStatus.isDeviceEligibleForDesktopMode(any()) }
         setUpMockDecorationsForTasks(task)
 
         onTaskOpening(task)
-        assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
+        assertTrue(task.taskId in windowDecorByTaskIdSpy)
     }
 
     @Test
     fun testOnDecorMaximizedOrRestored_togglesTaskSize_maximize() {
-        val maxOrRestoreListenerCaptor = forClass(Function0::class.java)
-                as ArgumentCaptor<Function0<Unit>>
+        val maxOrRestoreListenerCaptor = forClass(Function0::class.java as Class<Function0<Unit>>)
         val decor = createOpenTaskDecoration(
             windowingMode = WINDOWING_MODE_FREEFORM,
             onMaxOrRestoreListenerCaptor = maxOrRestoreListenerCaptor
@@ -655,7 +639,7 @@
 
         toDesktopListenerCaptor.value.accept(DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON)
 
-        verify(mockDesktopTasksController).moveTaskToDesktop(
+        verify(mockDesktopTasksController).moveTaskToDefaultDeskAndActivate(
             eq(decor.mTaskInfo.taskId),
             any(),
             eq(DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON),
@@ -893,7 +877,7 @@
         )
 
         verify(mockDesktopTasksController, times(1))
-            .moveTaskToDesktop(any(), any(), any(), anyOrNull(), anyOrNull())
+            .moveTaskToDefaultDeskAndActivate(any(), any(), any(), anyOrNull(), anyOrNull())
     }
 
     @Test
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index 12b1dd7..3dc53c5 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -288,6 +288,7 @@
         "tests/AttributeResolution_bench.cpp",
         "tests/CursorWindow_bench.cpp",
         "tests/Generic_bench.cpp",
+        "tests/LocaleDataLookup_bench.cpp",
         "tests/SparseEntry_bench.cpp",
         "tests/Theme_bench.cpp",
     ],
diff --git a/libs/androidfw/LocaleDataLookup.cpp b/libs/androidfw/LocaleDataLookup.cpp
index 6e751a7..ea9e9a2 100644
--- a/libs/androidfw/LocaleDataLookup.cpp
+++ b/libs/androidfw/LocaleDataLookup.cpp
@@ -7518,6 +7518,13 @@
      }
 }
 
+/*
+ * TODO: Consider turning the below switch statement into binary search
+ *      to save the disk space when the table is larger in the future.
+ *      Disassembled code shows that the jump table emitted by clang can be
+ *      4x larger than the data in disk size, but it depends on the optimization option.
+ *      However, a switch statement will benefit from the future of compiler improvement.
+ */
 bool isLocaleRepresentative(uint32_t language_and_region, const char* script) {
     const uint64_t packed_locale =
             ((static_cast<uint64_t>(language_and_region)) << 32u) |
diff --git a/libs/androidfw/TypeWrappers.cpp b/libs/androidfw/TypeWrappers.cpp
index 9704634..2a20106 100644
--- a/libs/androidfw/TypeWrappers.cpp
+++ b/libs/androidfw/TypeWrappers.cpp
@@ -18,8 +18,11 @@
 
 namespace android {
 
-TypeVariant::TypeVariant(const ResTable_type* data) : data(data), mLength(dtohl(data->entryCount)) {
-    if (data->flags & ResTable_type::FLAG_SPARSE) {
+TypeVariant::TypeVariant(const ResTable_type* data)
+    : data(data)
+    , mLength(dtohl(data->entryCount))
+    , mSparse(data->flags & ResTable_type::FLAG_SPARSE) {
+    if (mSparse) {
         const uint32_t entryCount = dtohl(data->entryCount);
         const uintptr_t containerEnd = reinterpret_cast<uintptr_t>(data) + dtohl(data->header.size);
         const uint32_t* const entryIndices = reinterpret_cast<const uint32_t*>(
@@ -40,18 +43,18 @@
         mIndex = mTypeVariant->mLength;
     }
 
-    const ResTable_type* type = mTypeVariant->data;
-    if ((type->flags & ResTable_type::FLAG_SPARSE) == 0) {
+    if (!mTypeVariant->mSparse) {
       return *this;
     }
 
     // Need to adjust |mSparseIndex| as well if we've passed its current element.
+    const ResTable_type* type = mTypeVariant->data;
     const uint32_t entryCount = dtohl(type->entryCount);
-    const auto entryIndices = reinterpret_cast<const uint32_t*>(
-        reinterpret_cast<uintptr_t>(type) + dtohs(type->header.headerSize));
     if (mSparseIndex >= entryCount) {
       return *this; // done
     }
+    const auto entryIndices = reinterpret_cast<const uint32_t*>(
+        reinterpret_cast<uintptr_t>(type) + dtohs(type->header.headerSize));
     const auto element = (const ResTable_sparseTypeEntry*)(entryIndices + mSparseIndex);
     if (mIndex > dtohs(element->idx)) {
       ++mSparseIndex;
@@ -79,7 +82,7 @@
     }
 
     uint32_t entryOffset;
-    if (type->flags & ResTable_type::FLAG_SPARSE) {
+    if (mTypeVariant->mSparse) {
       if (mSparseIndex >= entryCount) {
         return nullptr;
       }
diff --git a/libs/androidfw/include/androidfw/TypeWrappers.h b/libs/androidfw/include/androidfw/TypeWrappers.h
index db641b7..d901af3 100644
--- a/libs/androidfw/include/androidfw/TypeWrappers.h
+++ b/libs/androidfw/include/androidfw/TypeWrappers.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef __TYPE_WRAPPERS_H
-#define __TYPE_WRAPPERS_H
+#pragma once
 
 #include <androidfw/ResourceTypes.h>
 #include <utils/ByteOrder.h>
@@ -54,7 +53,7 @@
         enum class Kind { Begin, End };
         iterator(const TypeVariant* tv, Kind kind)
             : mTypeVariant(tv) {
-          mSparseIndex = mIndex = kind == Kind::Begin ? 0 : tv->mLength;
+          mSparseIndex = mIndex = (kind == Kind::Begin ? 0 : tv->mLength);
           // mSparseIndex here is technically past the number of sparse entries, but it is still
           // ok as it is enough to infer that this is the end iterator.
         }
@@ -75,9 +74,11 @@
     const ResTable_type* data;
 
 private:
-    size_t mLength;
+    // For a dense table, this is the number of the elements.
+    // For a sparse table, this is the index of the last element + 1.
+    // In both cases, it can be used for iteration as the upper loop bound as in |i < mLength|.
+    uint32_t mLength;
+    bool mSparse;
 };
 
 } // namespace android
-
-#endif // __TYPE_WRAPPERS_H
diff --git a/libs/androidfw/tests/LocaleDataLookup_bench.cpp b/libs/androidfw/tests/LocaleDataLookup_bench.cpp
new file mode 100644
index 0000000..60ce3b9
--- /dev/null
+++ b/libs/androidfw/tests/LocaleDataLookup_bench.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "benchmark/benchmark.h"
+
+#include "androidfw/LocaleDataLookup.h"
+
+namespace android {
+
+static void BM_LocaleDataLookupIsLocaleRepresentative(benchmark::State& state) {
+  for (auto&& _ : state) {
+    isLocaleRepresentative(packLocale("en", "US"), "Latn");
+    isLocaleRepresentative(packLocale("es", "ES"), "Latn");
+    isLocaleRepresentative(packLocale("zh", "CN"), "Hans");
+    isLocaleRepresentative(packLocale("pt", "BR"), "Latn");
+    isLocaleRepresentative(packLocale("ar", "EG"), "Arab");
+    isLocaleRepresentative(packLocale("hi", "IN"), "Deva");
+    isLocaleRepresentative(packLocale("jp", "JP"), "Jpan");
+  }
+}
+BENCHMARK(BM_LocaleDataLookupIsLocaleRepresentative);
+
+static void BM_LocaleDataLookupLikelyScript(benchmark::State& state) {
+  for (auto&& _ : state) {
+    lookupLikelyScript(packLocale("en", ""));
+    lookupLikelyScript(packLocale("es", ""));
+    lookupLikelyScript(packLocale("zh", ""));
+    lookupLikelyScript(packLocale("pt", ""));
+    lookupLikelyScript(packLocale("ar", ""));
+    lookupLikelyScript(packLocale("hi", ""));
+    lookupLikelyScript(packLocale("jp", ""));
+    lookupLikelyScript(packLocale("en", "US"));
+    lookupLikelyScript(packLocale("es", "ES"));
+    lookupLikelyScript(packLocale("zh", "CN"));
+    lookupLikelyScript(packLocale("pt", "BR"));
+    lookupLikelyScript(packLocale("ar", "EG"));
+    lookupLikelyScript(packLocale("hi", "IN"));
+    lookupLikelyScript(packLocale("jp", "JP"));
+  }
+}
+BENCHMARK(BM_LocaleDataLookupLikelyScript);
+
+
+}  // namespace android
diff --git a/libs/androidfw/tests/TypeWrappers_test.cpp b/libs/androidfw/tests/TypeWrappers_test.cpp
index d66e058..69c24c5 100644
--- a/libs/androidfw/tests/TypeWrappers_test.cpp
+++ b/libs/androidfw/tests/TypeWrappers_test.cpp
@@ -121,6 +121,7 @@
     values.push_back(std::nullopt);
     values.push_back(std::nullopt);
     values.push_back(Res_value{ sizeof(Res_value), 0, Res_value::TYPE_STRING, 0x87654321});
+    values.push_back(std::nullopt);
 
     // test for combinations of compact_entry and short_offsets
     for (size_t i = 0; i < 8; i++) {
@@ -191,6 +192,17 @@
 
         ++iter;
 
+        ASSERT_EQ(uint32_t(9), iter.index());
+        ASSERT_TRUE(NULL == *iter);
+        if (sparse) {
+          // Sparse iterator doesn't know anything beyond the last entry.
+          ASSERT_EQ(v.endEntries(), iter);
+        } else {
+          ASSERT_NE(v.endEntries(), iter);
+        }
+
+        ++iter;
+
         ASSERT_EQ(v.endEntries(), iter);
     }
 }
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 71013f7..5dc49a0 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -10406,6 +10406,23 @@
         }
     }
 
+    /**
+     * Enable strict audio hardening (background) enforcement, regardless of release or temporary
+     * exemptions for debugging purposes.
+     * Enforced hardening can be found in the audio dumpsys with the API being restricted and the
+     * level of restriction which was encountered.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+    public void setEnableHardening(boolean shouldEnable) {
+        final IAudioService service = getService();
+        try {
+            service.setEnableHardening(shouldEnable);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     //====================================================================
     // Mute await connection
 
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 2a740f8..7b8d666 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -819,4 +819,8 @@
     @EnforcePermission("QUERY_AUDIO_STATE")
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.QUERY_AUDIO_STATE)")
     boolean shouldNotificationSoundPlay(in AudioAttributes aa);
+
+    @EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)")
+    void setEnableHardening(in boolean shouldEnable);
 }
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 1a84371..fb1b5b5 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -3888,7 +3888,9 @@
 
         /**
          * Set a hardware graphic buffer to this queue request. Exactly one buffer must
-         * be set for a queue request before calling {@link #queue}.
+         * be set for a queue request before calling {@link #queue}. Ownership of the
+         * hardware buffer is not transferred to this queue request, nor will it be transferred
+         * to the codec once {@link #queue} is called.
          * <p>
          * Note: buffers should have format {@link HardwareBuffer#YCBCR_420_888},
          * a single layer, and an appropriate usage ({@link HardwareBuffer#USAGE_CPU_READ_OFTEN}
diff --git a/media/java/android/media/RoutingSessionInfo.java b/media/java/android/media/RoutingSessionInfo.java
index 87bb6ea..d27d7fc 100644
--- a/media/java/android/media/RoutingSessionInfo.java
+++ b/media/java/android/media/RoutingSessionInfo.java
@@ -649,9 +649,19 @@
          * @param sessionInfo the existing instance to copy data from.
          */
         public Builder(@NonNull RoutingSessionInfo sessionInfo) {
+            this(sessionInfo, sessionInfo.getOriginalId());
+        }
+
+        /**
+         * Builds upon the given {@code sessionInfo}, using the given {@link #getOriginalId()} for
+         * the id.
+         *
+         * @hide
+         */
+        public Builder(@NonNull RoutingSessionInfo sessionInfo, String originalId) {
             Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
 
-            mOriginalId = sessionInfo.mOriginalId;
+            mOriginalId = originalId;
             mName = sessionInfo.mName;
             mClientPackageName = sessionInfo.mClientPackageName;
             mProviderId = sessionInfo.mProviderId;
diff --git a/media/java/android/media/flags/media_better_together.aconfig b/media/java/android/media/flags/media_better_together.aconfig
index 405d292..2e8c28d 100644
--- a/media/java/android/media/flags/media_better_together.aconfig
+++ b/media/java/android/media/flags/media_better_together.aconfig
@@ -21,6 +21,16 @@
 }
 
 flag {
+    name: "disable_transfer_when_apps_do_not_support"
+    namespace: "media_better_together"
+    description: "Fixes a bug causing output switcher routes to be incorrectly enabled for media transfer."
+    bug: "373404114"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
     name: "enable_audio_input_device_routing_and_volume_control"
     namespace: "media_better_together"
     description: "Allows audio input devices routing and volume control via system settings."
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 3bc238a..61c287b 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -1232,63 +1232,73 @@
     sp<ABuffer> ivBuffer;
     CryptoPlugin::Mode mode;
     CryptoPlugin::Pattern pattern;
-    CHECK(msg->findInt32("mode", (int*)&mode));
-    CHECK(msg->findSize("numSubSamples", &numSubSamples));
-    CHECK(msg->findBuffer("subSamples", &subSamplesBuffer));
-    CHECK(msg->findInt32("encryptBlocks", (int32_t *)&pattern.mEncryptBlocks));
-    CHECK(msg->findInt32("skipBlocks", (int32_t *)&pattern.mSkipBlocks));
-    CHECK(msg->findBuffer("iv", &ivBuffer));
-    CHECK(msg->findBuffer("key", &keyBuffer));
-
-    // subsamples
+    CryptoPlugin::SubSample *samplesArray = nullptr;
+    ScopedLocalRef<jbyteArray> keyArray(env, env->NewByteArray(16));
+    ScopedLocalRef<jbyteArray> ivArray(env, env->NewByteArray(16));
+    jboolean isCopy;
+    sp<RefBase> cryptoInfosObj;
+    if (msg->findObject("cryptoInfos", &cryptoInfosObj)) {
+        sp<CryptoInfosWrapper> cryptoInfos((CryptoInfosWrapper*)cryptoInfosObj.get());
+        CHECK(!cryptoInfos->value.empty() && (cryptoInfos->value[0] != nullptr));
+        std::unique_ptr<CodecCryptoInfo> &info = cryptoInfos->value[0];
+        mode = info->mMode;
+        numSubSamples = info->mNumSubSamples;
+        samplesArray = info->mSubSamples;
+        pattern = info->mPattern;
+        if (info->mKey != nullptr) {
+            jbyte * dstKey = env->GetByteArrayElements(keyArray.get(), &isCopy);
+            memcpy(dstKey, info->mKey, 16);
+            env->ReleaseByteArrayElements(keyArray.get(), dstKey, 0);
+        }
+        if (info->mIv != nullptr) {
+            jbyte * dstIv = env->GetByteArrayElements(ivArray.get(), &isCopy);
+            memcpy(dstIv, info->mIv, 16);
+            env->ReleaseByteArrayElements(ivArray.get(), dstIv, 0);
+        }
+    } else {
+        CHECK(msg->findInt32("mode", (int*)&mode));
+        CHECK(msg->findSize("numSubSamples", &numSubSamples));
+        CHECK(msg->findBuffer("subSamples", &subSamplesBuffer));
+        CHECK(msg->findInt32("encryptBlocks", (int32_t *)&pattern.mEncryptBlocks));
+        CHECK(msg->findInt32("skipBlocks", (int32_t *)&pattern.mSkipBlocks));
+        CHECK(msg->findBuffer("iv", &ivBuffer));
+        CHECK(msg->findBuffer("key", &keyBuffer));
+        samplesArray =
+                (CryptoPlugin::SubSample*)(subSamplesBuffer.get()->data());
+        if (keyBuffer.get() != nullptr && keyBuffer->size() > 0) {
+            jbyte * dstKey = env->GetByteArrayElements(keyArray.get(), &isCopy);
+            memcpy(dstKey, keyBuffer->data(), keyBuffer->size());
+            env->ReleaseByteArrayElements(keyArray.get(), dstKey, 0);
+        }
+        if (ivBuffer.get() != nullptr && ivBuffer->size() > 0) {
+            jbyte * dstIv = env->GetByteArrayElements(ivArray.get(), &isCopy);
+            memcpy(dstIv, ivBuffer->data(), ivBuffer->size());
+            env->ReleaseByteArrayElements(ivArray.get(), dstIv, 0);
+        }
+    }
     ScopedLocalRef<jintArray> samplesOfEncryptedDataArr(env, env->NewIntArray(numSubSamples));
     ScopedLocalRef<jintArray> samplesOfClearDataArr(env, env->NewIntArray(numSubSamples));
-    jboolean isCopy;
-    jint *dstEncryptedSamples =
-        env->GetIntArrayElements(samplesOfEncryptedDataArr.get(), &isCopy);
-    jint * dstClearSamples =
-        env->GetIntArrayElements(samplesOfClearDataArr.get(), &isCopy);
-
-    CryptoPlugin::SubSample * samplesArray =
-        (CryptoPlugin::SubSample*)(subSamplesBuffer.get()->data());
-
-    for(int i = 0 ; i < numSubSamples ; i++) {
-        dstEncryptedSamples[i] = samplesArray[i].mNumBytesOfEncryptedData;
-        dstClearSamples[i] = samplesArray[i].mNumBytesOfClearData;
+    if (numSubSamples > 0) {
+        jint *dstEncryptedSamples =
+            env->GetIntArrayElements(samplesOfEncryptedDataArr.get(), &isCopy);
+        jint * dstClearSamples =
+            env->GetIntArrayElements(samplesOfClearDataArr.get(), &isCopy);
+        for(int i = 0 ; i < numSubSamples ; i++) {
+            dstEncryptedSamples[i] = samplesArray[i].mNumBytesOfEncryptedData;
+            dstClearSamples[i] = samplesArray[i].mNumBytesOfClearData;
+        }
+        env->ReleaseIntArrayElements(samplesOfEncryptedDataArr.get(), dstEncryptedSamples, 0);
+        env->ReleaseIntArrayElements(samplesOfClearDataArr.get(), dstClearSamples, 0);
     }
-    env->ReleaseIntArrayElements(samplesOfEncryptedDataArr.get(), dstEncryptedSamples, 0);
-    env->ReleaseIntArrayElements(samplesOfClearDataArr.get(), dstClearSamples, 0);
-    // key and iv
-    jbyteArray keyArray = NULL;
-    jbyteArray ivArray = NULL;
-    if (keyBuffer.get() != nullptr && keyBuffer->size() > 0) {
-        keyArray = env->NewByteArray(keyBuffer->size());
-        jbyte * dstKey = env->GetByteArrayElements(keyArray, &isCopy);
-        memcpy(dstKey, keyBuffer->data(), keyBuffer->size());
-        env->ReleaseByteArrayElements(keyArray,dstKey,0);
-    }
-    if (ivBuffer.get() != nullptr && ivBuffer->size() > 0) {
-        ivArray = env->NewByteArray(ivBuffer->size());
-        jbyte *dstIv = env->GetByteArrayElements(ivArray, &isCopy);
-        memcpy(dstIv, ivBuffer->data(), ivBuffer->size());
-        env->ReleaseByteArrayElements(ivArray, dstIv,0);
-    }
-    // set samples, key and iv
     env->CallVoidMethod(
         obj,
         gFields.cryptoInfoSetID,
         (jint)numSubSamples,
         samplesOfClearDataArr.get(),
         samplesOfEncryptedDataArr.get(),
-        keyArray,
-        ivArray,
+        keyArray.get(),
+        ivArray.get(),
         mode);
-    if (keyArray != NULL) {
-        env->DeleteLocalRef(keyArray);
-    }
-    if (ivArray != NULL) {
-        env->DeleteLocalRef(ivArray);
-    }
     // set pattern
     env->CallVoidMethod(
         obj,
diff --git a/nfc-non-updatable/flags/flags.aconfig b/nfc-non-updatable/flags/flags.aconfig
index 54ded0c..eb30bbe 100644
--- a/nfc-non-updatable/flags/flags.aconfig
+++ b/nfc-non-updatable/flags/flags.aconfig
@@ -198,10 +198,6 @@
     bug: "380892385"
 }
 
-flag {
-    name: "nfc_hce_latency_events"
-    is_exported: true
-    namespace: "wallet_integration"
-    description: "Enables tracking latency for HCE"
-    bug: "379849603"
-}
+# Unless you are adding a flag for a file under nfc-non-updatable, you should
+# not add a flag here for Android 16+ targeting features. Use the flags
+# in com.android.nfc.module.flags (packages/modules/Nfc/flags) instead.
diff --git a/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.java b/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.java
index 93d6eb7..e83b9f1 100644
--- a/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -572,8 +572,10 @@
         if (mAutoTransact.getOrDefault(plf.toUpperCase(Locale.ROOT), false)) {
             return true;
         }
-        List<Pattern> patternMatches = mAutoTransactPatterns.keySet().stream()
-                .filter(p -> p.matcher(plf).matches()).toList();
+        boolean isPattern = plf.contains("?") || plf.contains("*");
+        List<Pattern> patternMatches = mAutoTransactPatterns.keySet().stream().filter(
+            p -> isPattern ? p.toString().equals(plf) : p.matcher(plf).matches()).toList();
+
         if (patternMatches == null || patternMatches.size() == 0) {
             return false;
         }
diff --git a/packages/CrashRecovery/framework/java/android/service/watchdog/ExplicitHealthCheckService.java b/packages/CrashRecovery/framework/java/android/service/watchdog/ExplicitHealthCheckService.java
deleted file mode 100644
index fdb0fc5..0000000
--- a/packages/CrashRecovery/framework/java/android/service/watchdog/ExplicitHealthCheckService.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.watchdog;
-
-import static android.os.Parcelable.Creator;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SdkConstant;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.app.Service;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.crashrecovery.flags.Flags;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteCallback;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
-
-/**
- * A service to provide packages supporting explicit health checks and route checks to these
- * packages on behalf of the package watchdog.
- *
- * <p>To extend this class, you must declare the service in your manifest file with the
- * {@link android.Manifest.permission#BIND_EXPLICIT_HEALTH_CHECK_SERVICE} permission,
- * and include an intent filter with the {@link #SERVICE_INTERFACE} action. In adddition,
- * your implementation must live in
- * {@link PackageManager#getServicesSystemSharedLibraryPackageName()}.
- * For example:</p>
- * <pre>
- *     &lt;service android:name=".FooExplicitHealthCheckService"
- *             android:exported="true"
- *             android:priority="100"
- *             android:permission="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"&gt;
- *         &lt;intent-filter&gt;
- *             &lt;action android:name="android.service.watchdog.ExplicitHealthCheckService" /&gt;
- *         &lt;/intent-filter&gt;
- *     &lt;/service&gt;
- * </pre>
- * @hide
- */
-@SystemApi
-public abstract class ExplicitHealthCheckService extends Service {
-
-    private static final String TAG = "ExplicitHealthCheckService";
-
-    /**
-     * {@link Bundle} key for a {@link List} of {@link PackageConfig} value.
-     *
-     * {@hide}
-     */
-    public static final String EXTRA_SUPPORTED_PACKAGES =
-            "android.service.watchdog.extra.supported_packages";
-
-    /**
-     * {@link Bundle} key for a {@link List} of {@link String} value.
-     *
-     * {@hide}
-     */
-    public static final String EXTRA_REQUESTED_PACKAGES =
-            "android.service.watchdog.extra.requested_packages";
-
-    /**
-     * {@link Bundle} key for a {@link String} value.
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_CRASHRECOVERY)
-    public static final String EXTRA_HEALTH_CHECK_PASSED_PACKAGE =
-            "android.service.watchdog.extra.HEALTH_CHECK_PASSED_PACKAGE";
-
-    /**
-     * The Intent action that a service must respond to. Add it to the intent filter of the service
-     * in its manifest.
-     */
-    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
-    public static final String SERVICE_INTERFACE =
-            "android.service.watchdog.ExplicitHealthCheckService";
-
-    /**
-     * The permission that a service must require to ensure that only Android system can bind to it.
-     * If this permission is not enforced in the AndroidManifest of the service, the system will
-     * skip that service.
-     */
-    public static final String BIND_PERMISSION =
-            "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE";
-
-    private final ExplicitHealthCheckServiceWrapper mWrapper =
-            new ExplicitHealthCheckServiceWrapper();
-
-    /**
-     * Called when the system requests an explicit health check for {@code packageName}.
-     *
-     * <p> When {@code packageName} passes the check, implementors should call
-     * {@link #notifyHealthCheckPassed} to inform the system.
-     *
-     * <p> It could take many hours before a {@code packageName} passes a check and implementors
-     * should never drop requests unless {@link onCancel} is called or the service dies.
-     *
-     * <p> Requests should not be queued and additional calls while expecting a result for
-     * {@code packageName} should have no effect.
-     */
-    public abstract void onRequestHealthCheck(@NonNull String packageName);
-
-    /**
-     * Called when the system cancels the explicit health check request for {@code packageName}.
-     * Should do nothing if there are is no active request for {@code packageName}.
-     */
-    public abstract void onCancelHealthCheck(@NonNull String packageName);
-
-    /**
-     * Called when the system requests for all the packages supporting explicit health checks. The
-     * system may request an explicit health check for any of these packages with
-     * {@link #onRequestHealthCheck}.
-     *
-     * @return all packages supporting explicit health checks
-     */
-    @NonNull public abstract List<PackageConfig> onGetSupportedPackages();
-
-    /**
-     * Called when the system requests for all the packages that it has currently requested
-     * an explicit health check for.
-     *
-     * @return all packages expecting an explicit health check result
-     */
-    @NonNull public abstract List<String> onGetRequestedPackages();
-
-    private final Handler mHandler = Handler.createAsync(Looper.getMainLooper());
-    @Nullable private Consumer<Bundle> mHealthCheckResultCallback;
-    @Nullable private Executor mCallbackExecutor;
-
-    @Override
-    @NonNull
-    public final IBinder onBind(@NonNull Intent intent) {
-        return mWrapper;
-    }
-
-    /**
-     * Sets a callback to be invoked when an explicit health check passes for a package.
-     * <p>
-     * The callback will receive a {@link Bundle} containing the package name that passed the
-     * health check, identified by the key {@link #EXTRA_HEALTH_CHECK_PASSED_PACKAGE}.
-     * <p>
-     * <b>Note:</b> This API is primarily intended for testing purposes. Calling this outside of a
-     * test environment will override the default callback mechanism used to notify the system
-     * about health check results. Use with caution in production code.
-     *
-     * @param executor The executor on which the callback should be invoked. If {@code null}, the
-     *                 callback will be executed on the main thread.
-     * @param callback A callback that receives a {@link Bundle} containing the package name that
-     *                 passed the health check.
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_CRASHRECOVERY)
-    public final void setHealthCheckPassedCallback(@CallbackExecutor @Nullable Executor executor,
-            @Nullable Consumer<Bundle> callback) {
-        mCallbackExecutor = executor;
-        mHealthCheckResultCallback = callback;
-    }
-
-    private void executeCallback(@NonNull String packageName) {
-        if (mHealthCheckResultCallback != null) {
-            Objects.requireNonNull(packageName,
-                    "Package passing explicit health check must be non-null");
-            Bundle bundle = new Bundle();
-            bundle.putString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE, packageName);
-            mHealthCheckResultCallback.accept(bundle);
-        } else {
-            Log.wtf(TAG, "System missed explicit health check result for " + packageName);
-        }
-    }
-
-    /**
-     * Implementors should call this to notify the system when explicit health check passes
-     * for {@code packageName};
-     */
-    public final void notifyHealthCheckPassed(@NonNull String packageName) {
-        if (mCallbackExecutor != null) {
-            mCallbackExecutor.execute(() -> executeCallback(packageName));
-        } else {
-            mHandler.post(() -> executeCallback(packageName));
-        }
-    }
-
-    /**
-     * A PackageConfig contains a package supporting explicit health checks and the
-     * timeout in {@link System#uptimeMillis} across reboots after which health
-     * check requests from clients are failed.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final class PackageConfig implements Parcelable {
-        private static final long DEFAULT_HEALTH_CHECK_TIMEOUT_MILLIS = TimeUnit.HOURS.toMillis(1);
-
-        private final String mPackageName;
-        private final long mHealthCheckTimeoutMillis;
-
-        /**
-         * Creates a new instance.
-         *
-         * @param packageName the package name
-         * @param durationMillis the duration in milliseconds, must be greater than or
-         * equal to 0. If it is 0, it will use a system default value.
-         */
-        public PackageConfig(@NonNull String packageName, long healthCheckTimeoutMillis) {
-            mPackageName = Preconditions.checkNotNull(packageName);
-            if (healthCheckTimeoutMillis == 0) {
-                mHealthCheckTimeoutMillis = DEFAULT_HEALTH_CHECK_TIMEOUT_MILLIS;
-            } else {
-                mHealthCheckTimeoutMillis = Preconditions.checkArgumentNonnegative(
-                        healthCheckTimeoutMillis);
-            }
-        }
-
-        private PackageConfig(Parcel parcel) {
-            mPackageName = parcel.readString();
-            mHealthCheckTimeoutMillis = parcel.readLong();
-        }
-
-        /**
-         * Gets the package name.
-         *
-         * @return the package name
-         */
-        public @NonNull String getPackageName() {
-            return mPackageName;
-        }
-
-        /**
-         * Gets the timeout in milliseconds to evaluate an explicit health check result after a
-         * request.
-         *
-         * @return the duration in {@link System#uptimeMillis} across reboots
-         */
-        public long getHealthCheckTimeoutMillis() {
-            return mHealthCheckTimeoutMillis;
-        }
-
-        @NonNull
-        @Override
-        public String toString() {
-            return "PackageConfig{" + mPackageName + ", " + mHealthCheckTimeoutMillis + "}";
-        }
-
-        @Override
-        public boolean equals(@Nullable Object other) {
-            if (other == this) {
-                return true;
-            }
-            if (!(other instanceof PackageConfig)) {
-                return false;
-            }
-
-            PackageConfig otherInfo = (PackageConfig) other;
-            return Objects.equals(otherInfo.getHealthCheckTimeoutMillis(),
-                    mHealthCheckTimeoutMillis)
-                    && Objects.equals(otherInfo.getPackageName(), mPackageName);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mPackageName, mHealthCheckTimeoutMillis);
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(@SuppressLint({"MissingNullability"}) Parcel parcel, int flags) {
-            parcel.writeString(mPackageName);
-            parcel.writeLong(mHealthCheckTimeoutMillis);
-        }
-
-        public static final @NonNull Creator<PackageConfig> CREATOR = new Creator<PackageConfig>() {
-                @Override
-                public PackageConfig createFromParcel(Parcel source) {
-                    return new PackageConfig(source);
-                }
-
-                @Override
-                public PackageConfig[] newArray(int size) {
-                    return new PackageConfig[size];
-                }
-            };
-    }
-
-
-    private class ExplicitHealthCheckServiceWrapper extends IExplicitHealthCheckService.Stub {
-        @Override
-        public void setCallback(RemoteCallback callback) throws RemoteException {
-            mHandler.post(() -> mHealthCheckResultCallback = callback::sendResult);
-        }
-
-        @Override
-        public void request(String packageName) throws RemoteException {
-            mHandler.post(() -> ExplicitHealthCheckService.this.onRequestHealthCheck(packageName));
-        }
-
-        @Override
-        public void cancel(String packageName) throws RemoteException {
-            mHandler.post(() -> ExplicitHealthCheckService.this.onCancelHealthCheck(packageName));
-        }
-
-        @Override
-        public void getSupportedPackages(RemoteCallback callback) throws RemoteException {
-            mHandler.post(() -> {
-                List<PackageConfig> packages =
-                        ExplicitHealthCheckService.this.onGetSupportedPackages();
-                Objects.requireNonNull(packages, "Supported package list must be non-null");
-                Bundle bundle = new Bundle();
-                bundle.putParcelableArrayList(EXTRA_SUPPORTED_PACKAGES, new ArrayList<>(packages));
-                callback.sendResult(bundle);
-            });
-        }
-
-        @Override
-        public void getRequestedPackages(RemoteCallback callback) throws RemoteException {
-            mHandler.post(() -> {
-                List<String> packages =
-                        ExplicitHealthCheckService.this.onGetRequestedPackages();
-                Objects.requireNonNull(packages, "Requested  package list must be non-null");
-                Bundle bundle = new Bundle();
-                bundle.putStringArrayList(EXTRA_REQUESTED_PACKAGES, new ArrayList<>(packages));
-                callback.sendResult(bundle);
-            });
-        }
-    }
-}
diff --git a/packages/CrashRecovery/framework/java/android/service/watchdog/IExplicitHealthCheckService.aidl b/packages/CrashRecovery/framework/java/android/service/watchdog/IExplicitHealthCheckService.aidl
deleted file mode 100644
index 9096509..0000000
--- a/packages/CrashRecovery/framework/java/android/service/watchdog/IExplicitHealthCheckService.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.watchdog;
-
-import android.os.RemoteCallback;
-
-/**
- * @hide
- */
-@PermissionManuallyEnforced
-oneway interface IExplicitHealthCheckService
-{
-    void setCallback(in @nullable RemoteCallback callback);
-    void request(String packageName);
-    void cancel(String packageName);
-    void getSupportedPackages(in RemoteCallback callback);
-    void getRequestedPackages(in RemoteCallback callback);
-}
diff --git a/packages/CrashRecovery/framework/java/android/service/watchdog/OWNERS b/packages/CrashRecovery/framework/java/android/service/watchdog/OWNERS
deleted file mode 100644
index 1c045e1..0000000
--- a/packages/CrashRecovery/framework/java/android/service/watchdog/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-narayan@google.com
-nandana@google.com
-olilan@google.com
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/ExplicitHealthCheckController.java b/packages/CrashRecovery/services/module/java/com/android/server/ExplicitHealthCheckController.java
deleted file mode 100644
index da9a139..0000000
--- a/packages/CrashRecovery/services/module/java/com/android/server/ExplicitHealthCheckController.java
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_HEALTH_CHECK_PASSED_PACKAGE;
-import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_REQUESTED_PACKAGES;
-import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_SUPPORTED_PACKAGES;
-import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
-
-import android.Manifest;
-import android.annotation.MainThread;
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.os.IBinder;
-import android.os.RemoteCallback;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.service.watchdog.ExplicitHealthCheckService;
-import android.service.watchdog.IExplicitHealthCheckService;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.Slog;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.function.Consumer;
-
-// TODO(b/120598832): Add tests
-/**
- * Controls the connections with {@link ExplicitHealthCheckService}.
- */
-class ExplicitHealthCheckController {
-    private static final String TAG = "ExplicitHealthCheckController";
-    private final Object mLock = new Object();
-    private final Context mContext;
-
-    // Called everytime a package passes the health check, so the watchdog is notified of the
-    // passing check. In practice, should never be null after it has been #setEnabled.
-    // To prevent deadlocks between the controller and watchdog threads, we have
-    // a lock invariant to ALWAYS acquire the PackageWatchdog#mLock before #mLock in this class.
-    // It's easier to just NOT hold #mLock when calling into watchdog code on this consumer.
-    @GuardedBy("mLock") @Nullable private Consumer<String> mPassedConsumer;
-    // Called everytime after a successful #syncRequest call, so the watchdog can receive packages
-    // supporting health checks and update its internal state. In practice, should never be null
-    // after it has been #setEnabled.
-    // To prevent deadlocks between the controller and watchdog threads, we have
-    // a lock invariant to ALWAYS acquire the PackageWatchdog#mLock before #mLock in this class.
-    // It's easier to just NOT hold #mLock when calling into watchdog code on this consumer.
-    @GuardedBy("mLock") @Nullable private Consumer<List<PackageConfig>> mSupportedConsumer;
-    // Called everytime we need to notify the watchdog to sync requests between itself and the
-    // health check service. In practice, should never be null after it has been #setEnabled.
-    // To prevent deadlocks between the controller and watchdog threads, we have
-    // a lock invariant to ALWAYS acquire the PackageWatchdog#mLock before #mLock in this class.
-    // It's easier to just NOT hold #mLock when calling into watchdog code on this runnable.
-    @GuardedBy("mLock") @Nullable private Runnable mNotifySyncRunnable;
-    // Actual binder object to the explicit health check service.
-    @GuardedBy("mLock") @Nullable private IExplicitHealthCheckService mRemoteService;
-    // Connection to the explicit health check service, necessary to unbind.
-    // We should only try to bind if mConnection is null, non-null indicates we
-    // are connected or at least connecting.
-    @GuardedBy("mLock") @Nullable private ServiceConnection mConnection;
-    // Bind state of the explicit health check service.
-    @GuardedBy("mLock") private boolean mEnabled;
-
-    ExplicitHealthCheckController(Context context) {
-        mContext = context;
-    }
-
-    /** Enables or disables explicit health checks. */
-    public void setEnabled(boolean enabled) {
-        synchronized (mLock) {
-            Slog.i(TAG, "Explicit health checks " + (enabled ? "enabled." : "disabled."));
-            mEnabled = enabled;
-        }
-    }
-
-    /**
-     * Sets callbacks to listen to important events from the controller.
-     *
-     * <p> Should be called once at initialization before any other calls to the controller to
-     * ensure a happens-before relationship of the set parameters and visibility on other threads.
-     */
-    public void setCallbacks(Consumer<String> passedConsumer,
-            Consumer<List<PackageConfig>> supportedConsumer, Runnable notifySyncRunnable) {
-        synchronized (mLock) {
-            if (mPassedConsumer != null || mSupportedConsumer != null
-                    || mNotifySyncRunnable != null) {
-                Slog.wtf(TAG, "Resetting health check controller callbacks");
-            }
-
-            mPassedConsumer = Objects.requireNonNull(passedConsumer);
-            mSupportedConsumer = Objects.requireNonNull(supportedConsumer);
-            mNotifySyncRunnable = Objects.requireNonNull(notifySyncRunnable);
-        }
-    }
-
-    /**
-     * Calls the health check service to request or cancel packages based on
-     * {@code newRequestedPackages}.
-     *
-     * <p> Supported packages in {@code newRequestedPackages} that have not been previously
-     * requested will be requested while supported packages not in {@code newRequestedPackages}
-     * but were previously requested will be cancelled.
-     *
-     * <p> This handles binding and unbinding to the health check service as required.
-     *
-     * <p> Note, calling this may modify {@code newRequestedPackages}.
-     *
-     * <p> Note, this method is not thread safe, all calls should be serialized.
-     */
-    public void syncRequests(Set<String> newRequestedPackages) {
-        boolean enabled;
-        synchronized (mLock) {
-            enabled = mEnabled;
-        }
-
-        if (!enabled) {
-            Slog.i(TAG, "Health checks disabled, no supported packages");
-            // Call outside lock
-            mSupportedConsumer.accept(Collections.emptyList());
-            return;
-        }
-
-        getSupportedPackages(supportedPackageConfigs -> {
-            // Notify the watchdog without lock held
-            mSupportedConsumer.accept(supportedPackageConfigs);
-            getRequestedPackages(previousRequestedPackages -> {
-                synchronized (mLock) {
-                    // Hold lock so requests and cancellations are sent atomically.
-                    // It is important we don't mix requests from multiple threads.
-
-                    Set<String> supportedPackages = new ArraySet<>();
-                    for (PackageConfig config : supportedPackageConfigs) {
-                        supportedPackages.add(config.getPackageName());
-                    }
-                    // Note, this may modify newRequestedPackages
-                    newRequestedPackages.retainAll(supportedPackages);
-
-                    // Cancel packages no longer requested
-                    actOnDifference(previousRequestedPackages,
-                            newRequestedPackages, p -> cancel(p));
-                    // Request packages not yet requested
-                    actOnDifference(newRequestedPackages,
-                            previousRequestedPackages, p -> request(p));
-
-                    if (newRequestedPackages.isEmpty()) {
-                        Slog.i(TAG, "No more health check requests, unbinding...");
-                        unbindService();
-                        return;
-                    }
-                }
-            });
-        });
-    }
-
-    private void actOnDifference(Collection<String> collection1, Collection<String> collection2,
-            Consumer<String> action) {
-        Iterator<String> iterator = collection1.iterator();
-        while (iterator.hasNext()) {
-            String packageName = iterator.next();
-            if (!collection2.contains(packageName)) {
-                action.accept(packageName);
-            }
-        }
-    }
-
-    /**
-     * Requests an explicit health check for {@code packageName}.
-     * After this request, the callback registered on {@link #setCallbacks} can receive explicit
-     * health check passed results.
-     */
-    private void request(String packageName) {
-        synchronized (mLock) {
-            if (!prepareServiceLocked("request health check for " + packageName)) {
-                return;
-            }
-
-            Slog.i(TAG, "Requesting health check for package " + packageName);
-            try {
-                mRemoteService.request(packageName);
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Failed to request health check for package " + packageName, e);
-            }
-        }
-    }
-
-    /**
-     * Cancels all explicit health checks for {@code packageName}.
-     * After this request, the callback registered on {@link #setCallbacks} can no longer receive
-     * explicit health check passed results.
-     */
-    private void cancel(String packageName) {
-        synchronized (mLock) {
-            if (!prepareServiceLocked("cancel health check for " + packageName)) {
-                return;
-            }
-
-            Slog.i(TAG, "Cancelling health check for package " + packageName);
-            try {
-                mRemoteService.cancel(packageName);
-            } catch (RemoteException e) {
-                // Do nothing, if the service is down, when it comes up, we will sync requests,
-                // if there's some other error, retrying wouldn't fix anyways.
-                Slog.w(TAG, "Failed to cancel health check for package " + packageName, e);
-            }
-        }
-    }
-
-    /**
-     * Returns the packages that we can request explicit health checks for.
-     * The packages will be returned to the {@code consumer}.
-     */
-    private void getSupportedPackages(Consumer<List<PackageConfig>> consumer) {
-        synchronized (mLock) {
-            if (!prepareServiceLocked("get health check supported packages")) {
-                return;
-            }
-
-            Slog.d(TAG, "Getting health check supported packages");
-            try {
-                mRemoteService.getSupportedPackages(new RemoteCallback(result -> {
-                    List<PackageConfig> packages =
-                            result.getParcelableArrayList(EXTRA_SUPPORTED_PACKAGES, android.service.watchdog.ExplicitHealthCheckService.PackageConfig.class);
-                    Slog.i(TAG, "Explicit health check supported packages " + packages);
-                    consumer.accept(packages);
-                }));
-            } catch (RemoteException e) {
-                // Request failed, treat as if all observed packages are supported, if any packages
-                // expire during this period, we may incorrectly treat it as failing health checks
-                // even if we don't support health checks for the package.
-                Slog.w(TAG, "Failed to get health check supported packages", e);
-            }
-        }
-    }
-
-    /**
-     * Returns the packages for which health checks are currently in progress.
-     * The packages will be returned to the {@code consumer}.
-     */
-    private void getRequestedPackages(Consumer<List<String>> consumer) {
-        synchronized (mLock) {
-            if (!prepareServiceLocked("get health check requested packages")) {
-                return;
-            }
-
-            Slog.d(TAG, "Getting health check requested packages");
-            try {
-                mRemoteService.getRequestedPackages(new RemoteCallback(result -> {
-                    List<String> packages = result.getStringArrayList(EXTRA_REQUESTED_PACKAGES);
-                    Slog.i(TAG, "Explicit health check requested packages " + packages);
-                    consumer.accept(packages);
-                }));
-            } catch (RemoteException e) {
-                // Request failed, treat as if we haven't requested any packages, if any packages
-                // were actually requested, they will not be cancelled now. May be cancelled later
-                Slog.w(TAG, "Failed to get health check requested packages", e);
-            }
-        }
-    }
-
-    /**
-     * Binds to the explicit health check service if the controller is enabled and
-     * not already bound.
-     */
-    private void bindService() {
-        synchronized (mLock) {
-            if (!mEnabled || mConnection != null || mRemoteService != null) {
-                if (!mEnabled) {
-                    Slog.i(TAG, "Not binding to service, service disabled");
-                } else if (mRemoteService != null) {
-                    Slog.i(TAG, "Not binding to service, service already connected");
-                } else {
-                    Slog.i(TAG, "Not binding to service, service already connecting");
-                }
-                return;
-            }
-            ComponentName component = getServiceComponentNameLocked();
-            if (component == null) {
-                Slog.wtf(TAG, "Explicit health check service not found");
-                return;
-            }
-
-            Intent intent = new Intent();
-            intent.setComponent(component);
-            mConnection = new ServiceConnection() {
-                @Override
-                public void onServiceConnected(ComponentName name, IBinder service) {
-                    Slog.i(TAG, "Explicit health check service is connected " + name);
-                    initState(service);
-                }
-
-                @Override
-                @MainThread
-                public void onServiceDisconnected(ComponentName name) {
-                    // Service crashed or process was killed, #onServiceConnected will be called.
-                    // Don't need to re-bind.
-                    Slog.i(TAG, "Explicit health check service is disconnected " + name);
-                    synchronized (mLock) {
-                        mRemoteService = null;
-                    }
-                }
-
-                @Override
-                public void onBindingDied(ComponentName name) {
-                    // Application hosting service probably got updated
-                    // Need to re-bind.
-                    Slog.i(TAG, "Explicit health check service binding is dead. Rebind: " + name);
-                    unbindService();
-                    bindService();
-                }
-
-                @Override
-                public void onNullBinding(ComponentName name) {
-                    // Should never happen. Service returned null from #onBind.
-                    Slog.wtf(TAG, "Explicit health check service binding is null?? " + name);
-                }
-            };
-
-            mContext.bindServiceAsUser(intent, mConnection,
-                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
-            Slog.i(TAG, "Explicit health check service is bound");
-        }
-    }
-
-    /** Unbinds the explicit health check service. */
-    private void unbindService() {
-        synchronized (mLock) {
-            if (mRemoteService != null) {
-                mContext.unbindService(mConnection);
-                mRemoteService = null;
-                mConnection = null;
-            }
-            Slog.i(TAG, "Explicit health check service is unbound");
-        }
-    }
-
-    @GuardedBy("mLock")
-    @Nullable
-    private ServiceInfo getServiceInfoLocked() {
-        final Intent intent = new Intent(ExplicitHealthCheckService.SERVICE_INTERFACE);
-        final ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent,
-                PackageManager.GET_SERVICES | PackageManager.GET_META_DATA
-                        |  PackageManager.MATCH_SYSTEM_ONLY);
-        if (resolveInfo == null || resolveInfo.serviceInfo == null) {
-            Slog.w(TAG, "No valid components found.");
-            return null;
-        }
-        return resolveInfo.serviceInfo;
-    }
-
-    @GuardedBy("mLock")
-    @Nullable
-    private ComponentName getServiceComponentNameLocked() {
-        final ServiceInfo serviceInfo = getServiceInfoLocked();
-        if (serviceInfo == null) {
-            return null;
-        }
-
-        final ComponentName name = new ComponentName(serviceInfo.packageName, serviceInfo.name);
-        if (!Manifest.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE
-                .equals(serviceInfo.permission)) {
-            Slog.w(TAG, name.flattenToShortString() + " does not require permission "
-                    + Manifest.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE);
-            return null;
-        }
-        return name;
-    }
-
-    private void initState(IBinder service) {
-        synchronized (mLock) {
-            if (!mEnabled) {
-                Slog.w(TAG, "Attempting to connect disabled service?? Unbinding...");
-                // Very unlikely, but we disabled the service after binding but before we connected
-                unbindService();
-                return;
-            }
-            mRemoteService = IExplicitHealthCheckService.Stub.asInterface(service);
-            try {
-                mRemoteService.setCallback(new RemoteCallback(result -> {
-                    String packageName = result.getString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE);
-                    if (!TextUtils.isEmpty(packageName)) {
-                        if (mPassedConsumer == null) {
-                            Slog.wtf(TAG, "Health check passed for package " + packageName
-                                    + "but no consumer registered.");
-                        } else {
-                            // Call without lock held
-                            mPassedConsumer.accept(packageName);
-                        }
-                    } else {
-                        Slog.wtf(TAG, "Empty package passed explicit health check?");
-                    }
-                }));
-                Slog.i(TAG, "Service initialized, syncing requests");
-            } catch (RemoteException e) {
-                Slog.wtf(TAG, "Could not setCallback on explicit health check service");
-            }
-        }
-        // Calling outside lock
-        mNotifySyncRunnable.run();
-    }
-
-    /**
-     * Prepares the health check service to receive requests.
-     *
-     * @return {@code true} if it is ready and we can proceed with a request,
-     * {@code false} otherwise. If it is not ready, and the service is enabled,
-     * we will bind and the request should be automatically attempted later.
-     */
-    @GuardedBy("mLock")
-    private boolean prepareServiceLocked(String action) {
-        if (mRemoteService != null && mEnabled) {
-            return true;
-        }
-        Slog.i(TAG, "Service not ready to " + action
-                + (mEnabled ? ". Binding..." : ". Disabled"));
-        if (mEnabled) {
-            bindService();
-        }
-        return false;
-    }
-}
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
deleted file mode 100644
index e4f07f9..0000000
--- a/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
+++ /dev/null
@@ -1,2253 +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.server;
-
-import static android.content.Intent.ACTION_REBOOT;
-import static android.content.Intent.ACTION_SHUTDOWN;
-import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
-import static android.util.Xml.Encoding.UTF_8;
-
-import static com.android.server.crashrecovery.CrashRecoveryUtils.dumpCrashRecoveryEvents;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.annotation.CallbackExecutor;
-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.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.VersionedPackage;
-import android.crashrecovery.flags.Flags;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Process;
-import android.os.SystemProperties;
-import android.provider.DeviceConfig;
-import android.sysprop.CrashRecoveryProperties;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.AtomicFile;
-import android.util.EventLog;
-import android.util.IndentingPrintWriter;
-import android.util.LongArrayQueue;
-import android.util.Slog;
-import android.util.Xml;
-import android.util.XmlUtils;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FastXmlSerializer;
-import com.android.modules.utils.BackgroundThread;
-
-import libcore.io.IoUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Monitors the health of packages on the system and notifies interested observers when packages
- * fail. On failure, the registered observer with the least user impacting mitigation will
- * be notified.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_ENABLE_CRASHRECOVERY)
-@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-public class PackageWatchdog {
-    private static final String TAG = "PackageWatchdog";
-
-    static final String PROPERTY_WATCHDOG_TRIGGER_DURATION_MILLIS =
-            "watchdog_trigger_failure_duration_millis";
-    static final String PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT =
-            "watchdog_trigger_failure_count";
-    static final String PROPERTY_WATCHDOG_EXPLICIT_HEALTH_CHECK_ENABLED =
-            "watchdog_explicit_health_check_enabled";
-
-    // TODO: make the following values configurable via DeviceConfig
-    private static final long NATIVE_CRASH_POLLING_INTERVAL_MILLIS =
-            TimeUnit.SECONDS.toMillis(30);
-    private static final long NUMBER_OF_NATIVE_CRASH_POLLS = 10;
-
-
-    /** Reason for package failure could not be determined. */
-    public static final int FAILURE_REASON_UNKNOWN = 0;
-
-    /** The package had a native crash. */
-    public static final int FAILURE_REASON_NATIVE_CRASH = 1;
-
-    /** The package failed an explicit health check. */
-    public static final int FAILURE_REASON_EXPLICIT_HEALTH_CHECK = 2;
-
-    /** The app crashed. */
-    public static final int FAILURE_REASON_APP_CRASH = 3;
-
-    /** The app was not responding. */
-    public static final int FAILURE_REASON_APP_NOT_RESPONDING = 4;
-
-    /** The device was boot looping. */
-    public static final int FAILURE_REASON_BOOT_LOOP = 5;
-
-    /** @hide */
-    @IntDef(prefix = { "FAILURE_REASON_" }, value = {
-            FAILURE_REASON_UNKNOWN,
-            FAILURE_REASON_NATIVE_CRASH,
-            FAILURE_REASON_EXPLICIT_HEALTH_CHECK,
-            FAILURE_REASON_APP_CRASH,
-            FAILURE_REASON_APP_NOT_RESPONDING,
-            FAILURE_REASON_BOOT_LOOP
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface FailureReasons {}
-
-    // Duration to count package failures before it resets to 0
-    @VisibleForTesting
-    static final int DEFAULT_TRIGGER_FAILURE_DURATION_MS =
-            (int) TimeUnit.MINUTES.toMillis(1);
-    // Number of package failures within the duration above before we notify observers
-    @VisibleForTesting
-    static final int DEFAULT_TRIGGER_FAILURE_COUNT = 5;
-    @VisibleForTesting
-    static final long DEFAULT_OBSERVING_DURATION_MS = TimeUnit.DAYS.toMillis(2);
-    // Sliding window for tracking how many mitigation calls were made for a package.
-    @VisibleForTesting
-    static final long DEFAULT_DEESCALATION_WINDOW_MS = TimeUnit.HOURS.toMillis(1);
-    // Whether explicit health checks are enabled or not
-    private static final boolean DEFAULT_EXPLICIT_HEALTH_CHECK_ENABLED = true;
-
-    @VisibleForTesting
-    static final int DEFAULT_BOOT_LOOP_TRIGGER_COUNT = 5;
-
-    static final long DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS = TimeUnit.MINUTES.toMillis(10);
-
-    // Time needed to apply mitigation
-    private static final String MITIGATION_WINDOW_MS =
-            "persist.device_config.configuration.mitigation_window_ms";
-    @VisibleForTesting
-    static final long DEFAULT_MITIGATION_WINDOW_MS = TimeUnit.SECONDS.toMillis(5);
-
-    // Threshold level at which or above user might experience significant disruption.
-    private static final String MAJOR_USER_IMPACT_LEVEL_THRESHOLD =
-            "persist.device_config.configuration.major_user_impact_level_threshold";
-    private static final int DEFAULT_MAJOR_USER_IMPACT_LEVEL_THRESHOLD =
-            PackageHealthObserverImpact.USER_IMPACT_LEVEL_71;
-
-    // Comma separated list of all packages exempt from user impact level threshold. If a package
-    // in the list is crash looping, all the mitigations including factory reset will be performed.
-    private static final String PACKAGES_EXEMPT_FROM_IMPACT_LEVEL_THRESHOLD =
-            "persist.device_config.configuration.packages_exempt_from_impact_level_threshold";
-
-    // Comma separated list of default packages exempt from user impact level threshold.
-    private static final String DEFAULT_PACKAGES_EXEMPT_FROM_IMPACT_LEVEL_THRESHOLD =
-            "com.android.systemui";
-
-    private long mNumberOfNativeCrashPollsRemaining;
-
-    private static final int DB_VERSION = 1;
-    private static final String TAG_PACKAGE_WATCHDOG = "package-watchdog";
-    private static final String TAG_PACKAGE = "package";
-    private static final String TAG_OBSERVER = "observer";
-    private static final String ATTR_VERSION = "version";
-    private static final String ATTR_NAME = "name";
-    private static final String ATTR_DURATION = "duration";
-    private static final String ATTR_EXPLICIT_HEALTH_CHECK_DURATION = "health-check-duration";
-    private static final String ATTR_PASSED_HEALTH_CHECK = "passed-health-check";
-    private static final String ATTR_MITIGATION_CALLS = "mitigation-calls";
-    private static final String ATTR_MITIGATION_COUNT = "mitigation-count";
-
-    // A file containing information about the current mitigation count in the case of a boot loop.
-    // This allows boot loop information to persist in the case of an fs-checkpoint being
-    // aborted.
-    private static final String METADATA_FILE = "/metadata/watchdog/mitigation_count.txt";
-
-    /**
-     * EventLog tags used when logging into the event log. Note the values must be sync with
-     * frameworks/base/services/core/java/com/android/server/EventLogTags.logtags to get correct
-     * name translation.
-     */
-    private static final int LOG_TAG_RESCUE_NOTE = 2900;
-
-    private static final Object sPackageWatchdogLock = new Object();
-    @GuardedBy("sPackageWatchdogLock")
-    private static PackageWatchdog sPackageWatchdog;
-
-    private static final Object sLock = new Object();
-    // System server context
-    private final Context mContext;
-    // Handler to run short running tasks
-    private final Handler mShortTaskHandler;
-    // Handler for processing IO and long running tasks
-    private final Handler mLongTaskHandler;
-    // Contains (observer-name -> observer-handle) that have ever been registered from
-    // previous boots. Observers with all packages expired are periodically pruned.
-    // It is saved to disk on system shutdown and repouplated on startup so it survives reboots.
-    @GuardedBy("sLock")
-    private final ArrayMap<String, ObserverInternal> mAllObservers = new ArrayMap<>();
-    // File containing the XML data of monitored packages /data/system/package-watchdog.xml
-    private final AtomicFile mPolicyFile;
-    private final ExplicitHealthCheckController mHealthCheckController;
-    private final Runnable mSyncRequests = this::syncRequests;
-    private final Runnable mSyncStateWithScheduledReason = this::syncStateWithScheduledReason;
-    private final Runnable mSaveToFile = this::saveToFile;
-    private final SystemClock mSystemClock;
-    private final BootThreshold mBootThreshold;
-    private final DeviceConfig.OnPropertiesChangedListener
-            mOnPropertyChangedListener = this::onPropertyChanged;
-
-    private final Set<String> mPackagesExemptFromImpactLevelThreshold = new ArraySet<>();
-
-    // The set of packages that have been synced with the ExplicitHealthCheckController
-    @GuardedBy("sLock")
-    private Set<String> mRequestedHealthCheckPackages = new ArraySet<>();
-    @GuardedBy("sLock")
-    private boolean mIsPackagesReady;
-    // Flag to control whether explicit health checks are supported or not
-    @GuardedBy("sLock")
-    private boolean mIsHealthCheckEnabled = DEFAULT_EXPLICIT_HEALTH_CHECK_ENABLED;
-    @GuardedBy("sLock")
-    private int mTriggerFailureDurationMs = DEFAULT_TRIGGER_FAILURE_DURATION_MS;
-    @GuardedBy("sLock")
-    private int mTriggerFailureCount = DEFAULT_TRIGGER_FAILURE_COUNT;
-    // SystemClock#uptimeMillis when we last executed #syncState
-    // 0 if no prune is scheduled.
-    @GuardedBy("sLock")
-    private long mUptimeAtLastStateSync;
-    // If true, sync explicit health check packages with the ExplicitHealthCheckController.
-    @GuardedBy("sLock")
-    private boolean mSyncRequired = false;
-
-    @GuardedBy("sLock")
-    private long mLastMitigation = -1000000;
-
-    @FunctionalInterface
-    @VisibleForTesting
-    interface SystemClock {
-        long uptimeMillis();
-    }
-
-    private PackageWatchdog(Context context) {
-        // Needs to be constructed inline
-        this(context, new AtomicFile(
-                        new File(new File(Environment.getDataDirectory(), "system"),
-                                "package-watchdog.xml")),
-                new Handler(Looper.myLooper()), BackgroundThread.getHandler(),
-                new ExplicitHealthCheckController(context),
-                android.os.SystemClock::uptimeMillis);
-    }
-
-    /**
-     * Creates a PackageWatchdog that allows injecting dependencies.
-     */
-    @VisibleForTesting
-    PackageWatchdog(Context context, AtomicFile policyFile, Handler shortTaskHandler,
-            Handler longTaskHandler, ExplicitHealthCheckController controller,
-            SystemClock clock) {
-        mContext = context;
-        mPolicyFile = policyFile;
-        mShortTaskHandler = shortTaskHandler;
-        mLongTaskHandler = longTaskHandler;
-        mHealthCheckController = controller;
-        mSystemClock = clock;
-        mNumberOfNativeCrashPollsRemaining = NUMBER_OF_NATIVE_CRASH_POLLS;
-        mBootThreshold = new BootThreshold(DEFAULT_BOOT_LOOP_TRIGGER_COUNT,
-                DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS);
-
-        loadFromFile();
-        sPackageWatchdog = this;
-    }
-
-    /**
-     * Creates or gets singleton instance of PackageWatchdog.
-     *
-     * @param context The system server context.
-     */
-    public static  @NonNull PackageWatchdog getInstance(@NonNull Context context) {
-        synchronized (sPackageWatchdogLock) {
-            if (sPackageWatchdog == null) {
-                new PackageWatchdog(context);
-            }
-            return sPackageWatchdog;
-        }
-    }
-
-    /**
-     * Called during boot to notify when packages are ready on the device so we can start
-     * binding.
-     * @hide
-     */
-    public void onPackagesReady() {
-        synchronized (sLock) {
-            mIsPackagesReady = true;
-            mHealthCheckController.setCallbacks(packageName -> onHealthCheckPassed(packageName),
-                    packages -> onSupportedPackages(packages),
-                    this::onSyncRequestNotified);
-            setPropertyChangedListenerLocked();
-            updateConfigs();
-        }
-    }
-
-    /**
-     * Registers {@code observer} to listen for package failures. Add a new ObserverInternal for
-     * this observer if it does not already exist.
-     * For executing mitigations observers will receive callback on the given executor.
-     *
-     * <p>Observers are expected to call this on boot. It does not specify any packages but
-     * it will resume observing any packages requested from a previous boot.
-     *
-     * @param observer instance of {@link PackageHealthObserver} for observing package failures
-     *                 and boot loops.
-     * @param executor Executor for the thread on which observers would receive callbacks
-     */
-    public void registerHealthObserver(@NonNull @CallbackExecutor Executor executor,
-            @NonNull PackageHealthObserver observer) {
-        synchronized (sLock) {
-            ObserverInternal internalObserver = mAllObservers.get(observer.getUniqueIdentifier());
-            if (internalObserver != null) {
-                internalObserver.registeredObserver = observer;
-                internalObserver.observerExecutor = executor;
-            } else {
-                internalObserver = new ObserverInternal(observer.getUniqueIdentifier(),
-                        new ArrayList<>());
-                internalObserver.registeredObserver = observer;
-                internalObserver.observerExecutor = executor;
-                mAllObservers.put(observer.getUniqueIdentifier(), internalObserver);
-                syncState("added new observer");
-            }
-        }
-    }
-
-    /**
-     * Starts observing the health of the {@code packages} for {@code observer}.
-     * Note: Observer needs to be registered with {@link #registerHealthObserver} before calling
-     * this API.
-     *
-     * <p>If monitoring a package supporting explicit health check, at the end of the monitoring
-     * duration if {@link #onHealthCheckPassed} was never called,
-     * {@link PackageHealthObserver#onExecuteHealthCheckMitigation} will be called as if the
-     * package failed.
-     *
-     * <p>If {@code observer} is already monitoring a package in {@code packageNames},
-     * the monitoring window of that package will be reset to {@code durationMs} and the health
-     * check state will be reset to a default.
-     *
-     * <p>The {@code observer} must be registered with {@link #registerHealthObserver} before
-     * calling this method.
-     *
-     * @param packageNames The list of packages to check. If this is empty, the call will be a
-     *                     no-op.
-     *
-     * @param timeoutMs The timeout after which Explicit Health Checks would not run. If this is
-     *                  less than 1, a default monitoring duration 2 days will be used.
-     *
-     * @throws IllegalStateException if the observer was not previously registered
-     */
-    public void startExplicitHealthCheck(@NonNull List<String> packageNames, long timeoutMs,
-            @NonNull PackageHealthObserver observer) {
-        synchronized (sLock) {
-            if (!mAllObservers.containsKey(observer.getUniqueIdentifier())) {
-                Slog.wtf(TAG, "No observer found, need to register the observer: "
-                        + observer.getUniqueIdentifier());
-                throw new IllegalStateException("Observer not registered");
-            }
-        }
-        if (packageNames.isEmpty()) {
-            Slog.wtf(TAG, "No packages to observe, " + observer.getUniqueIdentifier());
-            return;
-        }
-        if (timeoutMs < 1) {
-            Slog.wtf(TAG, "Invalid duration " + timeoutMs + "ms for observer "
-                    + observer.getUniqueIdentifier() + ". Not observing packages " + packageNames);
-            timeoutMs = DEFAULT_OBSERVING_DURATION_MS;
-        }
-
-        List<MonitoredPackage> packages = new ArrayList<>();
-        for (int i = 0; i < packageNames.size(); i++) {
-            // Health checks not available yet so health check state will start INACTIVE
-            MonitoredPackage pkg = newMonitoredPackage(packageNames.get(i), timeoutMs, false);
-            if (pkg != null) {
-                packages.add(pkg);
-            } else {
-                Slog.w(TAG, "Failed to create MonitoredPackage for pkg=" + packageNames.get(i));
-            }
-        }
-
-        if (packages.isEmpty()) {
-            return;
-        }
-
-        // Sync before we add the new packages to the observers. This will #pruneObservers,
-        // causing any elapsed time to be deducted from all existing packages before we add new
-        // packages. This maintains the invariant that the elapsed time for ALL (new and existing)
-        // packages is the same.
-        mLongTaskHandler.post(() -> {
-            syncState("observing new packages");
-
-            synchronized (sLock) {
-                ObserverInternal oldObserver = mAllObservers.get(observer.getUniqueIdentifier());
-                if (oldObserver == null) {
-                    Slog.d(TAG, observer.getUniqueIdentifier() + " started monitoring health "
-                            + "of packages " + packageNames);
-                    mAllObservers.put(observer.getUniqueIdentifier(),
-                            new ObserverInternal(observer.getUniqueIdentifier(), packages));
-                } else {
-                    Slog.d(TAG, observer.getUniqueIdentifier() + " added the following "
-                            + "packages to monitor " + packageNames);
-                    oldObserver.updatePackagesLocked(packages);
-                }
-            }
-
-            // Sync after we add the new packages to the observers. We may have received packges
-            // requiring an earlier schedule than we are currently scheduled for.
-            syncState("updated observers");
-        });
-
-    }
-
-    /**
-     * Unregisters {@code observer} from listening to package failure.
-     * Additionally, this stops observing any packages that may have previously been observed
-     * even from a previous boot.
-     */
-    public void unregisterHealthObserver(@NonNull PackageHealthObserver observer) {
-        mLongTaskHandler.post(() -> {
-            synchronized (sLock) {
-                mAllObservers.remove(observer.getUniqueIdentifier());
-            }
-            syncState("unregistering observer: " + observer.getUniqueIdentifier());
-        });
-    }
-
-    /**
-     * Called when a process fails due to a crash, ANR or explicit health check.
-     *
-     * <p>For each package contained in the process, one registered observer with the least user
-     * impact will be notified for mitigation.
-     *
-     * <p>This method could be called frequently if there is a severe problem on the device.
-     */
-    public void notifyPackageFailure(@NonNull List<VersionedPackage> packages,
-            @FailureReasons int failureReason) {
-        if (packages == null) {
-            Slog.w(TAG, "Could not resolve a list of failing packages");
-            return;
-        }
-        synchronized (sLock) {
-            final long now = mSystemClock.uptimeMillis();
-            if (Flags.recoverabilityDetection()) {
-                if (now >= mLastMitigation
-                        && (now - mLastMitigation) < getMitigationWindowMs()) {
-                    Slog.i(TAG, "Skipping notifyPackageFailure mitigation");
-                    return;
-                }
-            }
-        }
-        mLongTaskHandler.post(() -> {
-            synchronized (sLock) {
-                if (mAllObservers.isEmpty()) {
-                    return;
-                }
-                boolean requiresImmediateAction = (failureReason == FAILURE_REASON_NATIVE_CRASH
-                        || failureReason == FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
-                if (requiresImmediateAction) {
-                    handleFailureImmediately(packages, failureReason);
-                } else {
-                    for (int pIndex = 0; pIndex < packages.size(); pIndex++) {
-                        VersionedPackage versionedPackage = packages.get(pIndex);
-                        // Observer that will receive failure for versionedPackage
-                        ObserverInternal currentObserverToNotify = null;
-                        int currentObserverImpact = Integer.MAX_VALUE;
-                        MonitoredPackage currentMonitoredPackage = null;
-
-                        // Find observer with least user impact
-                        for (int oIndex = 0; oIndex < mAllObservers.size(); oIndex++) {
-                            ObserverInternal observer = mAllObservers.valueAt(oIndex);
-                            PackageHealthObserver registeredObserver = observer.registeredObserver;
-                            if (registeredObserver != null
-                                    && observer.notifyPackageFailureLocked(
-                                    versionedPackage.getPackageName())) {
-                                MonitoredPackage p = observer.getMonitoredPackage(
-                                        versionedPackage.getPackageName());
-                                int mitigationCount = 1;
-                                if (p != null) {
-                                    mitigationCount = p.getMitigationCountLocked() + 1;
-                                }
-                                int impact = registeredObserver.onHealthCheckFailed(
-                                        versionedPackage, failureReason, mitigationCount);
-                                if (impact != PackageHealthObserverImpact.USER_IMPACT_LEVEL_0
-                                        && impact < currentObserverImpact) {
-                                    currentObserverToNotify = observer;
-                                    currentObserverImpact = impact;
-                                    currentMonitoredPackage = p;
-                                }
-                            }
-                        }
-
-                        // Execute action with least user impact
-                        if (currentObserverToNotify != null) {
-                            int mitigationCount;
-                            if (currentMonitoredPackage != null) {
-                                currentMonitoredPackage.noteMitigationCallLocked();
-                                mitigationCount =
-                                        currentMonitoredPackage.getMitigationCountLocked();
-                            } else {
-                                mitigationCount = 1;
-                            }
-                            if (Flags.recoverabilityDetection()) {
-                                maybeExecute(currentObserverToNotify, versionedPackage,
-                                        failureReason, currentObserverImpact, mitigationCount);
-                            } else {
-                                PackageHealthObserver registeredObserver =
-                                        currentObserverToNotify.registeredObserver;
-                                currentObserverToNotify.observerExecutor.execute(() ->
-                                        registeredObserver.onExecuteHealthCheckMitigation(
-                                                versionedPackage, failureReason, mitigationCount));
-                            }
-                        }
-                    }
-                }
-            }
-        });
-    }
-
-    /**
-     * For native crashes or explicit health check failures, call directly into each observer to
-     * mitigate the error without going through failure threshold logic.
-     */
-    @GuardedBy("sLock")
-    private void handleFailureImmediately(List<VersionedPackage> packages,
-            @FailureReasons int failureReason) {
-        VersionedPackage failingPackage = packages.size() > 0 ? packages.get(0) : null;
-        ObserverInternal currentObserverToNotify = null;
-        int currentObserverImpact = Integer.MAX_VALUE;
-        for (ObserverInternal observer: mAllObservers.values()) {
-            PackageHealthObserver registeredObserver = observer.registeredObserver;
-            if (registeredObserver != null) {
-                int impact = registeredObserver.onHealthCheckFailed(
-                        failingPackage, failureReason, 1);
-                if (impact != PackageHealthObserverImpact.USER_IMPACT_LEVEL_0
-                        && impact < currentObserverImpact) {
-                    currentObserverToNotify = observer;
-                    currentObserverImpact = impact;
-                }
-            }
-        }
-        if (currentObserverToNotify != null) {
-            if (Flags.recoverabilityDetection()) {
-                maybeExecute(currentObserverToNotify, failingPackage, failureReason,
-                        currentObserverImpact, /*mitigationCount=*/ 1);
-            } else {
-                PackageHealthObserver registeredObserver =
-                        currentObserverToNotify.registeredObserver;
-                currentObserverToNotify.observerExecutor.execute(() ->
-                        registeredObserver.onExecuteHealthCheckMitigation(failingPackage,
-                                failureReason, 1));
-
-            }
-        }
-    }
-
-    private void maybeExecute(ObserverInternal currentObserverToNotify,
-                              VersionedPackage versionedPackage,
-                              @FailureReasons int failureReason,
-                              int currentObserverImpact,
-                              int mitigationCount) {
-        if (allowMitigations(currentObserverImpact, versionedPackage)) {
-            PackageHealthObserver registeredObserver;
-            synchronized (sLock) {
-                mLastMitigation = mSystemClock.uptimeMillis();
-                registeredObserver = currentObserverToNotify.registeredObserver;
-            }
-            currentObserverToNotify.observerExecutor.execute(() ->
-                    registeredObserver.onExecuteHealthCheckMitigation(versionedPackage,
-                            failureReason, mitigationCount));
-        }
-    }
-
-    private boolean allowMitigations(int currentObserverImpact,
-            VersionedPackage versionedPackage) {
-        return currentObserverImpact < getUserImpactLevelLimit()
-                || getPackagesExemptFromImpactLevelThreshold().contains(
-                versionedPackage.getPackageName());
-    }
-
-    private long getMitigationWindowMs() {
-        return SystemProperties.getLong(MITIGATION_WINDOW_MS, DEFAULT_MITIGATION_WINDOW_MS);
-    }
-
-
-    /**
-     * Called when the system server boots. If the system server is detected to be in a boot loop,
-     * query each observer and perform the mitigation action with the lowest user impact.
-     *
-     * Note: PackageWatchdog considers system_server restart loop as bootloop. Full reboots
-     * are not counted in bootloop.
-     * @hide
-     */
-    @SuppressWarnings("GuardedBy")
-    public void noteBoot() {
-        synchronized (sLock) {
-            // if boot count has reached threshold, start mitigation.
-            // We wait until threshold number of restarts only for the first time. Perform
-            // mitigations for every restart after that.
-            boolean mitigate = mBootThreshold.incrementAndTest();
-            if (mitigate) {
-                if (!Flags.recoverabilityDetection()) {
-                    mBootThreshold.reset();
-                }
-                int mitigationCount = mBootThreshold.getMitigationCount() + 1;
-                ObserverInternal currentObserverToNotify = null;
-                int currentObserverImpact = Integer.MAX_VALUE;
-                for (int i = 0; i < mAllObservers.size(); i++) {
-                    final ObserverInternal observer = mAllObservers.valueAt(i);
-                    PackageHealthObserver registeredObserver = observer.registeredObserver;
-                    if (registeredObserver != null) {
-                        int impact = Flags.recoverabilityDetection()
-                                ? registeredObserver.onBootLoop(
-                                        observer.getBootMitigationCount() + 1)
-                                : registeredObserver.onBootLoop(mitigationCount);
-                        if (impact != PackageHealthObserverImpact.USER_IMPACT_LEVEL_0
-                                && impact < currentObserverImpact) {
-                            currentObserverToNotify = observer;
-                            currentObserverImpact = impact;
-                        }
-                    }
-                }
-
-                if (currentObserverToNotify != null) {
-                    PackageHealthObserver registeredObserver =
-                            currentObserverToNotify.registeredObserver;
-                    if (Flags.recoverabilityDetection()) {
-                        int currentObserverMitigationCount =
-                                currentObserverToNotify.getBootMitigationCount() + 1;
-                        currentObserverToNotify.setBootMitigationCount(
-                                currentObserverMitigationCount);
-                        saveAllObserversBootMitigationCountToMetadata(METADATA_FILE);
-                        currentObserverToNotify.observerExecutor
-                                .execute(() -> registeredObserver.onExecuteBootLoopMitigation(
-                                        currentObserverMitigationCount));
-                    } else {
-                        mBootThreshold.setMitigationCount(mitigationCount);
-                        mBootThreshold.saveMitigationCountToMetadata();
-                        currentObserverToNotify.observerExecutor
-                                .execute(() -> registeredObserver.onExecuteBootLoopMitigation(
-                                        mitigationCount));
-
-                    }
-                }
-            }
-        }
-    }
-
-    // TODO(b/120598832): Optimize write? Maybe only write a separate smaller file? Also
-    // avoid holding lock?
-    // This currently adds about 7ms extra to shutdown thread
-    /** @hide Writes the package information to file during shutdown. */
-    public void writeNow() {
-        synchronized (sLock) {
-            // Must only run synchronous tasks as this runs on the ShutdownThread and no other
-            // thread is guaranteed to run during shutdown.
-            if (!mAllObservers.isEmpty()) {
-                mLongTaskHandler.removeCallbacks(mSaveToFile);
-                pruneObserversLocked();
-                saveToFile();
-                Slog.i(TAG, "Last write to update package durations");
-            }
-        }
-    }
-
-    /**
-     * Enables or disables explicit health checks.
-     * <p> If explicit health checks are enabled, the health check service is started.
-     * <p> If explicit health checks are disabled, pending explicit health check requests are
-     * passed and the health check service is stopped.
-     */
-    private void setExplicitHealthCheckEnabled(boolean enabled) {
-        synchronized (sLock) {
-            mIsHealthCheckEnabled = enabled;
-            mHealthCheckController.setEnabled(enabled);
-            mSyncRequired = true;
-            // Prune to update internal state whenever health check is enabled/disabled
-            syncState("health check state " + (enabled ? "enabled" : "disabled"));
-        }
-    }
-
-    /**
-     * This method should be only called on mShortTaskHandler, since it modifies
-     * {@link #mNumberOfNativeCrashPollsRemaining}.
-     */
-    private void checkAndMitigateNativeCrashes() {
-        mNumberOfNativeCrashPollsRemaining--;
-        // Check if native watchdog reported a crash
-        if ("1".equals(SystemProperties.get("sys.init.updatable_crashing"))) {
-            // We rollback all available low impact rollbacks when crash is unattributable
-            notifyPackageFailure(Collections.EMPTY_LIST, FAILURE_REASON_NATIVE_CRASH);
-            // we stop polling after an attempt to execute rollback, regardless of whether the
-            // attempt succeeds or not
-        } else {
-            if (mNumberOfNativeCrashPollsRemaining > 0) {
-                mShortTaskHandler.postDelayed(() -> checkAndMitigateNativeCrashes(),
-                        NATIVE_CRASH_POLLING_INTERVAL_MILLIS);
-            }
-        }
-    }
-
-    /**
-     * Since this method can eventually trigger a rollback, it should be called
-     * only once boot has completed {@code onBootCompleted} and not earlier, because the install
-     * session must be entirely completed before we try to rollback.
-     * @hide
-     */
-    public void scheduleCheckAndMitigateNativeCrashes() {
-        Slog.i(TAG, "Scheduling " + mNumberOfNativeCrashPollsRemaining + " polls to check "
-                + "and mitigate native crashes");
-        mShortTaskHandler.post(()->checkAndMitigateNativeCrashes());
-    }
-
-    private int getUserImpactLevelLimit() {
-        return SystemProperties.getInt(MAJOR_USER_IMPACT_LEVEL_THRESHOLD,
-                DEFAULT_MAJOR_USER_IMPACT_LEVEL_THRESHOLD);
-    }
-
-    private Set<String> getPackagesExemptFromImpactLevelThreshold() {
-        if (mPackagesExemptFromImpactLevelThreshold.isEmpty()) {
-            String packageNames = SystemProperties.get(PACKAGES_EXEMPT_FROM_IMPACT_LEVEL_THRESHOLD,
-                    DEFAULT_PACKAGES_EXEMPT_FROM_IMPACT_LEVEL_THRESHOLD);
-            return Set.of(packageNames.split("\\s*,\\s*"));
-        }
-        return mPackagesExemptFromImpactLevelThreshold;
-    }
-
-    /**
-     * Indicates that a mitigation was successfully triggered or executed during
-     * {@link PackageHealthObserver#onExecuteHealthCheckMitigation} or
-     * {@link PackageHealthObserver#onExecuteBootLoopMitigation}.
-     */
-    public static final int MITIGATION_RESULT_SUCCESS =
-            ObserverMitigationResult.MITIGATION_RESULT_SUCCESS;
-
-    /**
-     * Indicates that a mitigation executed during
-     * {@link PackageHealthObserver#onExecuteHealthCheckMitigation} or
-     * {@link PackageHealthObserver#onExecuteBootLoopMitigation} was skipped.
-     */
-    public static final int MITIGATION_RESULT_SKIPPED =
-            ObserverMitigationResult.MITIGATION_RESULT_SKIPPED;
-
-
-    /**
-     * Possible return values of the for mitigations executed during
-     * {@link PackageHealthObserver#onExecuteHealthCheckMitigation} and
-     * {@link PackageHealthObserver#onExecuteBootLoopMitigation}.
-     * @hide
-     */
-    @Retention(SOURCE)
-    @IntDef(prefix = "MITIGATION_RESULT_", value = {
-            ObserverMitigationResult.MITIGATION_RESULT_SUCCESS,
-            ObserverMitigationResult.MITIGATION_RESULT_SKIPPED,
-            })
-    public @interface ObserverMitigationResult {
-        int MITIGATION_RESULT_SUCCESS = 1;
-        int MITIGATION_RESULT_SKIPPED = 2;
-    }
-
-    /**
-     * The minimum value that can be returned by any observer.
-     * It represents that no mitigations were available.
-     */
-    public static final int USER_IMPACT_THRESHOLD_NONE =
-            PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
-
-    /**
-     * The mitigation impact beyond which the user will start noticing the mitigations.
-     */
-    public static final int USER_IMPACT_THRESHOLD_MEDIUM =
-            PackageHealthObserverImpact.USER_IMPACT_LEVEL_20;
-
-    /**
-     * The mitigation impact beyond which the user impact is severely high.
-     */
-    public static final int USER_IMPACT_THRESHOLD_HIGH =
-            PackageHealthObserverImpact.USER_IMPACT_LEVEL_71;
-
-    /**
-     * Possible severity values of the user impact of a
-     * {@link PackageHealthObserver#onExecuteHealthCheckMitigation}.
-     * @hide
-     */
-    @Retention(SOURCE)
-    @IntDef(value = {PackageHealthObserverImpact.USER_IMPACT_LEVEL_0,
-                     PackageHealthObserverImpact.USER_IMPACT_LEVEL_10,
-                     PackageHealthObserverImpact.USER_IMPACT_LEVEL_20,
-                     PackageHealthObserverImpact.USER_IMPACT_LEVEL_30,
-                     PackageHealthObserverImpact.USER_IMPACT_LEVEL_40,
-                     PackageHealthObserverImpact.USER_IMPACT_LEVEL_50,
-                     PackageHealthObserverImpact.USER_IMPACT_LEVEL_70,
-                     PackageHealthObserverImpact.USER_IMPACT_LEVEL_71,
-                     PackageHealthObserverImpact.USER_IMPACT_LEVEL_75,
-                     PackageHealthObserverImpact.USER_IMPACT_LEVEL_80,
-                     PackageHealthObserverImpact.USER_IMPACT_LEVEL_90,
-                     PackageHealthObserverImpact.USER_IMPACT_LEVEL_100})
-    public @interface PackageHealthObserverImpact {
-        /** No action to take. */
-        int USER_IMPACT_LEVEL_0 = 0;
-        /* Action has low user impact, user of a device will barely notice. */
-        int USER_IMPACT_LEVEL_10 = 10;
-        /* Actions having medium user impact, user of a device will likely notice. */
-        int USER_IMPACT_LEVEL_20 = 20;
-        int USER_IMPACT_LEVEL_30 = 30;
-        int USER_IMPACT_LEVEL_40 = 40;
-        int USER_IMPACT_LEVEL_50 = 50;
-        int USER_IMPACT_LEVEL_70 = 70;
-        /* Action has high user impact, a last resort, user of a device will be very frustrated. */
-        int USER_IMPACT_LEVEL_71 = 71;
-        int USER_IMPACT_LEVEL_75 = 75;
-        int USER_IMPACT_LEVEL_80 = 80;
-        int USER_IMPACT_LEVEL_90 = 90;
-        int USER_IMPACT_LEVEL_100 = 100;
-    }
-
-    /** Register instances of this interface to receive notifications on package failure. */
-    @SuppressLint({"CallbackName"})
-    public interface PackageHealthObserver {
-        /**
-         * Called when health check fails for the {@code versionedPackage}.
-         * Note: if the returned user impact is higher than {@link #USER_IMPACT_THRESHOLD_HIGH},
-         * then {@link #onExecuteHealthCheckMitigation} would be called only in severe device
-         * conditions like boot-loop or network failure.
-         *
-         * @param versionedPackage the package that is failing. This may be null if a native
-         *                          service is crashing.
-         * @param failureReason   the type of failure that is occurring.
-         * @param mitigationCount the number of times mitigation has been called for this package
-         *                        (including this time).
-         *
-         * @return any value greater than {@link #USER_IMPACT_THRESHOLD_NONE} to express
-         * the impact of mitigation on the user in {@link #onExecuteHealthCheckMitigation}.
-         * Returning {@link #USER_IMPACT_THRESHOLD_NONE} would indicate no mitigations available.
-         */
-        @PackageHealthObserverImpact int onHealthCheckFailed(
-                @Nullable VersionedPackage versionedPackage,
-                @FailureReasons int failureReason,
-                int mitigationCount);
-
-        /**
-         * This would be called after {@link #onHealthCheckFailed}.
-         * This is called only if current observer returned least impact mitigation for failed
-         * health check.
-         *
-         * @param versionedPackage the package that is failing. This may be null if a native
-         *                         service is crashing.
-         * @param failureReason    the type of failure that is occurring.
-         * @param mitigationCount the number of times mitigation has been called for this package
-         *                         (including this time).
-         * @return {@link #MITIGATION_RESULT_SUCCESS} if the mitigation was successful,
-         *         or {@link #MITIGATION_RESULT_SKIPPED} if the mitigation was skipped.
-         */
-        @ObserverMitigationResult int onExecuteHealthCheckMitigation(
-                @Nullable VersionedPackage versionedPackage,
-                @FailureReasons int failureReason, int mitigationCount);
-
-
-        /**
-         * Called when the system server has booted several times within a window of time, defined
-         * by {@link #mBootThreshold}
-         *
-         * @param mitigationCount the number of times mitigation has been attempted for this
-         *                        boot loop (including this time).
-         *
-         * @return any value greater than {@link #USER_IMPACT_THRESHOLD_NONE} to express
-         * the impact of mitigation on the user in {@link #onExecuteBootLoopMitigation}.
-         * Returning {@link #USER_IMPACT_THRESHOLD_NONE} would indicate no mitigations available.
-         */
-        default @PackageHealthObserverImpact int onBootLoop(int mitigationCount) {
-            return PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
-        }
-
-        /**
-         * This would be called after {@link #onBootLoop}.
-         * This is called only if current observer returned least impact mitigation for fixing
-         * boot loop.
-         *
-         * @param mitigationCount the number of times mitigation has been attempted for this
-         *                        boot loop (including this time).
-         *
-         * @return {@link #MITIGATION_RESULT_SUCCESS} if the mitigation was successful,
-         *         or {@link #MITIGATION_RESULT_SKIPPED} if the mitigation was skipped.
-         */
-        default @ObserverMitigationResult int onExecuteBootLoopMitigation(int mitigationCount) {
-            return ObserverMitigationResult.MITIGATION_RESULT_SKIPPED;
-        }
-
-        // TODO(b/120598832): Ensure uniqueness?
-        /**
-         * Identifier for the observer, should not change across device updates otherwise the
-         * watchdog may drop observing packages with the old name.
-         */
-        @NonNull String getUniqueIdentifier();
-
-        /**
-         * An observer will not be pruned if this is set, even if the observer is not explicitly
-         * monitoring any packages.
-         */
-        default boolean isPersistent() {
-            return false;
-        }
-
-        /**
-         * Returns {@code true} if this observer wishes to observe the given package, {@code false}
-         * otherwise.
-         * Any failing package can be passed on to the observer. Currently the packages that have
-         * ANRs and perform {@link android.service.watchdog.ExplicitHealthCheckService} are being
-         * passed to observers in these API.
-         *
-         * <p> A persistent observer may choose to start observing certain failing packages, even if
-         * it has not explicitly asked to watch the package with {@link #startExplicitHealthCheck}.
-         */
-        default boolean mayObservePackage(@NonNull String packageName) {
-            return false;
-        }
-    }
-
-    @VisibleForTesting
-    long getTriggerFailureCount() {
-        synchronized (sLock) {
-            return mTriggerFailureCount;
-        }
-    }
-
-    @VisibleForTesting
-    long getTriggerFailureDurationMs() {
-        synchronized (sLock) {
-            return mTriggerFailureDurationMs;
-        }
-    }
-
-    /**
-     * Serializes and syncs health check requests with the {@link ExplicitHealthCheckController}.
-     */
-    private void syncRequestsAsync() {
-        mShortTaskHandler.removeCallbacks(mSyncRequests);
-        mShortTaskHandler.post(mSyncRequests);
-    }
-
-    /**
-     * Syncs health check requests with the {@link ExplicitHealthCheckController}.
-     * Calls to this must be serialized.
-     *
-     * @see #syncRequestsAsync
-     */
-    private void syncRequests() {
-        boolean syncRequired = false;
-        synchronized (sLock) {
-            if (mIsPackagesReady) {
-                Set<String> packages = getPackagesPendingHealthChecksLocked();
-                if (mSyncRequired || !packages.equals(mRequestedHealthCheckPackages)
-                        || packages.isEmpty()) {
-                    syncRequired = true;
-                    mRequestedHealthCheckPackages = packages;
-                }
-            } // else, we will sync requests when packages become ready
-        }
-
-        // Call outside lock to avoid holding lock when calling into the controller.
-        if (syncRequired) {
-            Slog.i(TAG, "Syncing health check requests for packages: "
-                    + mRequestedHealthCheckPackages);
-            mHealthCheckController.syncRequests(mRequestedHealthCheckPackages);
-            mSyncRequired = false;
-        }
-    }
-
-    /**
-     * Updates the observers monitoring {@code packageName} that explicit health check has passed.
-     *
-     * <p> This update is strictly for registered observers at the time of the call
-     * Observers that register after this signal will have no knowledge of prior signals and will
-     * effectively behave as if the explicit health check hasn't passed for {@code packageName}.
-     *
-     * <p> {@code packageName} can still be considered failed if reported by
-     * {@link #notifyPackageFailureLocked} before the package expires.
-     *
-     * <p> Triggered by components outside the system server when they are fully functional after an
-     * update.
-     */
-    private void onHealthCheckPassed(String packageName) {
-        Slog.i(TAG, "Health check passed for package: " + packageName);
-        boolean isStateChanged = false;
-
-        synchronized (sLock) {
-            for (int observerIdx = 0; observerIdx < mAllObservers.size(); observerIdx++) {
-                ObserverInternal observer = mAllObservers.valueAt(observerIdx);
-                MonitoredPackage monitoredPackage = observer.getMonitoredPackage(packageName);
-
-                if (monitoredPackage != null) {
-                    int oldState = monitoredPackage.getHealthCheckStateLocked();
-                    int newState = monitoredPackage.tryPassHealthCheckLocked();
-                    isStateChanged |= oldState != newState;
-                }
-            }
-        }
-
-        if (isStateChanged) {
-            syncState("health check passed for " + packageName);
-        }
-    }
-
-    private void onSupportedPackages(List<PackageConfig> supportedPackages) {
-        boolean isStateChanged = false;
-
-        Map<String, Long> supportedPackageTimeouts = new ArrayMap<>();
-        Iterator<PackageConfig> it = supportedPackages.iterator();
-        while (it.hasNext()) {
-            PackageConfig info = it.next();
-            supportedPackageTimeouts.put(info.getPackageName(), info.getHealthCheckTimeoutMillis());
-        }
-
-        synchronized (sLock) {
-            Slog.d(TAG, "Received supported packages " + supportedPackages);
-            Iterator<ObserverInternal> oit = mAllObservers.values().iterator();
-            while (oit.hasNext()) {
-                Iterator<MonitoredPackage> pit = oit.next().getMonitoredPackages()
-                        .values().iterator();
-                while (pit.hasNext()) {
-                    MonitoredPackage monitoredPackage = pit.next();
-                    String packageName = monitoredPackage.getName();
-                    int oldState = monitoredPackage.getHealthCheckStateLocked();
-                    int newState;
-
-                    if (supportedPackageTimeouts.containsKey(packageName)) {
-                        // Supported packages become ACTIVE if currently INACTIVE
-                        newState = monitoredPackage.setHealthCheckActiveLocked(
-                                supportedPackageTimeouts.get(packageName));
-                    } else {
-                        // Unsupported packages are marked as PASSED unless already FAILED
-                        newState = monitoredPackage.tryPassHealthCheckLocked();
-                    }
-                    isStateChanged |= oldState != newState;
-                }
-            }
-        }
-
-        if (isStateChanged) {
-            syncState("updated health check supported packages " + supportedPackages);
-        }
-    }
-
-    private void onSyncRequestNotified() {
-        synchronized (sLock) {
-            mSyncRequired = true;
-            syncRequestsAsync();
-        }
-    }
-
-    @GuardedBy("sLock")
-    private Set<String> getPackagesPendingHealthChecksLocked() {
-        Set<String> packages = new ArraySet<>();
-        Iterator<ObserverInternal> oit = mAllObservers.values().iterator();
-        while (oit.hasNext()) {
-            ObserverInternal observer = oit.next();
-            Iterator<MonitoredPackage> pit =
-                    observer.getMonitoredPackages().values().iterator();
-            while (pit.hasNext()) {
-                MonitoredPackage monitoredPackage = pit.next();
-                String packageName = monitoredPackage.getName();
-                if (monitoredPackage.isPendingHealthChecksLocked()) {
-                    packages.add(packageName);
-                }
-            }
-        }
-        return packages;
-    }
-
-    /**
-     * Syncs the state of the observers.
-     *
-     * <p> Prunes all observers, saves new state to disk, syncs health check requests with the
-     * health check service and schedules the next state sync.
-     */
-    private void syncState(String reason) {
-        synchronized (sLock) {
-            Slog.i(TAG, "Syncing state, reason: " + reason);
-            pruneObserversLocked();
-
-            saveToFileAsync();
-            syncRequestsAsync();
-
-            // Done syncing state, schedule the next state sync
-            scheduleNextSyncStateLocked();
-        }
-    }
-
-    private void syncStateWithScheduledReason() {
-        syncState("scheduled");
-    }
-
-    @GuardedBy("sLock")
-    private void scheduleNextSyncStateLocked() {
-        long durationMs = getNextStateSyncMillisLocked();
-        mShortTaskHandler.removeCallbacks(mSyncStateWithScheduledReason);
-        if (durationMs == Long.MAX_VALUE) {
-            Slog.i(TAG, "Cancelling state sync, nothing to sync");
-            mUptimeAtLastStateSync = 0;
-        } else {
-            mUptimeAtLastStateSync = mSystemClock.uptimeMillis();
-            mShortTaskHandler.postDelayed(mSyncStateWithScheduledReason, durationMs);
-        }
-    }
-
-    /**
-     * Returns the next duration in millis to sync the watchdog state.
-     *
-     * @returns Long#MAX_VALUE if there are no observed packages.
-     */
-    @GuardedBy("sLock")
-    private long getNextStateSyncMillisLocked() {
-        long shortestDurationMs = Long.MAX_VALUE;
-        for (int oIndex = 0; oIndex < mAllObservers.size(); oIndex++) {
-            ArrayMap<String, MonitoredPackage> packages = mAllObservers.valueAt(oIndex)
-                    .getMonitoredPackages();
-            for (int pIndex = 0; pIndex < packages.size(); pIndex++) {
-                MonitoredPackage mp = packages.valueAt(pIndex);
-                long duration = mp.getShortestScheduleDurationMsLocked();
-                if (duration < shortestDurationMs) {
-                    shortestDurationMs = duration;
-                }
-            }
-        }
-        return shortestDurationMs;
-    }
-
-    /**
-     * Removes {@code elapsedMs} milliseconds from all durations on monitored packages
-     * and updates other internal state.
-     */
-    @GuardedBy("sLock")
-    private void pruneObserversLocked() {
-        long elapsedMs = mUptimeAtLastStateSync == 0
-                ? 0 : mSystemClock.uptimeMillis() - mUptimeAtLastStateSync;
-        if (elapsedMs <= 0) {
-            Slog.i(TAG, "Not pruning observers, elapsed time: " + elapsedMs + "ms");
-            return;
-        }
-
-        Iterator<ObserverInternal> it = mAllObservers.values().iterator();
-        while (it.hasNext()) {
-            ObserverInternal observer = it.next();
-            Set<MonitoredPackage> failedPackages =
-                    observer.prunePackagesLocked(elapsedMs);
-            if (!failedPackages.isEmpty()) {
-                onHealthCheckFailed(observer, failedPackages);
-            }
-            if (observer.getMonitoredPackages().isEmpty() && (observer.registeredObserver == null
-                    || !observer.registeredObserver.isPersistent())) {
-                Slog.i(TAG, "Discarding observer " + observer.name + ". All packages expired");
-                it.remove();
-            }
-        }
-    }
-
-    private void onHealthCheckFailed(ObserverInternal observer,
-            Set<MonitoredPackage> failedPackages) {
-        mLongTaskHandler.post(() -> {
-            synchronized (sLock) {
-                PackageHealthObserver registeredObserver = observer.registeredObserver;
-                if (registeredObserver != null) {
-                    Iterator<MonitoredPackage> it = failedPackages.iterator();
-                    while (it.hasNext()) {
-                        VersionedPackage versionedPkg = getVersionedPackage(it.next().getName());
-                        if (versionedPkg != null) {
-                            Slog.i(TAG,
-                                    "Explicit health check failed for package " + versionedPkg);
-                            observer.observerExecutor.execute(() ->
-                                    registeredObserver.onExecuteHealthCheckMitigation(versionedPkg,
-                                            PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK,
-                                            1));
-                        }
-                    }
-                }
-            }
-        });
-    }
-
-    /**
-     * Gets PackageInfo for the given package. Matches any user and apex.
-     *
-     * @throws PackageManager.NameNotFoundException if no such package is installed.
-     */
-    private PackageInfo getPackageInfo(String packageName)
-            throws PackageManager.NameNotFoundException {
-        PackageManager pm = mContext.getPackageManager();
-        try {
-            // The MATCH_ANY_USER flag doesn't mix well with the MATCH_APEX
-            // flag, so make two separate attempts to get the package info.
-            // We don't need both flags at the same time because we assume
-            // apex files are always installed for all users.
-            return pm.getPackageInfo(packageName, PackageManager.MATCH_ANY_USER);
-        } catch (PackageManager.NameNotFoundException e) {
-            return pm.getPackageInfo(packageName, PackageManager.MATCH_APEX);
-        }
-    }
-
-    @Nullable
-    private VersionedPackage getVersionedPackage(String packageName) {
-        final PackageManager pm = mContext.getPackageManager();
-        if (pm == null || TextUtils.isEmpty(packageName)) {
-            return null;
-        }
-        try {
-            final long versionCode = getPackageInfo(packageName).getLongVersionCode();
-            return new VersionedPackage(packageName, versionCode);
-        } catch (PackageManager.NameNotFoundException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Loads mAllObservers from file.
-     *
-     * <p>Note that this is <b>not</b> thread safe and should only called be called
-     * from the constructor.
-     */
-    private void loadFromFile() {
-        InputStream infile = null;
-        mAllObservers.clear();
-        try {
-            infile = mPolicyFile.openRead();
-            final XmlPullParser parser = Xml.newPullParser();
-            parser.setInput(infile, UTF_8.name());
-            XmlUtils.beginDocument(parser, TAG_PACKAGE_WATCHDOG);
-            int outerDepth = parser.getDepth();
-            while (XmlUtils.nextElementWithin(parser, outerDepth)) {
-                ObserverInternal observer = ObserverInternal.read(parser, this);
-                if (observer != null) {
-                    mAllObservers.put(observer.name, observer);
-                }
-            }
-        } catch (FileNotFoundException e) {
-            // Nothing to monitor
-        } catch (Exception e) {
-            Slog.wtf(TAG, "Unable to read monitored packages, deleting file", e);
-            mPolicyFile.delete();
-        } finally {
-            IoUtils.closeQuietly(infile);
-        }
-    }
-
-    private void onPropertyChanged(DeviceConfig.Properties properties) {
-        try {
-            updateConfigs();
-        } catch (Exception ignore) {
-            Slog.w(TAG, "Failed to reload device config changes");
-        }
-    }
-
-    /** Adds a {@link DeviceConfig#OnPropertiesChangedListener}. */
-    private void setPropertyChangedListenerLocked() {
-        DeviceConfig.addOnPropertiesChangedListener(
-                DeviceConfig.NAMESPACE_ROLLBACK,
-                mContext.getMainExecutor(),
-                mOnPropertyChangedListener);
-    }
-
-    @VisibleForTesting
-    void removePropertyChangedListener() {
-        DeviceConfig.removeOnPropertiesChangedListener(mOnPropertyChangedListener);
-    }
-
-    /**
-     * Health check is enabled or disabled after reading the flags
-     * from DeviceConfig.
-     */
-    @VisibleForTesting
-    void updateConfigs() {
-        synchronized (sLock) {
-            mTriggerFailureCount = DeviceConfig.getInt(
-                    DeviceConfig.NAMESPACE_ROLLBACK,
-                    PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT,
-                    DEFAULT_TRIGGER_FAILURE_COUNT);
-            if (mTriggerFailureCount <= 0) {
-                mTriggerFailureCount = DEFAULT_TRIGGER_FAILURE_COUNT;
-            }
-
-            mTriggerFailureDurationMs = DeviceConfig.getInt(
-                    DeviceConfig.NAMESPACE_ROLLBACK,
-                    PROPERTY_WATCHDOG_TRIGGER_DURATION_MILLIS,
-                    DEFAULT_TRIGGER_FAILURE_DURATION_MS);
-            if (mTriggerFailureDurationMs <= 0) {
-                mTriggerFailureDurationMs = DEFAULT_TRIGGER_FAILURE_DURATION_MS;
-            }
-
-            setExplicitHealthCheckEnabled(DeviceConfig.getBoolean(
-                    DeviceConfig.NAMESPACE_ROLLBACK,
-                    PROPERTY_WATCHDOG_EXPLICIT_HEALTH_CHECK_ENABLED,
-                    DEFAULT_EXPLICIT_HEALTH_CHECK_ENABLED));
-        }
-    }
-
-    /**
-     * Persists mAllObservers to file. Threshold information is ignored.
-     */
-    private boolean saveToFile() {
-        Slog.i(TAG, "Saving observer state to file");
-        synchronized (sLock) {
-            FileOutputStream stream;
-            try {
-                stream = mPolicyFile.startWrite();
-            } catch (IOException e) {
-                Slog.w(TAG, "Cannot update monitored packages", e);
-                return false;
-            }
-
-            try {
-                XmlSerializer out = new FastXmlSerializer();
-                out.setOutput(stream, UTF_8.name());
-                out.startDocument(null, true);
-                out.startTag(null, TAG_PACKAGE_WATCHDOG);
-                out.attribute(null, ATTR_VERSION, Integer.toString(DB_VERSION));
-                for (int oIndex = 0; oIndex < mAllObservers.size(); oIndex++) {
-                    mAllObservers.valueAt(oIndex).writeLocked(out);
-                }
-                out.endTag(null, TAG_PACKAGE_WATCHDOG);
-                out.endDocument();
-                mPolicyFile.finishWrite(stream);
-                return true;
-            } catch (IOException e) {
-                Slog.w(TAG, "Failed to save monitored packages, restoring backup", e);
-                mPolicyFile.failWrite(stream);
-                return false;
-            }
-        }
-    }
-
-    private void saveToFileAsync() {
-        if (!mLongTaskHandler.hasCallbacks(mSaveToFile)) {
-            mLongTaskHandler.post(mSaveToFile);
-        }
-    }
-
-    /** @hide Convert a {@code LongArrayQueue} to a String of comma-separated values. */
-    public static String longArrayQueueToString(LongArrayQueue queue) {
-        if (queue.size() > 0) {
-            StringBuilder sb = new StringBuilder();
-            sb.append(queue.get(0));
-            for (int i = 1; i < queue.size(); i++) {
-                sb.append(",");
-                sb.append(queue.get(i));
-            }
-            return sb.toString();
-        }
-        return "";
-    }
-
-    /** @hide Parse a comma-separated String of longs into a LongArrayQueue. */
-    public static LongArrayQueue parseLongArrayQueue(String commaSeparatedValues) {
-        LongArrayQueue result = new LongArrayQueue();
-        if (!TextUtils.isEmpty(commaSeparatedValues)) {
-            String[] values = commaSeparatedValues.split(",");
-            for (String value : values) {
-                result.addLast(Long.parseLong(value));
-            }
-        }
-        return result;
-    }
-
-
-    /** Dump status of every observer in mAllObservers. */
-    public void dump(@NonNull PrintWriter pw) {
-        if (Flags.synchronousRebootInRescueParty() && isRecoveryTriggeredReboot()) {
-            dumpInternal(pw);
-        } else {
-            synchronized (sLock) {
-                dumpInternal(pw);
-            }
-        }
-    }
-
-    /**
-     * Check if we're currently attempting to reboot during mitigation. This method must return
-     * true if triggered reboot early during a boot loop, since the device will not be fully booted
-     * at this time.
-     */
-    public static boolean isRecoveryTriggeredReboot() {
-        return isFactoryResetPropertySet() || isRebootPropertySet();
-    }
-
-    private static boolean isFactoryResetPropertySet() {
-        return CrashRecoveryProperties.attemptingFactoryReset().orElse(false);
-    }
-
-    private static boolean isRebootPropertySet() {
-        return CrashRecoveryProperties.attemptingReboot().orElse(false);
-    }
-
-    private void dumpInternal(@NonNull PrintWriter pw) {
-        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
-        ipw.println("Package Watchdog status");
-        ipw.increaseIndent();
-        synchronized (sLock) {
-            for (String observerName : mAllObservers.keySet()) {
-                ipw.println("Observer name: " + observerName);
-                ipw.increaseIndent();
-                ObserverInternal observerInternal = mAllObservers.get(observerName);
-                observerInternal.dump(ipw);
-                ipw.decreaseIndent();
-            }
-        }
-        ipw.decreaseIndent();
-        dumpCrashRecoveryEvents(ipw);
-    }
-
-    @VisibleForTesting
-    @GuardedBy("sLock")
-    void registerObserverInternal(ObserverInternal observerInternal) {
-        mAllObservers.put(observerInternal.name, observerInternal);
-    }
-
-    /**
-     * Represents an observer monitoring a set of packages along with the failure thresholds for
-     * each package.
-     *
-     * <p> Note, the PackageWatchdog#sLock must always be held when reading or writing
-     * instances of this class.
-     */
-    static class ObserverInternal {
-        public final String name;
-        @GuardedBy("sLock")
-        private final ArrayMap<String, MonitoredPackage> mPackages = new ArrayMap<>();
-        @Nullable
-        @GuardedBy("sLock")
-        public PackageHealthObserver registeredObserver;
-        public Executor observerExecutor;
-        private int mMitigationCount;
-
-        ObserverInternal(String name, List<MonitoredPackage> packages) {
-            this(name, packages, /*mitigationCount=*/ 0);
-        }
-
-        ObserverInternal(String name, List<MonitoredPackage> packages, int mitigationCount) {
-            this.name = name;
-            updatePackagesLocked(packages);
-            this.mMitigationCount = mitigationCount;
-        }
-
-        /**
-         * Writes important {@link MonitoredPackage} details for this observer to file.
-         * Does not persist any package failure thresholds.
-         */
-        @GuardedBy("sLock")
-        public boolean writeLocked(XmlSerializer out) {
-            try {
-                out.startTag(null, TAG_OBSERVER);
-                out.attribute(null, ATTR_NAME, name);
-                if (Flags.recoverabilityDetection()) {
-                    out.attribute(null, ATTR_MITIGATION_COUNT, Integer.toString(mMitigationCount));
-                }
-                for (int i = 0; i < mPackages.size(); i++) {
-                    MonitoredPackage p = mPackages.valueAt(i);
-                    p.writeLocked(out);
-                }
-                out.endTag(null, TAG_OBSERVER);
-                return true;
-            } catch (IOException e) {
-                Slog.w(TAG, "Cannot save observer", e);
-                return false;
-            }
-        }
-
-        public int getBootMitigationCount() {
-            return mMitigationCount;
-        }
-
-        public void setBootMitigationCount(int mitigationCount) {
-            mMitigationCount = mitigationCount;
-        }
-
-        @GuardedBy("sLock")
-        public void updatePackagesLocked(List<MonitoredPackage> packages) {
-            for (int pIndex = 0; pIndex < packages.size(); pIndex++) {
-                MonitoredPackage p = packages.get(pIndex);
-                MonitoredPackage existingPackage = getMonitoredPackage(p.getName());
-                if (existingPackage != null) {
-                    existingPackage.updateHealthCheckDuration(p.mDurationMs);
-                } else {
-                    putMonitoredPackage(p);
-                }
-            }
-        }
-
-        /**
-         * Reduces the monitoring durations of all packages observed by this observer by
-         * {@code elapsedMs}. If any duration is less than 0, the package is removed from
-         * observation. If any health check duration is less than 0, the health check result
-         * is evaluated.
-         *
-         * @return a {@link Set} of packages that were removed from the observer without explicit
-         * health check passing, or an empty list if no package expired for which an explicit health
-         * check was still pending
-         */
-        @GuardedBy("sLock")
-        private Set<MonitoredPackage> prunePackagesLocked(long elapsedMs) {
-            Set<MonitoredPackage> failedPackages = new ArraySet<>();
-            Iterator<MonitoredPackage> it = mPackages.values().iterator();
-            while (it.hasNext()) {
-                MonitoredPackage p = it.next();
-                int oldState = p.getHealthCheckStateLocked();
-                int newState = p.handleElapsedTimeLocked(elapsedMs);
-                if (oldState != HealthCheckState.FAILED
-                        && newState == HealthCheckState.FAILED) {
-                    Slog.i(TAG, "Package " + p.getName() + " failed health check");
-                    failedPackages.add(p);
-                }
-                if (p.isExpiredLocked()) {
-                    it.remove();
-                }
-            }
-            return failedPackages;
-        }
-
-        /**
-         * Increments failure counts of {@code packageName}.
-         * @returns {@code true} if failure threshold is exceeded, {@code false} otherwise
-         * @hide
-         */
-        @GuardedBy("sLock")
-        public boolean notifyPackageFailureLocked(String packageName) {
-            if (getMonitoredPackage(packageName) == null && registeredObserver.isPersistent()
-                    && registeredObserver.mayObservePackage(packageName)) {
-                putMonitoredPackage(sPackageWatchdog.newMonitoredPackage(
-                        packageName, DEFAULT_OBSERVING_DURATION_MS, false));
-            }
-            MonitoredPackage p = getMonitoredPackage(packageName);
-            if (p != null) {
-                return p.onFailureLocked();
-            }
-            return false;
-        }
-
-        /**
-         * Returns the map of packages monitored by this observer.
-         *
-         * @return a mapping of package names to {@link MonitoredPackage} objects.
-         */
-        @GuardedBy("sLock")
-        public ArrayMap<String, MonitoredPackage> getMonitoredPackages() {
-            return mPackages;
-        }
-
-        /**
-         * Returns the {@link MonitoredPackage} associated with a given package name if the
-         * package is being monitored by this observer.
-         *
-         * @param packageName: the name of the package.
-         * @return the {@link MonitoredPackage} object associated with the package name if one
-         *         exists, {@code null} otherwise.
-         */
-        @GuardedBy("sLock")
-        @Nullable
-        public MonitoredPackage getMonitoredPackage(String packageName) {
-            return mPackages.get(packageName);
-        }
-
-        /**
-         * Associates a {@link MonitoredPackage} with the observer.
-         *
-         * @param p: the {@link MonitoredPackage} to store.
-         */
-        @GuardedBy("sLock")
-        public void putMonitoredPackage(MonitoredPackage p) {
-            mPackages.put(p.getName(), p);
-        }
-
-        /**
-         * Returns one ObserverInternal from the {@code parser} and advances its state.
-         *
-         * <p>Note that this method is <b>not</b> thread safe. It should only be called from
-         * #loadFromFile which in turn is only called on construction of the
-         * singleton PackageWatchdog.
-         **/
-        public static ObserverInternal read(XmlPullParser parser, PackageWatchdog watchdog) {
-            String observerName = null;
-            int observerMitigationCount = 0;
-            if (TAG_OBSERVER.equals(parser.getName())) {
-                observerName = parser.getAttributeValue(null, ATTR_NAME);
-                if (TextUtils.isEmpty(observerName)) {
-                    Slog.wtf(TAG, "Unable to read observer name");
-                    return null;
-                }
-            }
-            List<MonitoredPackage> packages = new ArrayList<>();
-            int innerDepth = parser.getDepth();
-            try {
-                if (Flags.recoverabilityDetection()) {
-                    try {
-                        observerMitigationCount = Integer.parseInt(
-                                parser.getAttributeValue(null, ATTR_MITIGATION_COUNT));
-                    } catch (Exception e) {
-                        Slog.i(
-                            TAG,
-                            "ObserverInternal mitigation count was not present.");
-                    }
-                }
-                while (XmlUtils.nextElementWithin(parser, innerDepth)) {
-                    if (TAG_PACKAGE.equals(parser.getName())) {
-                        try {
-                            MonitoredPackage pkg = watchdog.parseMonitoredPackage(parser);
-                            if (pkg != null) {
-                                packages.add(pkg);
-                            }
-                        } catch (NumberFormatException e) {
-                            Slog.wtf(TAG, "Skipping package for observer " + observerName, e);
-                            continue;
-                        }
-                    }
-                }
-            } catch (XmlPullParserException | IOException e) {
-                Slog.wtf(TAG, "Unable to read observer " + observerName, e);
-                return null;
-            }
-            if (packages.isEmpty()) {
-                return null;
-            }
-            return new ObserverInternal(observerName, packages, observerMitigationCount);
-        }
-
-        /** Dumps information about this observer and the packages it watches. */
-        public void dump(IndentingPrintWriter pw) {
-            boolean isPersistent = registeredObserver != null && registeredObserver.isPersistent();
-            pw.println("Persistent: " + isPersistent);
-            for (String packageName : mPackages.keySet()) {
-                MonitoredPackage p = getMonitoredPackage(packageName);
-                pw.println(packageName +  ": ");
-                pw.increaseIndent();
-                pw.println("# Failures: " + p.mFailureHistory.size());
-                pw.println("Monitoring duration remaining: " + p.mDurationMs + "ms");
-                pw.println("Explicit health check duration: " + p.mHealthCheckDurationMs + "ms");
-                pw.println("Health check state: " + p.toString(p.mHealthCheckState));
-                pw.decreaseIndent();
-            }
-        }
-    }
-
-    /** @hide */
-    @Retention(SOURCE)
-    @IntDef(value = {
-            HealthCheckState.ACTIVE,
-            HealthCheckState.INACTIVE,
-            HealthCheckState.PASSED,
-            HealthCheckState.FAILED})
-    public @interface HealthCheckState {
-        // The package has not passed health check but has requested a health check
-        int ACTIVE = 0;
-        // The package has not passed health check and has not requested a health check
-        int INACTIVE = 1;
-        // The package has passed health check
-        int PASSED = 2;
-        // The package has failed health check
-        int FAILED = 3;
-    }
-
-    MonitoredPackage newMonitoredPackage(
-            String name, long durationMs, boolean hasPassedHealthCheck) {
-        return newMonitoredPackage(name, durationMs, Long.MAX_VALUE, hasPassedHealthCheck,
-                new LongArrayQueue());
-    }
-
-    MonitoredPackage newMonitoredPackage(String name, long durationMs, long healthCheckDurationMs,
-            boolean hasPassedHealthCheck, LongArrayQueue mitigationCalls) {
-        return new MonitoredPackage(name, durationMs, healthCheckDurationMs,
-                hasPassedHealthCheck, mitigationCalls);
-    }
-
-    MonitoredPackage parseMonitoredPackage(XmlPullParser parser)
-            throws XmlPullParserException {
-        String packageName = parser.getAttributeValue(null, ATTR_NAME);
-        long duration = Long.parseLong(parser.getAttributeValue(null, ATTR_DURATION));
-        long healthCheckDuration = Long.parseLong(parser.getAttributeValue(null,
-                ATTR_EXPLICIT_HEALTH_CHECK_DURATION));
-        boolean hasPassedHealthCheck = Boolean.parseBoolean(parser.getAttributeValue(null,
-                ATTR_PASSED_HEALTH_CHECK));
-        LongArrayQueue mitigationCalls = parseLongArrayQueue(
-                parser.getAttributeValue(null, ATTR_MITIGATION_CALLS));
-        return newMonitoredPackage(packageName,
-                duration, healthCheckDuration, hasPassedHealthCheck, mitigationCalls);
-    }
-
-    /**
-     * Represents a package and its health check state along with the time
-     * it should be monitored for.
-     *
-     * <p> Note, the PackageWatchdog#sLock must always be held when reading or writing
-     * instances of this class.
-     */
-    class MonitoredPackage {
-        private final String mPackageName;
-        // Times when package failures happen sorted in ascending order
-        @GuardedBy("sLock")
-        private final LongArrayQueue mFailureHistory = new LongArrayQueue();
-        // Times when an observer was called to mitigate this package's failure. Sorted in
-        // ascending order.
-        @GuardedBy("sLock")
-        private final LongArrayQueue mMitigationCalls;
-        // One of STATE_[ACTIVE|INACTIVE|PASSED|FAILED]. Updated on construction and after
-        // methods that could change the health check state: handleElapsedTimeLocked and
-        // tryPassHealthCheckLocked
-        private int mHealthCheckState = HealthCheckState.INACTIVE;
-        // Whether an explicit health check has passed.
-        // This value in addition with mHealthCheckDurationMs determines the health check state
-        // of the package, see #getHealthCheckStateLocked
-        @GuardedBy("sLock")
-        private boolean mHasPassedHealthCheck;
-        // System uptime duration to monitor package.
-        @GuardedBy("sLock")
-        private long mDurationMs;
-        // System uptime duration to check the result of an explicit health check
-        // Initially, MAX_VALUE until we get a value from the health check service
-        // and request health checks.
-        // This value in addition with mHasPassedHealthCheck determines the health check state
-        // of the package, see #getHealthCheckStateLocked
-        @GuardedBy("sLock")
-        private long mHealthCheckDurationMs = Long.MAX_VALUE;
-
-        MonitoredPackage(String packageName, long durationMs,
-                long healthCheckDurationMs, boolean hasPassedHealthCheck,
-                LongArrayQueue mitigationCalls) {
-            mPackageName = packageName;
-            mDurationMs = durationMs;
-            mHealthCheckDurationMs = healthCheckDurationMs;
-            mHasPassedHealthCheck = hasPassedHealthCheck;
-            mMitigationCalls = mitigationCalls;
-            updateHealthCheckStateLocked();
-        }
-
-        /** Writes the salient fields to disk using {@code out}.
-         * @hide
-         */
-        @GuardedBy("sLock")
-        public void writeLocked(XmlSerializer out) throws IOException {
-            out.startTag(null, TAG_PACKAGE);
-            out.attribute(null, ATTR_NAME, getName());
-            out.attribute(null, ATTR_DURATION, Long.toString(mDurationMs));
-            out.attribute(null, ATTR_EXPLICIT_HEALTH_CHECK_DURATION,
-                    Long.toString(mHealthCheckDurationMs));
-            out.attribute(null, ATTR_PASSED_HEALTH_CHECK, Boolean.toString(mHasPassedHealthCheck));
-            LongArrayQueue normalizedCalls = normalizeMitigationCalls();
-            out.attribute(null, ATTR_MITIGATION_CALLS, longArrayQueueToString(normalizedCalls));
-            out.endTag(null, TAG_PACKAGE);
-        }
-
-        /**
-         * Increment package failures or resets failure count depending on the last package failure.
-         *
-         * @return {@code true} if failure count exceeds a threshold, {@code false} otherwise
-         */
-        @GuardedBy("sLock")
-        public boolean onFailureLocked() {
-            // Sliding window algorithm: find out if there exists a window containing failures >=
-            // mTriggerFailureCount.
-            final long now = mSystemClock.uptimeMillis();
-            mFailureHistory.addLast(now);
-            while (now - mFailureHistory.peekFirst() > mTriggerFailureDurationMs) {
-                // Prune values falling out of the window
-                mFailureHistory.removeFirst();
-            }
-            boolean failed = mFailureHistory.size() >= mTriggerFailureCount;
-            if (failed) {
-                mFailureHistory.clear();
-            }
-            return failed;
-        }
-
-        /**
-         * Notes the timestamp of a mitigation call into the observer.
-         */
-        @GuardedBy("sLock")
-        public void noteMitigationCallLocked() {
-            mMitigationCalls.addLast(mSystemClock.uptimeMillis());
-        }
-
-        /**
-         * Prunes any mitigation calls outside of the de-escalation window, and returns the
-         * number of calls that are in the window afterwards.
-         *
-         * @return the number of mitigation calls made in the de-escalation window.
-         */
-        @GuardedBy("sLock")
-        public int getMitigationCountLocked() {
-            try {
-                final long now = mSystemClock.uptimeMillis();
-                while (now - mMitigationCalls.peekFirst() > DEFAULT_DEESCALATION_WINDOW_MS) {
-                    mMitigationCalls.removeFirst();
-                }
-            } catch (NoSuchElementException ignore) {
-            }
-
-            return mMitigationCalls.size();
-        }
-
-        /**
-         * Before writing to disk, make the mitigation call timestamps relative to the current
-         * system uptime. This is because they need to be relative to the uptime which will reset
-         * at the next boot.
-         *
-         * @return a LongArrayQueue of the mitigation calls relative to the current system uptime.
-         */
-        @GuardedBy("sLock")
-        public LongArrayQueue normalizeMitigationCalls() {
-            LongArrayQueue normalized = new LongArrayQueue();
-            final long now = mSystemClock.uptimeMillis();
-            for (int i = 0; i < mMitigationCalls.size(); i++) {
-                normalized.addLast(mMitigationCalls.get(i) - now);
-            }
-            return normalized;
-        }
-
-        /**
-         * Sets the initial health check duration.
-         *
-         * @return the new health check state
-         */
-        @GuardedBy("sLock")
-        public int setHealthCheckActiveLocked(long initialHealthCheckDurationMs) {
-            if (initialHealthCheckDurationMs <= 0) {
-                Slog.wtf(TAG, "Cannot set non-positive health check duration "
-                        + initialHealthCheckDurationMs + "ms for package " + getName()
-                        + ". Using total duration " + mDurationMs + "ms instead");
-                initialHealthCheckDurationMs = mDurationMs;
-            }
-            if (mHealthCheckState == HealthCheckState.INACTIVE) {
-                // Transitions to ACTIVE
-                mHealthCheckDurationMs = initialHealthCheckDurationMs;
-            }
-            return updateHealthCheckStateLocked();
-        }
-
-        /**
-         * Updates the monitoring durations of the package.
-         *
-         * @return the new health check state
-         */
-        @GuardedBy("sLock")
-        public int handleElapsedTimeLocked(long elapsedMs) {
-            if (elapsedMs <= 0) {
-                Slog.w(TAG, "Cannot handle non-positive elapsed time for package " + getName());
-                return mHealthCheckState;
-            }
-            // Transitions to FAILED if now <= 0 and health check not passed
-            mDurationMs -= elapsedMs;
-            if (mHealthCheckState == HealthCheckState.ACTIVE) {
-                // We only update health check durations if we have #setHealthCheckActiveLocked
-                // This ensures we don't leave the INACTIVE state for an unexpected elapsed time
-                // Transitions to FAILED if now <= 0 and health check not passed
-                mHealthCheckDurationMs -= elapsedMs;
-            }
-            return updateHealthCheckStateLocked();
-        }
-
-        /** Explicitly update the monitoring duration of the package. */
-        @GuardedBy("sLock")
-        public void updateHealthCheckDuration(long newDurationMs) {
-            mDurationMs = newDurationMs;
-        }
-
-        /**
-         * Marks the health check as passed and transitions to {@link HealthCheckState.PASSED}
-         * if not yet {@link HealthCheckState.FAILED}.
-         *
-         * @return the new {@link HealthCheckState health check state}
-         */
-        @GuardedBy("sLock")
-        @HealthCheckState
-        public int tryPassHealthCheckLocked() {
-            if (mHealthCheckState != HealthCheckState.FAILED) {
-                // FAILED is a final state so only pass if we haven't failed
-                // Transition to PASSED
-                mHasPassedHealthCheck = true;
-            }
-            return updateHealthCheckStateLocked();
-        }
-
-        /** Returns the monitored package name. */
-        private String getName() {
-            return mPackageName;
-        }
-
-        /**
-         * Returns the current {@link HealthCheckState health check state}.
-         */
-        @GuardedBy("sLock")
-        @HealthCheckState
-        public int getHealthCheckStateLocked() {
-            return mHealthCheckState;
-        }
-
-        /**
-         * Returns the shortest duration before the package should be scheduled for a prune.
-         *
-         * @return the duration or {@link Long#MAX_VALUE} if the package should not be scheduled
-         */
-        @GuardedBy("sLock")
-        public long getShortestScheduleDurationMsLocked() {
-            // Consider health check duration only if #isPendingHealthChecksLocked is true
-            return Math.min(toPositive(mDurationMs),
-                    isPendingHealthChecksLocked()
-                    ? toPositive(mHealthCheckDurationMs) : Long.MAX_VALUE);
-        }
-
-        /**
-         * Returns {@code true} if the total duration left to monitor the package is less than or
-         * equal to 0 {@code false} otherwise.
-         */
-        @GuardedBy("sLock")
-        public boolean isExpiredLocked() {
-            return mDurationMs <= 0;
-        }
-
-        /**
-         * Returns {@code true} if the package, {@link #getName} is expecting health check results
-         * {@code false} otherwise.
-         */
-        @GuardedBy("sLock")
-        public boolean isPendingHealthChecksLocked() {
-            return mHealthCheckState == HealthCheckState.ACTIVE
-                    || mHealthCheckState == HealthCheckState.INACTIVE;
-        }
-
-        /**
-         * Updates the health check state based on {@link #mHasPassedHealthCheck}
-         * and {@link #mHealthCheckDurationMs}.
-         *
-         * @return the new {@link HealthCheckState health check state}
-         */
-        @GuardedBy("sLock")
-        @HealthCheckState
-        private int updateHealthCheckStateLocked() {
-            int oldState = mHealthCheckState;
-            if (mHasPassedHealthCheck) {
-                // Set final state first to avoid ambiguity
-                mHealthCheckState = HealthCheckState.PASSED;
-            } else if (mHealthCheckDurationMs <= 0 || mDurationMs <= 0) {
-                // Set final state first to avoid ambiguity
-                mHealthCheckState = HealthCheckState.FAILED;
-            } else if (mHealthCheckDurationMs == Long.MAX_VALUE) {
-                mHealthCheckState = HealthCheckState.INACTIVE;
-            } else {
-                mHealthCheckState = HealthCheckState.ACTIVE;
-            }
-
-            if (oldState != mHealthCheckState) {
-                Slog.i(TAG, "Updated health check state for package " + getName() + ": "
-                        + toString(oldState) + " -> " + toString(mHealthCheckState));
-            }
-            return mHealthCheckState;
-        }
-
-        /** Returns a {@link String} representation of the current health check state. */
-        private String toString(@HealthCheckState int state) {
-            switch (state) {
-                case HealthCheckState.ACTIVE:
-                    return "ACTIVE";
-                case HealthCheckState.INACTIVE:
-                    return "INACTIVE";
-                case HealthCheckState.PASSED:
-                    return "PASSED";
-                case HealthCheckState.FAILED:
-                    return "FAILED";
-                default:
-                    return "UNKNOWN";
-            }
-        }
-
-        /** Returns {@code value} if it is greater than 0 or {@link Long#MAX_VALUE} otherwise. */
-        private long toPositive(long value) {
-            return value > 0 ? value : Long.MAX_VALUE;
-        }
-
-        /** Compares the equality of this object with another {@link MonitoredPackage}. */
-        @VisibleForTesting
-        boolean isEqualTo(MonitoredPackage pkg) {
-            return (getName().equals(pkg.getName()))
-                    && mDurationMs == pkg.mDurationMs
-                    && mHasPassedHealthCheck == pkg.mHasPassedHealthCheck
-                    && mHealthCheckDurationMs == pkg.mHealthCheckDurationMs
-                    && (mMitigationCalls.toString()).equals(pkg.mMitigationCalls.toString());
-        }
-    }
-
-    @GuardedBy("sLock")
-    @SuppressWarnings("GuardedBy")
-    void saveAllObserversBootMitigationCountToMetadata(String filePath) {
-        HashMap<String, Integer> bootMitigationCounts = new HashMap<>();
-        for (int i = 0; i < mAllObservers.size(); i++) {
-            final ObserverInternal observer = mAllObservers.valueAt(i);
-            bootMitigationCounts.put(observer.name, observer.getBootMitigationCount());
-        }
-
-        FileOutputStream fileStream = null;
-        ObjectOutputStream objectStream = null;
-        try {
-            fileStream = new FileOutputStream(new File(filePath));
-            objectStream = new ObjectOutputStream(fileStream);
-            objectStream.writeObject(bootMitigationCounts);
-            objectStream.flush();
-        } catch (Exception e) {
-            Slog.i(TAG, "Could not save observers metadata to file: " + e);
-            return;
-        } finally {
-            IoUtils.closeQuietly(objectStream);
-            IoUtils.closeQuietly(fileStream);
-        }
-    }
-
-    /**
-     * Handles the thresholding logic for system server boots.
-     */
-    class BootThreshold {
-
-        private final int mBootTriggerCount;
-        private final long mTriggerWindow;
-
-        BootThreshold(int bootTriggerCount, long triggerWindow) {
-            this.mBootTriggerCount = bootTriggerCount;
-            this.mTriggerWindow = triggerWindow;
-        }
-
-        public void reset() {
-            setStart(0);
-            setCount(0);
-        }
-
-        protected int getCount() {
-            return CrashRecoveryProperties.rescueBootCount().orElse(0);
-        }
-
-        protected void setCount(int count) {
-            CrashRecoveryProperties.rescueBootCount(count);
-        }
-
-        public long getStart() {
-            return CrashRecoveryProperties.rescueBootStart().orElse(0L);
-        }
-
-        public int getMitigationCount() {
-            return CrashRecoveryProperties.bootMitigationCount().orElse(0);
-        }
-
-        public void setStart(long start) {
-            CrashRecoveryProperties.rescueBootStart(getStartTime(start));
-        }
-
-        public void setMitigationStart(long start) {
-            CrashRecoveryProperties.bootMitigationStart(getStartTime(start));
-        }
-
-        public long getMitigationStart() {
-            return CrashRecoveryProperties.bootMitigationStart().orElse(0L);
-        }
-
-        public void setMitigationCount(int count) {
-            CrashRecoveryProperties.bootMitigationCount(count);
-        }
-
-        private static long constrain(long amount, long low, long high) {
-            return amount < low ? low : (amount > high ? high : amount);
-        }
-
-        public long getStartTime(long start) {
-            final long now = mSystemClock.uptimeMillis();
-            return constrain(start, 0, now);
-        }
-
-        public void saveMitigationCountToMetadata() {
-            try (BufferedWriter writer = new BufferedWriter(new FileWriter(METADATA_FILE))) {
-                writer.write(String.valueOf(getMitigationCount()));
-            } catch (Exception e) {
-                Slog.e(TAG, "Could not save metadata to file: " + e);
-            }
-        }
-
-        public void readMitigationCountFromMetadataIfNecessary() {
-            File bootPropsFile = new File(METADATA_FILE);
-            if (bootPropsFile.exists()) {
-                try (BufferedReader reader = new BufferedReader(new FileReader(METADATA_FILE))) {
-                    String mitigationCount = reader.readLine();
-                    setMitigationCount(Integer.parseInt(mitigationCount));
-                    bootPropsFile.delete();
-                } catch (Exception e) {
-                    Slog.i(TAG, "Could not read metadata file: " + e);
-                }
-            }
-        }
-
-
-        /** Increments the boot counter, and returns whether the device is bootlooping. */
-        @GuardedBy("sLock")
-        public boolean incrementAndTest() {
-            if (Flags.recoverabilityDetection()) {
-                readAllObserversBootMitigationCountIfNecessary(METADATA_FILE);
-            } else {
-                readMitigationCountFromMetadataIfNecessary();
-            }
-
-            final long now = mSystemClock.uptimeMillis();
-            if (now - getStart() < 0) {
-                Slog.e(TAG, "Window was less than zero. Resetting start to current time.");
-                setStart(now);
-                setMitigationStart(now);
-            }
-            if (now - getMitigationStart() > DEFAULT_DEESCALATION_WINDOW_MS) {
-                setMitigationStart(now);
-                if (Flags.recoverabilityDetection()) {
-                    resetAllObserversBootMitigationCount();
-                } else {
-                    setMitigationCount(0);
-                }
-            }
-            final long window = now - getStart();
-            if (window >= mTriggerWindow) {
-                setCount(1);
-                setStart(now);
-                return false;
-            } else {
-                int count = getCount() + 1;
-                setCount(count);
-                EventLog.writeEvent(LOG_TAG_RESCUE_NOTE, Process.ROOT_UID, count, window);
-                if (Flags.recoverabilityDetection()) {
-                    // After a reboot (e.g. by WARM_REBOOT or mainline rollback) we apply
-                    // mitigations without waiting for DEFAULT_BOOT_LOOP_TRIGGER_COUNT.
-                    return (count >= mBootTriggerCount)
-                            || (performedMitigationsDuringWindow() && count > 1);
-                }
-                return count >= mBootTriggerCount;
-            }
-        }
-
-        @GuardedBy("sLock")
-        private boolean performedMitigationsDuringWindow() {
-            for (ObserverInternal observerInternal: mAllObservers.values()) {
-                if (observerInternal.getBootMitigationCount() > 0) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        @GuardedBy("sLock")
-        private void resetAllObserversBootMitigationCount() {
-            for (int i = 0; i < mAllObservers.size(); i++) {
-                final ObserverInternal observer = mAllObservers.valueAt(i);
-                observer.setBootMitigationCount(0);
-            }
-            saveAllObserversBootMitigationCountToMetadata(METADATA_FILE);
-        }
-
-        @GuardedBy("sLock")
-        @SuppressWarnings("GuardedBy")
-        void readAllObserversBootMitigationCountIfNecessary(String filePath) {
-            File metadataFile = new File(filePath);
-            if (metadataFile.exists()) {
-                FileInputStream fileStream = null;
-                ObjectInputStream objectStream = null;
-                HashMap<String, Integer> bootMitigationCounts = null;
-                try {
-                    fileStream = new FileInputStream(metadataFile);
-                    objectStream = new ObjectInputStream(fileStream);
-                    bootMitigationCounts =
-                            (HashMap<String, Integer>) objectStream.readObject();
-                } catch (Exception e) {
-                    Slog.i(TAG, "Could not read observer metadata file: " + e);
-                   return;
-                } finally {
-                    IoUtils.closeQuietly(objectStream);
-                    IoUtils.closeQuietly(fileStream);
-                }
-
-                if (bootMitigationCounts == null || bootMitigationCounts.isEmpty()) {
-                    Slog.i(TAG, "No observer in metadata file");
-                    return;
-                }
-                for (int i = 0; i < mAllObservers.size(); i++) {
-                    final ObserverInternal observer = mAllObservers.valueAt(i);
-                    if (bootMitigationCounts.containsKey(observer.name)) {
-                        observer.setBootMitigationCount(
-                                bootMitigationCounts.get(observer.name));
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Register broadcast receiver for shutdown.
-     * We would save the observer state to persist across boots.
-     *
-     * @hide
-     */
-    public void registerShutdownBroadcastReceiver() {
-        BroadcastReceiver shutdownEventReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                // Only write if intent is relevant to device reboot or shutdown.
-                String intentAction = intent.getAction();
-                if (ACTION_REBOOT.equals(intentAction)
-                        || ACTION_SHUTDOWN.equals(intentAction)) {
-                    writeNow();
-                }
-            }
-        };
-
-        // Setup receiver for device reboots or shutdowns.
-        IntentFilter filter = new IntentFilter(ACTION_REBOOT);
-        filter.addAction(ACTION_SHUTDOWN);
-        mContext.registerReceiverForAllUsers(shutdownEventReceiver, filter, null,
-                /* run on main thread */ null);
-    }
-}
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/RescueParty.java b/packages/CrashRecovery/services/module/java/com/android/server/RescueParty.java
deleted file mode 100644
index 846da19..0000000
--- a/packages/CrashRecovery/services/module/java/com/android/server/RescueParty.java
+++ /dev/null
@@ -1,861 +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;
-
-import static com.android.server.PackageWatchdog.MITIGATION_RESULT_SKIPPED;
-import static com.android.server.PackageWatchdog.MITIGATION_RESULT_SUCCESS;
-import static com.android.server.crashrecovery.CrashRecoveryUtils.logCrashRecoveryEvent;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.VersionedPackage;
-import android.crashrecovery.flags.Flags;
-import android.os.Build;
-import android.os.PowerManager;
-import android.os.RecoverySystem;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.sysprop.CrashRecoveryProperties;
-import android.text.TextUtils;
-import android.util.EventLog;
-import android.util.FileUtils;
-import android.util.Log;
-import android.util.Slog;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.PackageWatchdog.FailureReasons;
-import com.android.server.PackageWatchdog.PackageHealthObserver;
-import com.android.server.PackageWatchdog.PackageHealthObserverImpact;
-import com.android.server.crashrecovery.proto.CrashRecoveryStatsLog;
-
-import java.io.File;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Utilities to help rescue the system from crash loops. Callers are expected to
- * report boot events and persistent app crashes, and if they happen frequently
- * enough this class will slowly escalate through several rescue operations
- * before finally rebooting and prompting the user if they want to wipe data as
- * a last resort.
- *
- * @hide
- */
-public class RescueParty {
-    @VisibleForTesting
-    static final String PROP_ENABLE_RESCUE = "persist.sys.enable_rescue";
-    @VisibleForTesting
-    static final int LEVEL_NONE = 0;
-    @VisibleForTesting
-    static final int LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS = 1;
-    @VisibleForTesting
-    static final int LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES = 2;
-    @VisibleForTesting
-    static final int LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS = 3;
-    @VisibleForTesting
-    static final int LEVEL_WARM_REBOOT = 4;
-    @VisibleForTesting
-    static final int LEVEL_FACTORY_RESET = 5;
-    @VisibleForTesting
-    static final int RESCUE_LEVEL_NONE = 0;
-    @VisibleForTesting
-    static final int RESCUE_LEVEL_SCOPED_DEVICE_CONFIG_RESET = 1;
-    @VisibleForTesting
-    static final int RESCUE_LEVEL_ALL_DEVICE_CONFIG_RESET = 2;
-    @VisibleForTesting
-    static final int RESCUE_LEVEL_WARM_REBOOT = 3;
-    @VisibleForTesting
-    static final int RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS = 4;
-    @VisibleForTesting
-    static final int RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES = 5;
-    @VisibleForTesting
-    static final int RESCUE_LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS = 6;
-    @VisibleForTesting
-    static final int RESCUE_LEVEL_FACTORY_RESET = 7;
-
-    @IntDef(prefix = { "RESCUE_LEVEL_" }, value = {
-        RESCUE_LEVEL_NONE,
-        RESCUE_LEVEL_SCOPED_DEVICE_CONFIG_RESET,
-        RESCUE_LEVEL_ALL_DEVICE_CONFIG_RESET,
-        RESCUE_LEVEL_WARM_REBOOT,
-        RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS,
-        RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES,
-        RESCUE_LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS,
-        RESCUE_LEVEL_FACTORY_RESET
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    @interface RescueLevels {}
-
-    @VisibleForTesting
-    static final String RESCUE_NON_REBOOT_LEVEL_LIMIT = "persist.sys.rescue_non_reboot_level_limit";
-    @VisibleForTesting
-    static final int DEFAULT_RESCUE_NON_REBOOT_LEVEL_LIMIT = RESCUE_LEVEL_WARM_REBOOT - 1;
-    @VisibleForTesting
-    static final String TAG = "RescueParty";
-    @VisibleForTesting
-    static final long DEFAULT_OBSERVING_DURATION_MS = TimeUnit.DAYS.toMillis(2);
-    @VisibleForTesting
-    static final int DEVICE_CONFIG_RESET_MODE = Settings.RESET_MODE_TRUSTED_DEFAULTS;
-    // The DeviceConfig namespace containing all RescueParty switches.
-    @VisibleForTesting
-    static final String NAMESPACE_CONFIGURATION = "configuration";
-    @VisibleForTesting
-    static final String NAMESPACE_TO_PACKAGE_MAPPING_FLAG =
-            "namespace_to_package_mapping";
-    @VisibleForTesting
-    static final long DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN = 1440;
-
-    private static final String NAME = "rescue-party-observer";
-
-    private static final String PROP_DISABLE_RESCUE = "persist.sys.disable_rescue";
-    private static final String PROP_VIRTUAL_DEVICE = "ro.hardware.virtual_device";
-    private static final String PROP_DEVICE_CONFIG_DISABLE_FLAG =
-            "persist.device_config.configuration.disable_rescue_party";
-    private static final String PROP_DISABLE_FACTORY_RESET_FLAG =
-            "persist.device_config.configuration.disable_rescue_party_factory_reset";
-    private static final String PROP_THROTTLE_DURATION_MIN_FLAG =
-            "persist.device_config.configuration.rescue_party_throttle_duration_min";
-
-    private static final int PERSISTENT_MASK = ApplicationInfo.FLAG_PERSISTENT
-            | ApplicationInfo.FLAG_SYSTEM;
-
-    /**
-     * EventLog tags used when logging into the event log. Note the values must be sync with
-     * frameworks/base/services/core/java/com/android/server/EventLogTags.logtags to get correct
-     * name translation.
-     */
-    private static final int LOG_TAG_RESCUE_SUCCESS = 2902;
-    private static final int LOG_TAG_RESCUE_FAILURE = 2903;
-
-    /** Register the Rescue Party observer as a Package Watchdog health observer */
-    public static void registerHealthObserver(Context context) {
-        PackageWatchdog.getInstance(context).registerHealthObserver(
-                context.getMainExecutor(), RescuePartyObserver.getInstance(context));
-    }
-
-    private static boolean isDisabled() {
-        // Check if we're explicitly enabled for testing
-        if (SystemProperties.getBoolean(PROP_ENABLE_RESCUE, false)) {
-            return false;
-        }
-
-        // We're disabled if the DeviceConfig disable flag is set to true.
-        // This is in case that an emergency rollback of the feature is needed.
-        if (SystemProperties.getBoolean(PROP_DEVICE_CONFIG_DISABLE_FLAG, false)) {
-            Slog.v(TAG, "Disabled because of DeviceConfig flag");
-            return true;
-        }
-
-        // We're disabled on all engineering devices
-        if (Build.TYPE.equals("eng")) {
-            Slog.v(TAG, "Disabled because of eng build");
-            return true;
-        }
-
-        // We're disabled on userdebug devices connected over USB, since that's
-        // a decent signal that someone is actively trying to debug the device,
-        // or that it's in a lab environment.
-        if (Build.TYPE.equals("userdebug") && isUsbActive()) {
-            Slog.v(TAG, "Disabled because of active USB connection");
-            return true;
-        }
-
-        // One last-ditch check
-        if (SystemProperties.getBoolean(PROP_DISABLE_RESCUE, false)) {
-            Slog.v(TAG, "Disabled because of manual property");
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Check if we're currently attempting to reboot for a factory reset. This method must
-     * return true if RescueParty tries to reboot early during a boot loop, since the device
-     * will not be fully booted at this time.
-     */
-    public static boolean isRecoveryTriggeredReboot() {
-        return isFactoryResetPropertySet() || isRebootPropertySet();
-    }
-
-    static boolean isFactoryResetPropertySet() {
-        return CrashRecoveryProperties.attemptingFactoryReset().orElse(false);
-    }
-
-    static boolean isRebootPropertySet() {
-        return CrashRecoveryProperties.attemptingReboot().orElse(false);
-    }
-
-    protected static long getLastFactoryResetTimeMs() {
-        return CrashRecoveryProperties.lastFactoryResetTimeMs().orElse(0L);
-    }
-
-    protected static int getMaxRescueLevelAttempted() {
-        return CrashRecoveryProperties.maxRescueLevelAttempted().orElse(LEVEL_NONE);
-    }
-
-    protected static void setFactoryResetProperty(boolean value) {
-        CrashRecoveryProperties.attemptingFactoryReset(value);
-    }
-    protected static void setRebootProperty(boolean value) {
-        CrashRecoveryProperties.attemptingReboot(value);
-    }
-
-    protected static void setLastFactoryResetTimeMs(long value) {
-        CrashRecoveryProperties.lastFactoryResetTimeMs(value);
-    }
-
-    protected static void setMaxRescueLevelAttempted(int level) {
-        CrashRecoveryProperties.maxRescueLevelAttempted(level);
-    }
-
-    @VisibleForTesting
-    static long getElapsedRealtime() {
-        return SystemClock.elapsedRealtime();
-    }
-
-    private static int getMaxRescueLevel(boolean mayPerformReboot) {
-        if (Flags.recoverabilityDetection()) {
-            if (!mayPerformReboot
-                    || SystemProperties.getBoolean(PROP_DISABLE_FACTORY_RESET_FLAG, false)) {
-                return SystemProperties.getInt(RESCUE_NON_REBOOT_LEVEL_LIMIT,
-                        DEFAULT_RESCUE_NON_REBOOT_LEVEL_LIMIT);
-            }
-            return RESCUE_LEVEL_FACTORY_RESET;
-        } else {
-            if (!mayPerformReboot
-                    || SystemProperties.getBoolean(PROP_DISABLE_FACTORY_RESET_FLAG, false)) {
-                return LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS;
-            }
-            return LEVEL_FACTORY_RESET;
-        }
-    }
-
-    private static int getMaxRescueLevel() {
-        if (!SystemProperties.getBoolean(PROP_DISABLE_FACTORY_RESET_FLAG, false)) {
-            return Level.factoryReset();
-        }
-        return Level.reboot();
-    }
-
-    /**
-     * Get the rescue level to perform if this is the n-th attempt at mitigating failure.
-     *
-     * @param mitigationCount: the mitigation attempt number (1 = first attempt etc.)
-     * @param mayPerformReboot: whether or not a reboot and factory reset may be performed
-     *                          for the given failure.
-     * @return the rescue level for the n-th mitigation attempt.
-     */
-    private static int getRescueLevel(int mitigationCount, boolean mayPerformReboot) {
-        if (!Flags.deprecateFlagsAndSettingsResets()) {
-            if (mitigationCount == 1) {
-                return LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS;
-            } else if (mitigationCount == 2) {
-                return LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES;
-            } else if (mitigationCount == 3) {
-                return LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS;
-            } else if (mitigationCount == 4) {
-                return Math.min(getMaxRescueLevel(mayPerformReboot), LEVEL_WARM_REBOOT);
-            } else if (mitigationCount >= 5) {
-                return Math.min(getMaxRescueLevel(mayPerformReboot), LEVEL_FACTORY_RESET);
-            } else {
-                Slog.w(TAG, "Expected positive mitigation count, was " + mitigationCount);
-                return LEVEL_NONE;
-            }
-        } else {
-            if (mitigationCount == 1) {
-                return Level.reboot();
-            } else if (mitigationCount >= 2) {
-                return Math.min(getMaxRescueLevel(), Level.factoryReset());
-            } else {
-                Slog.w(TAG, "Expected positive mitigation count, was " + mitigationCount);
-                return LEVEL_NONE;
-            }
-        }
-    }
-
-    /**
-     * Get the rescue level to perform if this is the n-th attempt at mitigating failure.
-     * When failedPackage is null then 1st and 2nd mitigation counts are redundant (scoped and
-     * all device config reset). Behaves as if one mitigation attempt was already done.
-     *
-     * @param mitigationCount the mitigation attempt number (1 = first attempt etc.).
-     * @param mayPerformReboot whether or not a reboot and factory reset may be performed
-     * for the given failure.
-     * @param failedPackage in case of bootloop this is null.
-     * @return the rescue level for the n-th mitigation attempt.
-     */
-    private static @RescueLevels int getRescueLevel(int mitigationCount, boolean mayPerformReboot,
-            @Nullable VersionedPackage failedPackage) {
-        // Skipping RESCUE_LEVEL_SCOPED_DEVICE_CONFIG_RESET since it's not defined without a failed
-        // package.
-        if (failedPackage == null && mitigationCount > 0) {
-            mitigationCount += 1;
-        }
-        if (mitigationCount == 1) {
-            return RESCUE_LEVEL_SCOPED_DEVICE_CONFIG_RESET;
-        } else if (mitigationCount == 2) {
-            return RESCUE_LEVEL_ALL_DEVICE_CONFIG_RESET;
-        } else if (mitigationCount == 3) {
-            return Math.min(getMaxRescueLevel(mayPerformReboot), RESCUE_LEVEL_WARM_REBOOT);
-        } else if (mitigationCount == 4) {
-            return Math.min(getMaxRescueLevel(mayPerformReboot),
-                    RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS);
-        } else if (mitigationCount == 5) {
-            return Math.min(getMaxRescueLevel(mayPerformReboot),
-                    RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES);
-        } else if (mitigationCount == 6) {
-            return Math.min(getMaxRescueLevel(mayPerformReboot),
-                    RESCUE_LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS);
-        } else if (mitigationCount >= 7) {
-            return Math.min(getMaxRescueLevel(mayPerformReboot), RESCUE_LEVEL_FACTORY_RESET);
-        } else {
-            return RESCUE_LEVEL_NONE;
-        }
-    }
-
-    /**
-     * Get the rescue level to perform if this is the n-th attempt at mitigating failure.
-     *
-     * @param mitigationCount the mitigation attempt number (1 = first attempt etc.).
-     * @return the rescue level for the n-th mitigation attempt.
-     */
-    private static @RescueLevels int getRescueLevel(int mitigationCount) {
-        if (mitigationCount == 1) {
-            return Level.reboot();
-        } else if (mitigationCount >= 2) {
-            return Math.min(getMaxRescueLevel(), Level.factoryReset());
-        } else {
-            return Level.none();
-        }
-    }
-
-    private static void executeRescueLevel(Context context, @Nullable String failedPackage,
-            int level) {
-        Slog.w(TAG, "Attempting rescue level " + levelToString(level));
-        try {
-            executeRescueLevelInternal(context, level, failedPackage);
-            EventLog.writeEvent(LOG_TAG_RESCUE_SUCCESS, level);
-            String successMsg = "Finished rescue level " + levelToString(level);
-            if (!TextUtils.isEmpty(failedPackage)) {
-                successMsg += " for package " + failedPackage;
-            }
-            logCrashRecoveryEvent(Log.DEBUG, successMsg);
-        } catch (Throwable t) {
-            logRescueException(level, failedPackage, t);
-        }
-    }
-
-    private static void executeRescueLevelInternal(Context context, int level, @Nullable
-            String failedPackage) throws Exception {
-        if (Flags.recoverabilityDetection()) {
-            executeRescueLevelInternalNew(context, level, failedPackage);
-        } else {
-            executeRescueLevelInternalOld(context, level, failedPackage);
-        }
-    }
-
-    private static void executeRescueLevelInternalOld(Context context, int level, @Nullable
-            String failedPackage) throws Exception {
-        CrashRecoveryStatsLog.write(CrashRecoveryStatsLog.RESCUE_PARTY_RESET_REPORTED,
-                level, levelToString(level));
-        // Try our best to reset all settings possible, and once finished
-        // rethrow any exception that we encountered
-        Exception res = null;
-        switch (level) {
-            case LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS:
-                break;
-            case LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES:
-                break;
-            case LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS:
-                break;
-            case LEVEL_WARM_REBOOT:
-                executeWarmReboot(context, level, failedPackage);
-                break;
-            case LEVEL_FACTORY_RESET:
-                // Before the completion of Reboot, if any crash happens then PackageWatchdog
-                // escalates to next level i.e. factory reset, as they happen in separate threads.
-                // Adding a check to prevent factory reset to execute before above reboot completes.
-                // Note: this reboot property is not persistent resets after reboot is completed.
-                if (isRebootPropertySet()) {
-                    return;
-                }
-                executeFactoryReset(context, level, failedPackage);
-                break;
-        }
-
-        if (res != null) {
-            throw res;
-        }
-    }
-
-    private static void executeRescueLevelInternalNew(Context context, @RescueLevels int level,
-            @Nullable String failedPackage) throws Exception {
-        CrashRecoveryStatsLog.write(CrashRecoveryStatsLog.RESCUE_PARTY_RESET_REPORTED,
-                level, levelToString(level));
-        switch (level) {
-            case RESCUE_LEVEL_SCOPED_DEVICE_CONFIG_RESET:
-                break;
-            case RESCUE_LEVEL_ALL_DEVICE_CONFIG_RESET:
-                break;
-            case RESCUE_LEVEL_WARM_REBOOT:
-                executeWarmReboot(context, level, failedPackage);
-                break;
-            case RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS:
-                // do nothing
-                break;
-            case RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES:
-                // do nothing
-                break;
-            case RESCUE_LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS:
-                // do nothing
-                break;
-            case RESCUE_LEVEL_FACTORY_RESET:
-                // Before the completion of Reboot, if any crash happens then PackageWatchdog
-                // escalates to next level i.e. factory reset, as they happen in separate threads.
-                // Adding a check to prevent factory reset to execute before above reboot completes.
-                // Note: this reboot property is not persistent resets after reboot is completed.
-                if (isRebootPropertySet()) {
-                    return;
-                }
-                executeFactoryReset(context, level, failedPackage);
-                break;
-        }
-    }
-
-    private static void executeWarmReboot(Context context, int level,
-            @Nullable String failedPackage) {
-        if (Flags.deprecateFlagsAndSettingsResets()) {
-            if (shouldThrottleReboot()) {
-                return;
-            }
-        }
-
-        // Request the reboot from a separate thread to avoid deadlock on PackageWatchdog
-        // when device shutting down.
-        setRebootProperty(true);
-
-        if (Flags.synchronousRebootInRescueParty()) {
-            try {
-                PowerManager pm = context.getSystemService(PowerManager.class);
-                if (pm != null) {
-                    pm.reboot(TAG);
-                }
-            } catch (Throwable t) {
-                logRescueException(level, failedPackage, t);
-            }
-        } else {
-            Runnable runnable = () -> {
-                try {
-                    PowerManager pm = context.getSystemService(PowerManager.class);
-                    if (pm != null) {
-                        pm.reboot(TAG);
-                    }
-                } catch (Throwable t) {
-                    logRescueException(level, failedPackage, t);
-                }
-            };
-            Thread thread = new Thread(runnable);
-            thread.start();
-        }
-    }
-
-    private static void executeFactoryReset(Context context, int level,
-            @Nullable String failedPackage) {
-        if (Flags.deprecateFlagsAndSettingsResets()) {
-            if (shouldThrottleReboot()) {
-                return;
-            }
-        }
-        setFactoryResetProperty(true);
-        long now = System.currentTimeMillis();
-        setLastFactoryResetTimeMs(now);
-
-        if (Flags.synchronousRebootInRescueParty()) {
-            try {
-                RecoverySystem.rebootPromptAndWipeUserData(context, TAG + "," + failedPackage);
-            } catch (Throwable t) {
-                logRescueException(level, failedPackage, t);
-            }
-        } else {
-            Runnable runnable = new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        RecoverySystem.rebootPromptAndWipeUserData(context,
-                            TAG + "," + failedPackage);
-                    } catch (Throwable t) {
-                        logRescueException(level, failedPackage, t);
-                    }
-                }
-            };
-            Thread thread = new Thread(runnable);
-            thread.start();
-        }
-    }
-
-
-    private static String getCompleteMessage(Throwable t) {
-        final StringBuilder builder = new StringBuilder();
-        builder.append(t.getMessage());
-        while ((t = t.getCause()) != null) {
-            builder.append(": ").append(t.getMessage());
-        }
-        return builder.toString();
-    }
-
-    private static void logRescueException(int level, @Nullable String failedPackageName,
-            Throwable t) {
-        final String msg = getCompleteMessage(t);
-        EventLog.writeEvent(LOG_TAG_RESCUE_FAILURE, level, msg);
-        String failureMsg = "Failed rescue level " + levelToString(level);
-        if (!TextUtils.isEmpty(failedPackageName)) {
-            failureMsg += " for package " + failedPackageName;
-        }
-        logCrashRecoveryEvent(Log.ERROR, failureMsg + ": " + msg);
-    }
-
-    private static int mapRescueLevelToUserImpact(int rescueLevel) {
-        if (Flags.recoverabilityDetection()) {
-            switch (rescueLevel) {
-                case RESCUE_LEVEL_SCOPED_DEVICE_CONFIG_RESET:
-                    return PackageHealthObserverImpact.USER_IMPACT_LEVEL_10;
-                case RESCUE_LEVEL_ALL_DEVICE_CONFIG_RESET:
-                    return PackageHealthObserverImpact.USER_IMPACT_LEVEL_40;
-                case RESCUE_LEVEL_WARM_REBOOT:
-                    return PackageHealthObserverImpact.USER_IMPACT_LEVEL_50;
-                case RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS:
-                    return PackageHealthObserverImpact.USER_IMPACT_LEVEL_71;
-                case RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES:
-                    return PackageHealthObserverImpact.USER_IMPACT_LEVEL_75;
-                case RESCUE_LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS:
-                    return PackageHealthObserverImpact.USER_IMPACT_LEVEL_80;
-                case RESCUE_LEVEL_FACTORY_RESET:
-                    return PackageHealthObserverImpact.USER_IMPACT_LEVEL_100;
-                default:
-                    return PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
-            }
-        } else {
-            switch (rescueLevel) {
-                case LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS:
-                case LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES:
-                    return PackageHealthObserverImpact.USER_IMPACT_LEVEL_10;
-                case LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS:
-                case LEVEL_WARM_REBOOT:
-                    return PackageHealthObserverImpact.USER_IMPACT_LEVEL_50;
-                case LEVEL_FACTORY_RESET:
-                    return PackageHealthObserverImpact.USER_IMPACT_LEVEL_100;
-                default:
-                    return PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
-            }
-        }
-    }
-
-    /**
-     * Handle mitigation action for package failures. This observer will be register to Package
-     * Watchdog and will receive calls about package failures. This observer is persistent so it
-     * may choose to mitigate failures for packages it has not explicitly asked to observe.
-     */
-    public static class RescuePartyObserver implements PackageHealthObserver {
-
-        private final Context mContext;
-        private final Map<String, Set<String>> mCallingPackageNamespaceSetMap = new HashMap<>();
-        private final Map<String, Set<String>> mNamespaceCallingPackageSetMap = new HashMap<>();
-
-        @GuardedBy("RescuePartyObserver.class")
-        static RescuePartyObserver sRescuePartyObserver;
-
-        private RescuePartyObserver(Context context) {
-            mContext = context;
-        }
-
-        /** Creates or gets singleton instance of RescueParty. */
-        public static RescuePartyObserver getInstance(Context context) {
-            synchronized (RescuePartyObserver.class) {
-                if (sRescuePartyObserver == null) {
-                    sRescuePartyObserver = new RescuePartyObserver(context);
-                }
-                return sRescuePartyObserver;
-            }
-        }
-
-        /** Gets singleton instance. It returns null if the instance is not created yet.*/
-        @Nullable
-        public static RescuePartyObserver getInstanceIfCreated() {
-            synchronized (RescuePartyObserver.class) {
-                return sRescuePartyObserver;
-            }
-        }
-
-        @VisibleForTesting
-        static void reset() {
-            synchronized (RescuePartyObserver.class) {
-                sRescuePartyObserver = null;
-            }
-        }
-
-        @Override
-        public int onHealthCheckFailed(@Nullable VersionedPackage failedPackage,
-                @FailureReasons int failureReason, int mitigationCount) {
-            int impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
-            if (!isDisabled() && (failureReason == PackageWatchdog.FAILURE_REASON_APP_CRASH
-                    || failureReason == PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING)) {
-                if (Flags.recoverabilityDetection()) {
-                    if (!Flags.deprecateFlagsAndSettingsResets()) {
-                        impact =  mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
-                                mayPerformReboot(failedPackage), failedPackage));
-                    } else {
-                        impact =  mapRescueLevelToUserImpact(getRescueLevel(mitigationCount));
-                    }
-                } else {
-                    impact =  mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
-                            mayPerformReboot(failedPackage)));
-                }
-            }
-
-            Slog.i(TAG, "Checking available remediations for health check failure."
-                    + " failedPackage: "
-                    + (failedPackage == null ? null : failedPackage.getPackageName())
-                    + " failureReason: " + failureReason
-                    + " available impact: " + impact);
-            return impact;
-        }
-
-        @Override
-        public int onExecuteHealthCheckMitigation(@Nullable VersionedPackage failedPackage,
-                @FailureReasons int failureReason, int mitigationCount) {
-            if (isDisabled()) {
-                return MITIGATION_RESULT_SKIPPED;
-            }
-            Slog.i(TAG, "Executing remediation."
-                    + " failedPackage: "
-                    + (failedPackage == null ? null : failedPackage.getPackageName())
-                    + " failureReason: " + failureReason
-                    + " mitigationCount: " + mitigationCount);
-            if (failureReason == PackageWatchdog.FAILURE_REASON_APP_CRASH
-                    || failureReason == PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING) {
-                final int level;
-                if (Flags.recoverabilityDetection()) {
-                    if (!Flags.deprecateFlagsAndSettingsResets()) {
-                        level = getRescueLevel(mitigationCount, mayPerformReboot(failedPackage),
-                                failedPackage);
-                    } else {
-                        level = getRescueLevel(mitigationCount);
-                    }
-                } else {
-                    level = getRescueLevel(mitigationCount, mayPerformReboot(failedPackage));
-                }
-                executeRescueLevel(mContext,
-                        failedPackage == null ? null : failedPackage.getPackageName(), level);
-                return MITIGATION_RESULT_SUCCESS;
-            } else {
-                return MITIGATION_RESULT_SKIPPED;
-            }
-        }
-
-        @Override
-        public boolean isPersistent() {
-            return true;
-        }
-
-        @Override
-        public boolean mayObservePackage(String packageName) {
-            PackageManager pm = mContext.getPackageManager();
-            try {
-                // A package is a module if this is non-null
-                if (pm.getModuleInfo(packageName, 0) != null) {
-                    return true;
-                }
-            } catch (PackageManager.NameNotFoundException | IllegalStateException ignore) {
-            }
-
-            return isPersistentSystemApp(packageName);
-        }
-
-        @Override
-        public int onBootLoop(int mitigationCount) {
-            if (isDisabled()) {
-                return PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
-            }
-            if (Flags.recoverabilityDetection()) {
-                if (!Flags.deprecateFlagsAndSettingsResets()) {
-                    return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
-                            true, /*failedPackage=*/ null));
-                } else {
-                    return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount));
-                }
-            } else {
-                return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount, true));
-            }
-        }
-
-        @Override
-        public int onExecuteBootLoopMitigation(int mitigationCount) {
-            if (isDisabled()) {
-                return MITIGATION_RESULT_SKIPPED;
-            }
-            boolean mayPerformReboot = !shouldThrottleReboot();
-            final int level;
-            if (Flags.recoverabilityDetection()) {
-                if (!Flags.deprecateFlagsAndSettingsResets()) {
-                    level = getRescueLevel(mitigationCount, mayPerformReboot,
-                            /*failedPackage=*/ null);
-                } else {
-                    level = getRescueLevel(mitigationCount);
-                }
-            } else {
-                level = getRescueLevel(mitigationCount, mayPerformReboot);
-            }
-            executeRescueLevel(mContext, /*failedPackage=*/ null, level);
-            return MITIGATION_RESULT_SUCCESS;
-        }
-
-        @Override
-        public String getUniqueIdentifier() {
-            return NAME;
-        }
-
-        /**
-         * Returns {@code true} if the failing package is non-null and performing a reboot or
-         * prompting a factory reset is an acceptable mitigation strategy for the package's
-         * failure, {@code false} otherwise.
-         */
-        private boolean mayPerformReboot(@Nullable VersionedPackage failingPackage) {
-            if (failingPackage == null) {
-                return false;
-            }
-            if (shouldThrottleReboot())  {
-                return false;
-            }
-
-            return isPersistentSystemApp(failingPackage.getPackageName());
-        }
-
-        private boolean isPersistentSystemApp(@NonNull String packageName) {
-            PackageManager pm = mContext.getPackageManager();
-            try {
-                ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
-                return (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK;
-            } catch (PackageManager.NameNotFoundException e) {
-                return false;
-            }
-        }
-
-        private synchronized Set<String> getCallingPackagesSet(String namespace) {
-            return mNamespaceCallingPackageSetMap.get(namespace);
-        }
-    }
-
-    /**
-     * Returns {@code true} if Rescue Party is allowed to attempt a reboot or factory reset.
-     * Will return {@code false} if a factory reset was already offered recently.
-     */
-    private static boolean shouldThrottleReboot() {
-        Long lastResetTime = getLastFactoryResetTimeMs();
-        long now = System.currentTimeMillis();
-        long throttleDurationMin = SystemProperties.getLong(PROP_THROTTLE_DURATION_MIN_FLAG,
-                DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN);
-        return now < lastResetTime + TimeUnit.MINUTES.toMillis(throttleDurationMin);
-    }
-
-    /**
-     * Hacky test to check if the device has an active USB connection, which is
-     * a good proxy for someone doing local development work.
-     */
-    private static boolean isUsbActive() {
-        if (SystemProperties.getBoolean(PROP_VIRTUAL_DEVICE, false)) {
-            Slog.v(TAG, "Assuming virtual device is connected over USB");
-            return true;
-        }
-        try {
-            final String state = FileUtils
-                    .readTextFile(new File("/sys/class/android_usb/android0/state"), 128, "");
-            return "CONFIGURED".equals(state.trim());
-        } catch (Throwable t) {
-            Slog.w(TAG, "Failed to determine if device was on USB", t);
-            return false;
-        }
-    }
-
-    private static class Level {
-        static int none() {
-            return Flags.recoverabilityDetection() ? RESCUE_LEVEL_NONE : LEVEL_NONE;
-        }
-
-        static int reboot() {
-            return Flags.recoverabilityDetection() ? RESCUE_LEVEL_WARM_REBOOT : LEVEL_WARM_REBOOT;
-        }
-
-        static int factoryReset() {
-            return Flags.recoverabilityDetection()
-                    ? RESCUE_LEVEL_FACTORY_RESET
-                    : LEVEL_FACTORY_RESET;
-        }
-    }
-
-    private static String levelToString(int level) {
-        if (Flags.recoverabilityDetection()) {
-            switch (level) {
-                case RESCUE_LEVEL_NONE:
-                    return "NONE";
-                case RESCUE_LEVEL_SCOPED_DEVICE_CONFIG_RESET:
-                    return "SCOPED_DEVICE_CONFIG_RESET";
-                case RESCUE_LEVEL_ALL_DEVICE_CONFIG_RESET:
-                    return "ALL_DEVICE_CONFIG_RESET";
-                case RESCUE_LEVEL_WARM_REBOOT:
-                    return "WARM_REBOOT";
-                case RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS:
-                    return "RESET_SETTINGS_UNTRUSTED_DEFAULTS";
-                case RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES:
-                    return "RESET_SETTINGS_UNTRUSTED_CHANGES";
-                case RESCUE_LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS:
-                    return "RESET_SETTINGS_TRUSTED_DEFAULTS";
-                case RESCUE_LEVEL_FACTORY_RESET:
-                    return "FACTORY_RESET";
-                default:
-                    return Integer.toString(level);
-            }
-        } else {
-            switch (level) {
-                case LEVEL_NONE:
-                    return "NONE";
-                case LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS:
-                    return "RESET_SETTINGS_UNTRUSTED_DEFAULTS";
-                case LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES:
-                    return "RESET_SETTINGS_UNTRUSTED_CHANGES";
-                case LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS:
-                    return "RESET_SETTINGS_TRUSTED_DEFAULTS";
-                case LEVEL_WARM_REBOOT:
-                    return "WARM_REBOOT";
-                case LEVEL_FACTORY_RESET:
-                    return "FACTORY_RESET";
-                default:
-                    return Integer.toString(level);
-            }
-        }
-    }
-}
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/crashrecovery/CrashRecoveryModule.java b/packages/CrashRecovery/services/module/java/com/android/server/crashrecovery/CrashRecoveryModule.java
deleted file mode 100644
index 8a81aaa..0000000
--- a/packages/CrashRecovery/services/module/java/com/android/server/crashrecovery/CrashRecoveryModule.java
+++ /dev/null
@@ -1,58 +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.server.crashrecovery;
-
-import android.content.Context;
-
-import com.android.server.PackageWatchdog;
-import com.android.server.RescueParty;
-import com.android.server.SystemService;
-
-
-/** This class encapsulate the lifecycle methods of CrashRecovery module.
- *
- * @hide
- */
-public class CrashRecoveryModule {
-    private static final String TAG = "CrashRecoveryModule";
-
-    /** Lifecycle definition for CrashRecovery module. */
-    public static class Lifecycle extends SystemService {
-        private Context mSystemContext;
-        private PackageWatchdog mPackageWatchdog;
-
-        public Lifecycle(Context context) {
-            super(context);
-            mSystemContext = context;
-            mPackageWatchdog = PackageWatchdog.getInstance(context);
-        }
-
-        @Override
-        public void onStart() {
-            RescueParty.registerHealthObserver(mSystemContext);
-            mPackageWatchdog.registerShutdownBroadcastReceiver();
-            mPackageWatchdog.noteBoot();
-        }
-
-        @Override
-        public void onBootPhase(int phase) {
-            if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
-                mPackageWatchdog.onPackagesReady();
-            }
-        }
-    }
-}
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/crashrecovery/CrashRecoveryUtils.java b/packages/CrashRecovery/services/module/java/com/android/server/crashrecovery/CrashRecoveryUtils.java
deleted file mode 100644
index 2e2a937..0000000
--- a/packages/CrashRecovery/services/module/java/com/android/server/crashrecovery/CrashRecoveryUtils.java
+++ /dev/null
@@ -1,85 +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.server.crashrecovery;
-
-import android.os.Environment;
-import android.util.IndentingPrintWriter;
-import android.util.Log;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-
-/**
- * Class containing helper methods for the CrashRecoveryModule.
- *
- * @hide
- */
-public class CrashRecoveryUtils {
-    private static final String TAG = "CrashRecoveryUtils";
-    private static final long MAX_CRITICAL_INFO_DUMP_SIZE = 1000 * 1000; // ~1MB
-    private static final Object sFileLock = new Object();
-
-    /** Persist recovery related events in crashrecovery events file.**/
-    public static void logCrashRecoveryEvent(int priority, String msg) {
-        Log.println(priority, TAG, msg);
-        try {
-            File fname = getCrashRecoveryEventsFile();
-            synchronized (sFileLock) {
-                FileOutputStream out = new FileOutputStream(fname, true);
-                PrintWriter pw = new PrintWriter(out);
-                String dateString = LocalDateTime.now(ZoneId.systemDefault()).toString();
-                pw.println(dateString + ": " + msg);
-                pw.close();
-            }
-        } catch (IOException e) {
-            Log.e(TAG, "Unable to log CrashRecoveryEvents " + e.getMessage());
-        }
-    }
-
-    /** Dump recovery related events from crashrecovery events file.**/
-    public static void dumpCrashRecoveryEvents(IndentingPrintWriter pw) {
-        pw.println("CrashRecovery Events: ");
-        pw.increaseIndent();
-        final File file = getCrashRecoveryEventsFile();
-        final long skipSize = file.length() - MAX_CRITICAL_INFO_DUMP_SIZE;
-        synchronized (sFileLock) {
-            try (BufferedReader in = new BufferedReader(new FileReader(file))) {
-                if (skipSize > 0) {
-                    in.skip(skipSize);
-                }
-                String line;
-                while ((line = in.readLine()) != null) {
-                    pw.println(line);
-                }
-            } catch (IOException e) {
-                Log.e(TAG, "Unable to dump CrashRecoveryEvents " + e.getMessage());
-            }
-        }
-        pw.decreaseIndent();
-    }
-
-    private static File getCrashRecoveryEventsFile() {
-        File systemDir = new File(Environment.getDataDirectory(), "system");
-        return new File(systemDir, "crashrecovery-events.txt");
-    }
-}
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/packages/CrashRecovery/services/module/java/com/android/server/rollback/RollbackPackageHealthObserver.java
deleted file mode 100644
index 4978df4..0000000
--- a/packages/CrashRecovery/services/module/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ /dev/null
@@ -1,785 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.rollback;
-
-import static com.android.server.PackageWatchdog.MITIGATION_RESULT_SKIPPED;
-import static com.android.server.PackageWatchdog.MITIGATION_RESULT_SUCCESS;
-import static com.android.server.crashrecovery.CrashRecoveryUtils.logCrashRecoveryEvent;
-
-import android.annotation.AnyThread;
-import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.annotation.WorkerThread;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.VersionedPackage;
-import android.content.rollback.PackageRollbackInfo;
-import android.content.rollback.RollbackInfo;
-import android.content.rollback.RollbackManager;
-import android.crashrecovery.flags.Flags;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.PowerManager;
-import android.os.SystemProperties;
-import android.sysprop.CrashRecoveryProperties;
-import android.util.ArraySet;
-import android.util.FileUtils;
-import android.util.Log;
-import android.util.Slog;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.Preconditions;
-import com.android.server.PackageWatchdog;
-import com.android.server.PackageWatchdog.FailureReasons;
-import com.android.server.PackageWatchdog.PackageHealthObserver;
-import com.android.server.PackageWatchdog.PackageHealthObserverImpact;
-import com.android.server.crashrecovery.proto.CrashRecoveryStatsLog;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Set;
-import java.util.function.Consumer;
-
-/**
- * {@link PackageHealthObserver} for {@link RollbackManagerService}.
- * This class monitors crashes and triggers RollbackManager rollback accordingly.
- * It also monitors native crashes for some short while after boot.
- *
- * @hide
- */
-@FlaggedApi(Flags.FLAG_ENABLE_CRASHRECOVERY)
-@SuppressLint({"CallbackName"})
-@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-public final class RollbackPackageHealthObserver implements PackageHealthObserver {
-    private static final String TAG = "RollbackPackageHealthObserver";
-    private static final String NAME = "rollback-observer";
-    private static final String CLASS_NAME = RollbackPackageHealthObserver.class.getName();
-
-    private static final int PERSISTENT_MASK = ApplicationInfo.FLAG_PERSISTENT
-            | ApplicationInfo.FLAG_SYSTEM;
-
-    private static final String PROP_DISABLE_HIGH_IMPACT_ROLLBACK_FLAG =
-            "persist.device_config.configuration.disable_high_impact_rollback";
-
-    private final Context mContext;
-    private final Handler mHandler;
-    private final File mLastStagedRollbackIdsFile;
-    private final File mTwoPhaseRollbackEnabledFile;
-    // Staged rollback ids that have been committed but their session is not yet ready
-    private final Set<Integer> mPendingStagedRollbackIds = new ArraySet<>();
-    // True if needing to roll back only rebootless apexes when native crash happens
-    private boolean mTwoPhaseRollbackEnabled;
-
-    @VisibleForTesting
-    public RollbackPackageHealthObserver(@NonNull Context context) {
-        mContext = context;
-        HandlerThread handlerThread = new HandlerThread("RollbackPackageHealthObserver");
-        handlerThread.start();
-        mHandler = new Handler(handlerThread.getLooper());
-        File dataDir = new File(Environment.getDataDirectory(), "rollback-observer");
-        dataDir.mkdirs();
-        mLastStagedRollbackIdsFile = new File(dataDir, "last-staged-rollback-ids");
-        mTwoPhaseRollbackEnabledFile = new File(dataDir, "two-phase-rollback-enabled");
-        PackageWatchdog.getInstance(mContext).registerHealthObserver(context.getMainExecutor(),
-                this);
-
-        if (SystemProperties.getBoolean("sys.boot_completed", false)) {
-            // Load the value from the file if system server has crashed and restarted
-            mTwoPhaseRollbackEnabled = readBoolean(mTwoPhaseRollbackEnabledFile);
-        } else {
-            // Disable two-phase rollback for a normal reboot. We assume the rebootless apex
-            // installed before reboot is stable if native crash didn't happen.
-            mTwoPhaseRollbackEnabled = false;
-            writeBoolean(mTwoPhaseRollbackEnabledFile, false);
-        }
-    }
-
-    @Override
-    public int onHealthCheckFailed(@Nullable VersionedPackage failedPackage,
-            @FailureReasons int failureReason, int mitigationCount) {
-        int impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
-        if (Flags.recoverabilityDetection()) {
-            List<RollbackInfo> availableRollbacks = getAvailableRollbacks();
-            List<RollbackInfo> lowImpactRollbacks = getRollbacksAvailableForImpactLevel(
-                    availableRollbacks, PackageManager.ROLLBACK_USER_IMPACT_LOW);
-            if (!lowImpactRollbacks.isEmpty()) {
-                if (failureReason == PackageWatchdog.FAILURE_REASON_NATIVE_CRASH) {
-                    // For native crashes, we will directly roll back any available rollbacks at low
-                    // impact level
-                    impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_30;
-                } else if (getRollbackForPackage(failedPackage, lowImpactRollbacks) != null) {
-                    // Rollback is available for crashing low impact package
-                    impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_30;
-                } else {
-                    impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_70;
-                }
-            }
-        } else {
-            boolean anyRollbackAvailable = !mContext.getSystemService(RollbackManager.class)
-                    .getAvailableRollbacks().isEmpty();
-
-            if (failureReason == PackageWatchdog.FAILURE_REASON_NATIVE_CRASH
-                    && anyRollbackAvailable) {
-                // For native crashes, we will directly roll back any available rollbacks
-                // Note: For non-native crashes the rollback-all step has higher impact
-                impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_30;
-            } else if (getAvailableRollback(failedPackage) != null) {
-                // Rollback is available, we may get a callback into #onExecuteHealthCheckMitigation
-                impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_30;
-            } else if (anyRollbackAvailable) {
-                // If any rollbacks are available, we will commit them
-                impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_70;
-            }
-        }
-
-        Slog.i(TAG, "Checking available remediations for health check failure."
-                + " failedPackage: "
-                + (failedPackage == null ? null : failedPackage.getPackageName())
-                + " failureReason: " + failureReason
-                + " available impact: " + impact);
-        return impact;
-    }
-
-    @Override
-    public int onExecuteHealthCheckMitigation(@Nullable VersionedPackage failedPackage,
-            @FailureReasons int rollbackReason, int mitigationCount) {
-        Slog.i(TAG, "Executing remediation."
-                + " failedPackage: "
-                + (failedPackage == null ? null : failedPackage.getPackageName())
-                + " rollbackReason: " + rollbackReason
-                + " mitigationCount: " + mitigationCount);
-        if (Flags.recoverabilityDetection()) {
-            List<RollbackInfo> availableRollbacks = getAvailableRollbacks();
-            if (rollbackReason == PackageWatchdog.FAILURE_REASON_NATIVE_CRASH) {
-                mHandler.post(() -> rollbackAllLowImpact(availableRollbacks, rollbackReason));
-                return MITIGATION_RESULT_SUCCESS;
-            }
-
-            List<RollbackInfo> lowImpactRollbacks = getRollbacksAvailableForImpactLevel(
-                    availableRollbacks, PackageManager.ROLLBACK_USER_IMPACT_LOW);
-            RollbackInfo rollback = getRollbackForPackage(failedPackage, lowImpactRollbacks);
-            if (rollback != null) {
-                mHandler.post(() -> rollbackPackage(rollback, failedPackage, rollbackReason));
-            } else if (!lowImpactRollbacks.isEmpty()) {
-                // Apply all available low impact rollbacks.
-                mHandler.post(() -> rollbackAllLowImpact(availableRollbacks, rollbackReason));
-            }
-        } else {
-            if (rollbackReason == PackageWatchdog.FAILURE_REASON_NATIVE_CRASH) {
-                mHandler.post(() -> rollbackAll(rollbackReason));
-                return MITIGATION_RESULT_SUCCESS;
-            }
-
-            RollbackInfo rollback = getAvailableRollback(failedPackage);
-            if (rollback != null) {
-                mHandler.post(() -> rollbackPackage(rollback, failedPackage, rollbackReason));
-            } else {
-                mHandler.post(() -> rollbackAll(rollbackReason));
-            }
-        }
-
-        // Assume rollbacks executed successfully
-        return MITIGATION_RESULT_SUCCESS;
-    }
-
-    @Override
-    public int onBootLoop(int mitigationCount) {
-        int impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
-        if (Flags.recoverabilityDetection()) {
-            List<RollbackInfo> availableRollbacks = getAvailableRollbacks();
-            if (!availableRollbacks.isEmpty()) {
-                impact = getUserImpactBasedOnRollbackImpactLevel(availableRollbacks);
-            }
-        }
-        return impact;
-    }
-
-    @Override
-    public int onExecuteBootLoopMitigation(int mitigationCount) {
-        if (Flags.recoverabilityDetection()) {
-            List<RollbackInfo> availableRollbacks = getAvailableRollbacks();
-
-            triggerLeastImpactLevelRollback(availableRollbacks,
-                    PackageWatchdog.FAILURE_REASON_BOOT_LOOP);
-            return MITIGATION_RESULT_SUCCESS;
-        }
-        return MITIGATION_RESULT_SKIPPED;
-    }
-
-    @Override
-    @NonNull
-    public String getUniqueIdentifier() {
-        return NAME;
-    }
-
-    @Override
-    public boolean isPersistent() {
-        return true;
-    }
-
-    @Override
-    public boolean mayObservePackage(@NonNull String packageName) {
-        if (getAvailableRollbacks().isEmpty()) {
-            return false;
-        }
-        return isPersistentSystemApp(packageName);
-    }
-
-    private List<RollbackInfo> getAvailableRollbacks() {
-        return mContext.getSystemService(RollbackManager.class).getAvailableRollbacks();
-    }
-
-    private boolean isPersistentSystemApp(@NonNull String packageName) {
-        PackageManager pm = mContext.getPackageManager();
-        try {
-            ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
-            return (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK;
-        } catch (PackageManager.NameNotFoundException e) {
-            return false;
-        }
-    }
-
-    private void assertInWorkerThread() {
-        Preconditions.checkState(mHandler.getLooper().isCurrentThread());
-    }
-
-    @AnyThread
-    @NonNull
-    public void notifyRollbackAvailable(@NonNull RollbackInfo rollback) {
-        mHandler.post(() -> {
-            // Enable two-phase rollback when a rebootless apex rollback is made available.
-            // We assume the rebootless apex is stable and is less likely to be the cause
-            // if native crash doesn't happen before reboot. So we will clear the flag and disable
-            // two-phase rollback after reboot.
-            if (isRebootlessApex(rollback)) {
-                mTwoPhaseRollbackEnabled = true;
-                writeBoolean(mTwoPhaseRollbackEnabledFile, true);
-            }
-        });
-    }
-
-    private static boolean isRebootlessApex(RollbackInfo rollback) {
-        if (!rollback.isStaged()) {
-            for (PackageRollbackInfo info : rollback.getPackages()) {
-                if (info.isApex()) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /** Verifies the rollback state after a reboot and schedules polling for sometime after reboot
-     * to check for native crashes and mitigate them if needed.
-     */
-    @AnyThread
-    public void onBootCompletedAsync() {
-        mHandler.post(()->onBootCompleted());
-    }
-
-    @WorkerThread
-    private void onBootCompleted() {
-        assertInWorkerThread();
-
-        RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
-        if (!rollbackManager.getAvailableRollbacks().isEmpty()) {
-            // TODO(gavincorkery): Call into Package Watchdog from outside the observer
-            PackageWatchdog.getInstance(mContext).scheduleCheckAndMitigateNativeCrashes();
-        }
-
-        SparseArray<String> rollbackIds = popLastStagedRollbackIds();
-        for (int i = 0; i < rollbackIds.size(); i++) {
-            WatchdogRollbackLogger.logRollbackStatusOnBoot(mContext,
-                    rollbackIds.keyAt(i), rollbackIds.valueAt(i),
-                    rollbackManager.getRecentlyCommittedRollbacks());
-        }
-    }
-
-    @AnyThread
-    private RollbackInfo getAvailableRollback(VersionedPackage failedPackage) {
-        RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
-        for (RollbackInfo rollback : rollbackManager.getAvailableRollbacks()) {
-            for (PackageRollbackInfo packageRollback : rollback.getPackages()) {
-                if (packageRollback.getVersionRolledBackFrom().equals(failedPackage)) {
-                    return rollback;
-                }
-                // TODO(b/147666157): Extract version number of apk-in-apex so that we don't have
-                //  to rely on complicated reasoning as below
-
-                // Due to b/147666157, for apk in apex, we do not know the version we are rolling
-                // back from. But if a package X is embedded in apex A exclusively (not embedded in
-                // any other apex), which is not guaranteed, then it is sufficient to check only
-                // package names here, as the version of failedPackage and the PackageRollbackInfo
-                // can't be different. If failedPackage has a higher version, then it must have
-                // been updated somehow. There are two ways: it was updated by an update of apex A
-                // or updated directly as apk. In both cases, this rollback would have gotten
-                // expired when onPackageReplaced() was called. Since the rollback exists, it has
-                // same version as failedPackage.
-                if (packageRollback.isApkInApex()
-                        && packageRollback.getVersionRolledBackFrom().getPackageName()
-                        .equals(failedPackage.getPackageName())) {
-                    return rollback;
-                }
-            }
-        }
-        return null;
-    }
-
-    @AnyThread
-    private RollbackInfo getRollbackForPackage(@Nullable VersionedPackage failedPackage,
-            List<RollbackInfo> availableRollbacks) {
-        if (failedPackage == null) {
-            return null;
-        }
-
-        for (RollbackInfo rollback : availableRollbacks) {
-            for (PackageRollbackInfo packageRollback : rollback.getPackages()) {
-                if (packageRollback.getVersionRolledBackFrom().equals(failedPackage)) {
-                    return rollback;
-                }
-                // TODO(b/147666157): Extract version number of apk-in-apex so that we don't have
-                //  to rely on complicated reasoning as below
-
-                // Due to b/147666157, for apk in apex, we do not know the version we are rolling
-                // back from. But if a package X is embedded in apex A exclusively (not embedded in
-                // any other apex), which is not guaranteed, then it is sufficient to check only
-                // package names here, as the version of failedPackage and the PackageRollbackInfo
-                // can't be different. If failedPackage has a higher version, then it must have
-                // been updated somehow. There are two ways: it was updated by an update of apex A
-                // or updated directly as apk. In both cases, this rollback would have gotten
-                // expired when onPackageReplaced() was called. Since the rollback exists, it has
-                // same version as failedPackage.
-                if (packageRollback.isApkInApex()
-                        && packageRollback.getVersionRolledBackFrom().getPackageName()
-                        .equals(failedPackage.getPackageName())) {
-                    return rollback;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns {@code true} if staged session associated with {@code rollbackId} was marked
-     * as handled, {@code false} if already handled.
-     */
-    @WorkerThread
-    private boolean markStagedSessionHandled(int rollbackId) {
-        assertInWorkerThread();
-        return mPendingStagedRollbackIds.remove(rollbackId);
-    }
-
-    /**
-     * Returns {@code true} if all pending staged rollback sessions were marked as handled,
-     * {@code false} if there is any left.
-     */
-    @WorkerThread
-    private boolean isPendingStagedSessionsEmpty() {
-        assertInWorkerThread();
-        return mPendingStagedRollbackIds.isEmpty();
-    }
-
-    private static boolean readBoolean(File file) {
-        try (FileInputStream fis = new FileInputStream(file)) {
-            return fis.read() == 1;
-        } catch (IOException ignore) {
-            return false;
-        }
-    }
-
-    private static void writeBoolean(File file, boolean value) {
-        try (FileOutputStream fos = new FileOutputStream(file)) {
-            fos.write(value ? 1 : 0);
-            fos.flush();
-            FileUtils.sync(fos);
-        } catch (IOException ignore) {
-        }
-    }
-
-    @WorkerThread
-    private void saveStagedRollbackId(int stagedRollbackId, @Nullable VersionedPackage logPackage) {
-        assertInWorkerThread();
-        writeStagedRollbackId(mLastStagedRollbackIdsFile, stagedRollbackId, logPackage);
-    }
-
-    static void writeStagedRollbackId(File file, int stagedRollbackId,
-            @Nullable VersionedPackage logPackage) {
-        try {
-            FileOutputStream fos = new FileOutputStream(file, true);
-            PrintWriter pw = new PrintWriter(fos);
-            String logPackageName = logPackage != null ? logPackage.getPackageName() : "";
-            pw.append(String.valueOf(stagedRollbackId)).append(",").append(logPackageName);
-            pw.println();
-            pw.flush();
-            FileUtils.sync(fos);
-            pw.close();
-        } catch (IOException e) {
-            Slog.e(TAG, "Failed to save last staged rollback id", e);
-            file.delete();
-        }
-    }
-
-    @WorkerThread
-    private SparseArray<String> popLastStagedRollbackIds() {
-        assertInWorkerThread();
-        try {
-            return readStagedRollbackIds(mLastStagedRollbackIdsFile);
-        } finally {
-            mLastStagedRollbackIdsFile.delete();
-        }
-    }
-
-    static SparseArray<String> readStagedRollbackIds(File file) {
-        SparseArray<String> result = new SparseArray<>();
-        try {
-            String line;
-            BufferedReader reader = new BufferedReader(new FileReader(file));
-            while ((line = reader.readLine()) != null) {
-                // Each line is of the format: "id,logging_package"
-                String[] values = line.trim().split(",");
-                String rollbackId = values[0];
-                String logPackageName = "";
-                if (values.length > 1) {
-                    logPackageName = values[1];
-                }
-                result.put(Integer.parseInt(rollbackId), logPackageName);
-            }
-        } catch (Exception ignore) {
-            return new SparseArray<>();
-        }
-        return result;
-    }
-
-
-    /**
-     * Returns true if the package name is the name of a module.
-     */
-    @AnyThread
-    private boolean isModule(String packageName) {
-        // Check if the package is listed among the system modules or is an
-        // APK inside an updatable APEX.
-        try {
-            PackageManager pm = mContext.getPackageManager();
-            final PackageInfo pkg = pm.getPackageInfo(packageName, 0 /* flags */);
-            String apexPackageName = pkg.getApexPackageName();
-            if (apexPackageName != null) {
-                packageName = apexPackageName;
-            }
-
-            return pm.getModuleInfo(packageName, 0 /* flags */) != null;
-        } catch (PackageManager.NameNotFoundException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Rolls back the session that owns {@code failedPackage}
-     *
-     * @param rollback {@code rollbackInfo} of the {@code failedPackage}
-     * @param failedPackage the package that needs to be rolled back
-     */
-    @WorkerThread
-    private void rollbackPackage(RollbackInfo rollback, VersionedPackage failedPackage,
-            @FailureReasons int rollbackReason) {
-        assertInWorkerThread();
-        String failedPackageName = (failedPackage == null ? null : failedPackage.getPackageName());
-
-        Slog.i(TAG, "Rolling back package. RollbackId: " + rollback.getRollbackId()
-                + " failedPackage: " + failedPackageName
-                + " rollbackReason: " + rollbackReason);
-        logCrashRecoveryEvent(Log.DEBUG, String.format("Rolling back %s. Reason: %s",
-                failedPackageName, rollbackReason));
-        final RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
-        int reasonToLog = WatchdogRollbackLogger.mapFailureReasonToMetric(rollbackReason);
-        final String failedPackageToLog;
-        if (rollbackReason == PackageWatchdog.FAILURE_REASON_NATIVE_CRASH) {
-            failedPackageToLog = SystemProperties.get(
-                    "sys.init.updatable_crashing_process_name", "");
-        } else {
-            failedPackageToLog = failedPackage.getPackageName();
-        }
-        VersionedPackage logPackageTemp = null;
-        if (isModule(failedPackage.getPackageName())) {
-            logPackageTemp = WatchdogRollbackLogger.getLogPackage(mContext, failedPackage);
-        }
-
-        final VersionedPackage logPackage = logPackageTemp;
-        WatchdogRollbackLogger.logEvent(logPackage,
-                CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE,
-                reasonToLog, failedPackageToLog);
-
-        Consumer<Intent> onResult = result -> {
-            assertInWorkerThread();
-            int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
-                    RollbackManager.STATUS_FAILURE);
-            if (status == RollbackManager.STATUS_SUCCESS) {
-                if (rollback.isStaged()) {
-                    int rollbackId = rollback.getRollbackId();
-                    saveStagedRollbackId(rollbackId, logPackage);
-                    WatchdogRollbackLogger.logEvent(logPackage,
-                            CrashRecoveryStatsLog
-                            .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED,
-                            reasonToLog, failedPackageToLog);
-
-                } else {
-                    WatchdogRollbackLogger.logEvent(logPackage,
-                            CrashRecoveryStatsLog
-                                    .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
-                            reasonToLog, failedPackageToLog);
-                }
-            } else {
-                WatchdogRollbackLogger.logEvent(logPackage,
-                        CrashRecoveryStatsLog
-                                .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
-                        reasonToLog, failedPackageToLog);
-            }
-            if (rollback.isStaged()) {
-                markStagedSessionHandled(rollback.getRollbackId());
-                // Wait for all pending staged sessions to get handled before rebooting.
-                if (isPendingStagedSessionsEmpty()) {
-                    CrashRecoveryProperties.attemptingReboot(true);
-                    mContext.getSystemService(PowerManager.class).reboot("Rollback staged install");
-                }
-            }
-        };
-
-        // Define a BroadcastReceiver to handle the result
-        BroadcastReceiver rollbackReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent result) {
-                mHandler.post(() -> onResult.accept(result));
-            }
-        };
-
-        String intentActionName = CLASS_NAME + rollback.getRollbackId();
-        // Register the BroadcastReceiver
-        mContext.registerReceiver(rollbackReceiver,
-                new IntentFilter(intentActionName),
-                Context.RECEIVER_NOT_EXPORTED);
-
-        Intent intentReceiver = new Intent(intentActionName);
-        intentReceiver.putExtra("rollbackId", rollback.getRollbackId());
-        intentReceiver.setPackage(mContext.getPackageName());
-        intentReceiver.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-
-        PendingIntent rollbackPendingIntent = PendingIntent.getBroadcast(mContext,
-                rollback.getRollbackId(),
-                intentReceiver,
-                PendingIntent.FLAG_MUTABLE);
-
-        rollbackManager.commitRollback(rollback.getRollbackId(),
-                Collections.singletonList(failedPackage),
-                rollbackPendingIntent.getIntentSender());
-    }
-
-    /**
-     * Two-phase rollback:
-     * 1. roll back rebootless apexes first
-     * 2. roll back all remaining rollbacks if native crash doesn't stop after (1) is done
-     *
-     * This approach gives us a better chance to correctly attribute native crash to rebootless
-     * apex update without rolling back Mainline updates which might contains critical security
-     * fixes.
-     */
-    @WorkerThread
-    private boolean useTwoPhaseRollback(List<RollbackInfo> rollbacks) {
-        assertInWorkerThread();
-        if (!mTwoPhaseRollbackEnabled) {
-            return false;
-        }
-
-        Slog.i(TAG, "Rolling back all rebootless APEX rollbacks");
-        boolean found = false;
-        for (RollbackInfo rollback : rollbacks) {
-            if (isRebootlessApex(rollback)) {
-                VersionedPackage firstRollback =
-                        rollback.getPackages().get(0).getVersionRolledBackFrom();
-                rollbackPackage(rollback, firstRollback,
-                        PackageWatchdog.FAILURE_REASON_NATIVE_CRASH);
-                found = true;
-            }
-        }
-        return found;
-    }
-
-    /**
-     * Rollback the package that has minimum rollback impact level.
-     * @param availableRollbacks all available rollbacks
-     * @param rollbackReason reason to rollback
-     */
-    private void triggerLeastImpactLevelRollback(List<RollbackInfo> availableRollbacks,
-            @FailureReasons int rollbackReason) {
-        int minRollbackImpactLevel = getMinRollbackImpactLevel(availableRollbacks);
-
-        if (minRollbackImpactLevel == PackageManager.ROLLBACK_USER_IMPACT_LOW) {
-            // Apply all available low impact rollbacks.
-            mHandler.post(() -> rollbackAllLowImpact(availableRollbacks, rollbackReason));
-        } else if (minRollbackImpactLevel == PackageManager.ROLLBACK_USER_IMPACT_HIGH) {
-            // Check disable_high_impact_rollback device config before performing rollback
-            if (SystemProperties.getBoolean(PROP_DISABLE_HIGH_IMPACT_ROLLBACK_FLAG, false)) {
-                return;
-            }
-            // Rollback one package at a time. If that doesn't resolve the issue, rollback
-            // next with same impact level.
-            mHandler.post(() -> rollbackHighImpact(availableRollbacks, rollbackReason));
-        }
-    }
-
-    /**
-     * sort the available high impact rollbacks by first package name to have a deterministic order.
-     * Apply the first available rollback.
-     * @param availableRollbacks all available rollbacks
-     * @param rollbackReason reason to rollback
-     */
-    @WorkerThread
-    private void rollbackHighImpact(List<RollbackInfo> availableRollbacks,
-            @FailureReasons int rollbackReason) {
-        assertInWorkerThread();
-        List<RollbackInfo> highImpactRollbacks =
-                getRollbacksAvailableForImpactLevel(
-                        availableRollbacks, PackageManager.ROLLBACK_USER_IMPACT_HIGH);
-
-        // sort rollbacks based on package name of the first package. This is to have a
-        // deterministic order of rollbacks.
-        List<RollbackInfo> sortedHighImpactRollbacks = highImpactRollbacks.stream().sorted(
-                Comparator.comparing(a -> a.getPackages().get(0).getPackageName())).toList();
-        VersionedPackage firstRollback =
-                sortedHighImpactRollbacks
-                        .get(0)
-                        .getPackages()
-                        .get(0)
-                        .getVersionRolledBackFrom();
-        Slog.i(TAG, "Rolling back high impact rollback for package: "
-                + firstRollback.getPackageName());
-        rollbackPackage(sortedHighImpactRollbacks.get(0), firstRollback, rollbackReason);
-    }
-
-    @WorkerThread
-    private void rollbackAll(@FailureReasons int rollbackReason) {
-        assertInWorkerThread();
-        RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
-        List<RollbackInfo> rollbacks = rollbackManager.getAvailableRollbacks();
-        if (useTwoPhaseRollback(rollbacks)) {
-            return;
-        }
-
-        Slog.i(TAG, "Rolling back all available rollbacks");
-        // Add all rollback ids to mPendingStagedRollbackIds, so that we do not reboot before all
-        // pending staged rollbacks are handled.
-        for (RollbackInfo rollback : rollbacks) {
-            if (rollback.isStaged()) {
-                mPendingStagedRollbackIds.add(rollback.getRollbackId());
-            }
-        }
-
-        for (RollbackInfo rollback : rollbacks) {
-            VersionedPackage firstRollback =
-                    rollback.getPackages().get(0).getVersionRolledBackFrom();
-            rollbackPackage(rollback, firstRollback, rollbackReason);
-        }
-    }
-
-    /**
-     * Rollback all available low impact rollbacks
-     * @param availableRollbacks all available rollbacks
-     * @param rollbackReason reason to rollbacks
-     */
-    @WorkerThread
-    private void rollbackAllLowImpact(
-            List<RollbackInfo> availableRollbacks, @FailureReasons int rollbackReason) {
-        assertInWorkerThread();
-
-        List<RollbackInfo> lowImpactRollbacks = getRollbacksAvailableForImpactLevel(
-                availableRollbacks,
-                PackageManager.ROLLBACK_USER_IMPACT_LOW);
-        if (useTwoPhaseRollback(lowImpactRollbacks)) {
-            return;
-        }
-
-        Slog.i(TAG, "Rolling back all available low impact rollbacks");
-        logCrashRecoveryEvent(Log.DEBUG, "Rolling back all available. Reason: " + rollbackReason);
-        // Add all rollback ids to mPendingStagedRollbackIds, so that we do not reboot before all
-        // pending staged rollbacks are handled.
-        for (RollbackInfo rollback : lowImpactRollbacks) {
-            if (rollback.isStaged()) {
-                mPendingStagedRollbackIds.add(rollback.getRollbackId());
-            }
-        }
-
-        for (RollbackInfo rollback : lowImpactRollbacks) {
-            VersionedPackage firstRollback =
-                    rollback.getPackages().get(0).getVersionRolledBackFrom();
-            rollbackPackage(rollback, firstRollback, rollbackReason);
-        }
-    }
-
-    private List<RollbackInfo> getRollbacksAvailableForImpactLevel(
-            List<RollbackInfo> availableRollbacks, int impactLevel) {
-        return availableRollbacks.stream()
-                .filter(rollbackInfo -> rollbackInfo.getRollbackImpactLevel() == impactLevel)
-                .toList();
-    }
-
-    private int getMinRollbackImpactLevel(List<RollbackInfo> availableRollbacks) {
-        return availableRollbacks.stream()
-                .mapToInt(RollbackInfo::getRollbackImpactLevel)
-                .min()
-                .orElse(-1);
-    }
-
-    private int getUserImpactBasedOnRollbackImpactLevel(List<RollbackInfo> availableRollbacks) {
-        int impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
-        int minImpact = getMinRollbackImpactLevel(availableRollbacks);
-        switch (minImpact) {
-            case PackageManager.ROLLBACK_USER_IMPACT_LOW:
-                impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_70;
-                break;
-            case PackageManager.ROLLBACK_USER_IMPACT_HIGH:
-                if (!SystemProperties.getBoolean(PROP_DISABLE_HIGH_IMPACT_ROLLBACK_FLAG, false)) {
-                    impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_90;
-                }
-                break;
-            default:
-                impact = PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
-        }
-        return impact;
-    }
-
-    @VisibleForTesting
-    Handler getHandler() {
-        return mHandler;
-    }
-}
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/rollback/WatchdogRollbackLogger.java b/packages/CrashRecovery/services/module/java/com/android/server/rollback/WatchdogRollbackLogger.java
deleted file mode 100644
index 9cfed02..0000000
--- a/packages/CrashRecovery/services/module/java/com/android/server/rollback/WatchdogRollbackLogger.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.rollback;
-
-import static com.android.server.crashrecovery.CrashRecoveryUtils.logCrashRecoveryEvent;
-import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_CRASH;
-import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_NOT_RESPONDING;
-import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_BOOT_LOOPING;
-import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_EXPLICIT_HEALTH_CHECK;
-import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH;
-import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH_DURING_BOOT;
-import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN;
-import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED;
-import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE;
-import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE;
-import static com.android.server.crashrecovery.proto.CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInstaller;
-import android.content.pm.PackageManager;
-import android.content.pm.VersionedPackage;
-import android.content.rollback.PackageRollbackInfo;
-import android.content.rollback.RollbackInfo;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.PackageWatchdog;
-import com.android.server.crashrecovery.proto.CrashRecoveryStatsLog;
-
-import java.util.List;
-
-/**
- * This class handles the logic for logging Watchdog-triggered rollback events.
- * @hide
- */
-public final class WatchdogRollbackLogger {
-    private static final String TAG = "WatchdogRollbackLogger";
-
-    private static final String LOGGING_PARENT_KEY = "android.content.pm.LOGGING_PARENT";
-
-    private WatchdogRollbackLogger() {
-    }
-
-    @Nullable
-    private static String getLoggingParentName(Context context, @NonNull String packageName) {
-        PackageManager packageManager = context.getPackageManager();
-        try {
-            int flags = PackageManager.MATCH_APEX | PackageManager.GET_META_DATA;
-            ApplicationInfo ai = packageManager.getPackageInfo(packageName, flags).applicationInfo;
-            if (ai.metaData == null) {
-                return null;
-            }
-            return ai.metaData.getString(LOGGING_PARENT_KEY);
-        } catch (Exception e) {
-            Slog.w(TAG, "Unable to discover logging parent package: " + packageName, e);
-            return null;
-        }
-    }
-
-    /**
-     * Returns the logging parent of a given package if it exists, {@code null} otherwise.
-     *
-     * The logging parent is defined by the {@code android.content.pm.LOGGING_PARENT} field in the
-     * metadata of a package's AndroidManifest.xml.
-     */
-    @VisibleForTesting
-    @Nullable
-    static VersionedPackage getLogPackage(Context context,
-            @NonNull VersionedPackage failingPackage) {
-        String logPackageName;
-        VersionedPackage loggingParent;
-        logPackageName = getLoggingParentName(context, failingPackage.getPackageName());
-        if (logPackageName == null) {
-            return null;
-        }
-        try {
-            loggingParent = new VersionedPackage(logPackageName, context.getPackageManager()
-                    .getPackageInfo(logPackageName, 0 /* flags */).getLongVersionCode());
-        } catch (PackageManager.NameNotFoundException e) {
-            return null;
-        }
-        return loggingParent;
-    }
-
-    static void logRollbackStatusOnBoot(Context context, int rollbackId, String logPackageName,
-            List<RollbackInfo> recentlyCommittedRollbacks) {
-        PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
-
-        RollbackInfo rollback = null;
-        for (RollbackInfo info : recentlyCommittedRollbacks) {
-            if (rollbackId == info.getRollbackId()) {
-                rollback = info;
-                break;
-            }
-        }
-
-        if (rollback == null) {
-            Slog.e(TAG, "rollback info not found for last staged rollback: " + rollbackId);
-            return;
-        }
-
-        // Use the version of the logging parent that was installed before
-        // we rolled back for logging purposes.
-        VersionedPackage oldLoggingPackage = null;
-        if (!TextUtils.isEmpty(logPackageName)) {
-            for (PackageRollbackInfo packageRollback : rollback.getPackages()) {
-                if (logPackageName.equals(packageRollback.getPackageName())) {
-                    oldLoggingPackage = packageRollback.getVersionRolledBackFrom();
-                    break;
-                }
-            }
-        }
-
-        int sessionId = rollback.getCommittedSessionId();
-        PackageInstaller.SessionInfo sessionInfo = packageInstaller.getSessionInfo(sessionId);
-        if (sessionInfo == null) {
-            Slog.e(TAG, "On boot completed, could not load session id " + sessionId);
-            return;
-        }
-
-        if (sessionInfo.isStagedSessionApplied()) {
-            logEvent(oldLoggingPackage,
-                    WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
-                    WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN, "");
-        } else if (sessionInfo.isStagedSessionFailed()) {
-            logEvent(oldLoggingPackage,
-                    WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
-                    WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN, "");
-        }
-    }
-
-    /**
-     * Log a Watchdog rollback event to statsd.
-     *
-     * @param logPackage the package to associate the rollback with.
-     * @param type the state of the rollback.
-     * @param rollbackReason the reason Watchdog triggered a rollback, if known.
-     * @param failingPackageName the failing package or process which triggered the rollback.
-     */
-    public static void logEvent(@Nullable VersionedPackage logPackage, int type,
-            int rollbackReason, @NonNull String failingPackageName) {
-        String logMsg = "Watchdog event occurred with type: " + rollbackTypeToString(type)
-                + " logPackage: " + logPackage
-                + " rollbackReason: " + rollbackReasonToString(rollbackReason)
-                + " failedPackageName: " + failingPackageName;
-        Slog.i(TAG, logMsg);
-        if (logPackage != null) {
-            CrashRecoveryStatsLog.write(
-                    CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED,
-                    type,
-                    logPackage.getPackageName(),
-                    logPackage.getVersionCode(),
-                    rollbackReason,
-                    failingPackageName,
-                    new byte[]{});
-        } else {
-            // In the case that the log package is null, still log an empty string as an
-            // indication that retrieving the logging parent failed.
-            CrashRecoveryStatsLog.write(
-                    CrashRecoveryStatsLog.WATCHDOG_ROLLBACK_OCCURRED,
-                    type,
-                    "",
-                    0,
-                    rollbackReason,
-                    failingPackageName,
-                    new byte[]{});
-        }
-
-        logTestProperties(logMsg);
-    }
-
-    /**
-     * Writes properties which will be used by rollback tests to check if particular rollback
-     * events have occurred.
-     */
-    private static void logTestProperties(String logMsg) {
-        // This property should be on only during the tests
-        if (!SystemProperties.getBoolean("persist.sys.rollbacktest.enabled", false)) {
-            return;
-        }
-        logCrashRecoveryEvent(Log.DEBUG, logMsg);
-    }
-
-    @VisibleForTesting
-    static int mapFailureReasonToMetric(@PackageWatchdog.FailureReasons int failureReason) {
-        switch (failureReason) {
-            case PackageWatchdog.FAILURE_REASON_NATIVE_CRASH:
-                return WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH;
-            case PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK:
-                return WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_EXPLICIT_HEALTH_CHECK;
-            case PackageWatchdog.FAILURE_REASON_APP_CRASH:
-                return WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_CRASH;
-            case PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING:
-                return WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_NOT_RESPONDING;
-            case PackageWatchdog.FAILURE_REASON_BOOT_LOOP:
-                return WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_BOOT_LOOPING;
-            default:
-                return WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN;
-        }
-    }
-
-    private static String rollbackTypeToString(int type) {
-        switch (type) {
-            case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE:
-                return "ROLLBACK_INITIATE";
-            case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS:
-                return "ROLLBACK_SUCCESS";
-            case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE:
-                return "ROLLBACK_FAILURE";
-            case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED:
-                return "ROLLBACK_BOOT_TRIGGERED";
-            default:
-                return "UNKNOWN";
-        }
-    }
-
-    private static String rollbackReasonToString(int reason) {
-        switch (reason) {
-            case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH:
-                return "REASON_NATIVE_CRASH";
-            case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_EXPLICIT_HEALTH_CHECK:
-                return "REASON_EXPLICIT_HEALTH_CHECK";
-            case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_CRASH:
-                return "REASON_APP_CRASH";
-            case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_NOT_RESPONDING:
-                return "REASON_APP_NOT_RESPONDING";
-            case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH_DURING_BOOT:
-                return "REASON_NATIVE_CRASH_DURING_BOOT";
-            case WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_BOOT_LOOPING:
-                return "REASON_BOOT_LOOP";
-            default:
-                return "UNKNOWN";
-        }
-    }
-}
diff --git a/packages/CrashRecovery/services/module/java/com/android/util/ArrayUtils.java b/packages/CrashRecovery/services/module/java/com/android/util/ArrayUtils.java
deleted file mode 100644
index 29ff7cc..0000000
--- a/packages/CrashRecovery/services/module/java/com/android/util/ArrayUtils.java
+++ /dev/null
@@ -1,42 +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 android.util;
-
-import android.annotation.Nullable;
-
-/**
- * Copied over from frameworks/base/core/java/com/android/internal/util/ArrayUtils.java
- *
- * @hide
- */
-public class ArrayUtils {
-    private ArrayUtils() { /* cannot be instantiated */ }
-
-    /**
-     * Checks if given array is null or has zero elements.
-     */
-    public static boolean isEmpty(@Nullable int[] array) {
-        return array == null || array.length == 0;
-    }
-
-    /**
-     * True if the byte array is null or has length 0.
-     */
-    public static boolean isEmpty(@Nullable byte[] array) {
-        return array == null || array.length == 0;
-    }
-}
diff --git a/packages/CrashRecovery/services/module/java/com/android/util/FileUtils.java b/packages/CrashRecovery/services/module/java/com/android/util/FileUtils.java
deleted file mode 100644
index d60a9b9..0000000
--- a/packages/CrashRecovery/services/module/java/com/android/util/FileUtils.java
+++ /dev/null
@@ -1,117 +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 android.util;
-
-import android.annotation.Nullable;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Bits and pieces copied from hidden API of android.os.FileUtils.
- *
- * @hide
- */
-public class FileUtils {
-    /**
-     * Read a text file into a String, optionally limiting the length.
-     *
-     * @param file     to read (will not seek, so things like /proc files are OK)
-     * @param max      length (positive for head, negative of tail, 0 for no limit)
-     * @param ellipsis to add of the file was truncated (can be null)
-     * @return the contents of the file, possibly truncated
-     * @throws IOException if something goes wrong reading the file
-     * @hide
-     */
-    public static @Nullable String readTextFile(@Nullable File file, @Nullable int max,
-            @Nullable String ellipsis) throws IOException {
-        InputStream input = new FileInputStream(file);
-        // wrapping a BufferedInputStream around it because when reading /proc with unbuffered
-        // input stream, bytes read not equal to buffer size is not necessarily the correct
-        // indication for EOF; but it is true for BufferedInputStream due to its implementation.
-        BufferedInputStream bis = new BufferedInputStream(input);
-        try {
-            long size = file.length();
-            if (max > 0 || (size > 0 && max == 0)) {  // "head" mode: read the first N bytes
-                if (size > 0 && (max == 0 || size < max)) max = (int) size;
-                byte[] data = new byte[max + 1];
-                int length = bis.read(data);
-                if (length <= 0) return "";
-                if (length <= max) return new String(data, 0, length);
-                if (ellipsis == null) return new String(data, 0, max);
-                return new String(data, 0, max) + ellipsis;
-            } else if (max < 0) {  // "tail" mode: keep the last N
-                int len;
-                boolean rolled = false;
-                byte[] last = null;
-                byte[] data = null;
-                do {
-                    if (last != null) rolled = true;
-                    byte[] tmp = last;
-                    last = data;
-                    data = tmp;
-                    if (data == null) data = new byte[-max];
-                    len = bis.read(data);
-                } while (len == data.length);
-
-                if (last == null && len <= 0) return "";
-                if (last == null) return new String(data, 0, len);
-                if (len > 0) {
-                    rolled = true;
-                    System.arraycopy(last, len, last, 0, last.length - len);
-                    System.arraycopy(data, 0, last, last.length - len, len);
-                }
-                if (ellipsis == null || !rolled) return new String(last);
-                return ellipsis + new String(last);
-            } else {  // "cat" mode: size unknown, read it all in streaming fashion
-                ByteArrayOutputStream contents = new ByteArrayOutputStream();
-                int len;
-                byte[] data = new byte[1024];
-                do {
-                    len = bis.read(data);
-                    if (len > 0) contents.write(data, 0, len);
-                } while (len == data.length);
-                return contents.toString();
-            }
-        } finally {
-            bis.close();
-            input.close();
-        }
-    }
-
-    /**
-     * Perform an fsync on the given FileOutputStream. The stream at this
-     * point must be flushed but not yet closed.
-     *
-     * @hide
-     */
-    public static boolean sync(FileOutputStream stream) {
-        try {
-            if (stream != null) {
-                stream.getFD().sync();
-            }
-            return true;
-        } catch (IOException e) {
-        }
-        return false;
-    }
-}
diff --git a/packages/CrashRecovery/services/module/java/com/android/util/LongArrayQueue.java b/packages/CrashRecovery/services/module/java/com/android/util/LongArrayQueue.java
deleted file mode 100644
index 9a24ada..0000000
--- a/packages/CrashRecovery/services/module/java/com/android/util/LongArrayQueue.java
+++ /dev/null
@@ -1,188 +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 android.util;
-
-import libcore.util.EmptyArray;
-
-import java.util.NoSuchElementException;
-
-/**
- * Copied from frameworks/base/core/java/android/util/LongArrayQueue.java
- *
- * @hide
- */
-public class LongArrayQueue {
-
-    private long[] mValues;
-    private int mSize;
-    private int mHead;
-    private int mTail;
-
-    private long[] newUnpaddedLongArray(int num) {
-        return new long[num];
-    }
-    /**
-     * Initializes a queue with the given starting capacity.
-     *
-     * @param initialCapacity the capacity.
-     */
-    public LongArrayQueue(int initialCapacity) {
-        if (initialCapacity == 0) {
-            mValues = EmptyArray.LONG;
-        } else {
-            mValues = newUnpaddedLongArray(initialCapacity);
-        }
-        mSize = 0;
-        mHead = mTail = 0;
-    }
-
-    /**
-     * Initializes a queue with default starting capacity.
-     */
-    public LongArrayQueue() {
-        this(16);
-    }
-
-    /** @hide */
-    public static int growSize(int currentSize) {
-        return currentSize <= 4 ? 8 : currentSize * 2;
-    }
-
-    private void grow() {
-        if (mSize < mValues.length) {
-            throw new IllegalStateException("Queue not full yet!");
-        }
-        final int newSize = growSize(mSize);
-        final long[] newArray = newUnpaddedLongArray(newSize);
-        final int r = mValues.length - mHead; // Number of elements on and to the right of head.
-        System.arraycopy(mValues, mHead, newArray, 0, r);
-        System.arraycopy(mValues, 0, newArray, r, mHead);
-        mValues = newArray;
-        mHead = 0;
-        mTail = mSize;
-    }
-
-    /**
-     * Returns the number of elements in the queue.
-     */
-    public int size() {
-        return mSize;
-    }
-
-    /**
-     * Removes all elements from this queue.
-     */
-    public void clear() {
-        mSize = 0;
-        mHead = mTail = 0;
-    }
-
-    /**
-     * Adds a value to the tail of the queue.
-     *
-     * @param value the value to be added.
-     */
-    public void addLast(long value) {
-        if (mSize == mValues.length) {
-            grow();
-        }
-        mValues[mTail] = value;
-        mTail = (mTail + 1) % mValues.length;
-        mSize++;
-    }
-
-    /**
-     * Removes an element from the head of the queue.
-     *
-     * @return the element at the head of the queue.
-     * @throws NoSuchElementException if the queue is empty.
-     */
-    public long removeFirst() {
-        if (mSize == 0) {
-            throw new NoSuchElementException("Queue is empty!");
-        }
-        final long ret = mValues[mHead];
-        mHead = (mHead + 1) % mValues.length;
-        mSize--;
-        return ret;
-    }
-
-    /**
-     * Returns the element at the given position from the head of the queue, where 0 represents the
-     * head of the queue.
-     *
-     * @param position the position from the head of the queue.
-     * @return the element found at the given position.
-     * @throws IndexOutOfBoundsException if {@code position} < {@code 0} or
-     *                                   {@code position} >= {@link #size()}
-     */
-    public long get(int position) {
-        if (position < 0 || position >= mSize) {
-            throw new IndexOutOfBoundsException("Index " + position
-                + " not valid for a queue of size " + mSize);
-        }
-        final int index = (mHead + position) % mValues.length;
-        return mValues[index];
-    }
-
-    /**
-     * Returns the element at the head of the queue, without removing it.
-     *
-     * @return the element at the head of the queue.
-     * @throws NoSuchElementException if the queue is empty
-     */
-    public long peekFirst() {
-        if (mSize == 0) {
-            throw new NoSuchElementException("Queue is empty!");
-        }
-        return mValues[mHead];
-    }
-
-    /**
-     * Returns the element at the tail of the queue.
-     *
-     * @return the element at the tail of the queue.
-     * @throws NoSuchElementException if the queue is empty.
-     */
-    public long peekLast() {
-        if (mSize == 0) {
-            throw new NoSuchElementException("Queue is empty!");
-        }
-        final int index = (mTail == 0) ? mValues.length - 1 : mTail - 1;
-        return mValues[index];
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String toString() {
-        if (mSize <= 0) {
-            return "{}";
-        }
-
-        final StringBuilder buffer = new StringBuilder(mSize * 64);
-        buffer.append('{');
-        buffer.append(get(0));
-        for (int i = 1; i < mSize; i++) {
-            buffer.append(", ");
-            buffer.append(get(i));
-        }
-        buffer.append('}');
-        return buffer.toString();
-    }
-}
diff --git a/packages/CrashRecovery/services/module/java/com/android/util/XmlUtils.java b/packages/CrashRecovery/services/module/java/com/android/util/XmlUtils.java
deleted file mode 100644
index 488b531..0000000
--- a/packages/CrashRecovery/services/module/java/com/android/util/XmlUtils.java
+++ /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 android.util;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-
-/**
- *  Bits and pieces copied from hidden API of
- *  frameworks/base/core/java/com/android/internal/util/XmlUtils.java
- *
- * @hide
- */
-public class XmlUtils {
-
-    /** @hide */
-    public static final void beginDocument(XmlPullParser parser, String firstElementName)
-            throws XmlPullParserException, IOException {
-        int type;
-        while ((type = parser.next()) != parser.START_TAG
-            && type != parser.END_DOCUMENT) {
-            // Do nothing
-        }
-
-        if (type != parser.START_TAG) {
-            throw new XmlPullParserException("No start tag found");
-        }
-
-        if (!parser.getName().equals(firstElementName)) {
-            throw new XmlPullParserException("Unexpected start tag: found " + parser.getName()
-                + ", expected " + firstElementName);
-        }
-    }
-
-    /** @hide */
-    public static boolean nextElementWithin(XmlPullParser parser, int outerDepth)
-            throws IOException, XmlPullParserException {
-        for (;;) {
-            int type = parser.next();
-            if (type == XmlPullParser.END_DOCUMENT
-                    || (type == XmlPullParser.END_TAG && parser.getDepth() == outerDepth)) {
-                return false;
-            }
-            if (type == XmlPullParser.START_TAG
-                    && parser.getDepth() == outerDepth + 1) {
-                return true;
-            }
-        }
-    }
-}
diff --git a/packages/PrintSpooler/res/values-es-rUS/strings.xml b/packages/PrintSpooler/res/values-es-rUS/strings.xml
index 9f88f14..bfe5bb3 100644
--- a/packages/PrintSpooler/res/values-es-rUS/strings.xml
+++ b/packages/PrintSpooler/res/values-es-rUS/strings.xml
@@ -32,7 +32,7 @@
     <string name="template_page_range" msgid="428638530038286328">"Rango de <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"Ej.: 1-5, 8, 11-13"</string>
     <string name="print_preview" msgid="8010217796057763343">"Vista previa de impresión"</string>
-    <string name="install_for_print_preview" msgid="6366303997385509332">"Instalar visualizador de PDF para vista previa"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Instalar lector de PDF para obtener vista previa"</string>
     <string name="printing_app_crashed" msgid="854477616686566398">"La aplicación de impresión falló"</string>
     <string name="generating_print_job" msgid="3119608742651698916">"Generando trabajo de impresión"</string>
     <string name="save_as_pdf" msgid="5718454119847596853">"Guardar como PDF"</string>
diff --git a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreferenceGroup.kt b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreferenceGroup.kt
index 7545563..8dd169b1 100644
--- a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreferenceGroup.kt
+++ b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreferenceGroup.kt
@@ -23,7 +23,6 @@
 import androidx.preference.Preference
 import androidx.preference.PreferenceGroup
 import androidx.preference.PreferenceViewHolder
-
 import com.android.settingslib.widget.preference.banner.R
 
 /**
@@ -68,6 +67,11 @@
         }
 
         childPreferences.add(preference)
+        expandPreference?.let {
+            it.count = childPreferences.size - 1
+        }
+        updateExpandCollapsePreference()
+        updateChildrenVisibility()
         return super.addPreference(preference)
     }
 
@@ -76,18 +80,40 @@
             return false
         }
         childPreferences.remove(preference)
+        expandPreference?.let {
+            it.count = childPreferences.size - 1
+        }
+        updateChildrenVisibility()
+        updateExpandCollapsePreference()
         return super.removePreference(preference)
     }
 
+    override fun removePreferenceRecursively(key: CharSequence): Boolean {
+        val preference = findPreference<Preference>(key) ?: return false
+
+        if (preference !is BannerMessagePreference) {
+            return false
+        }
+
+        childPreferences.remove(preference)
+        expandPreference?.let {
+            it.count = childPreferences.size - 1
+        }
+        updateChildrenVisibility()
+        updateExpandCollapsePreference()
+        return super.removePreferenceRecursively(key)
+    }
+
     override fun onBindViewHolder(holder: PreferenceViewHolder) {
         super.onBindViewHolder(holder)
-        if (childPreferences.size >= MAX_CHILDREN - 1) {
+        if (childPreferences.size >= 2) {
             if (expandPreference == null) {
                 expandPreference = NumberButtonPreference(context).apply {
                     key = expandKey
                     title = expandTitle
                     count = childPreferences.size - 1
                     btnContentDescription = expandContentDescription
+                    order = EXPAND_ORDER
                     clickListener = View.OnClickListener {
                         toggleExpansion()
                     }
@@ -100,6 +126,7 @@
                     key = collapseKey
                     title = collapseTitle
                     icon = collapseIcon
+                    order = COLLAPSE_ORDER
                     setOnClickListener {
                         toggleExpansion()
                     }
@@ -112,14 +139,20 @@
     }
 
     private fun updateExpandCollapsePreference() {
-        expandPreference?.isVisible = !isExpanded
-        collapsePreference?.isVisible = isExpanded
+        expandPreference?.isVisible = !isExpanded && childPreferences.size > 1
+        collapsePreference?.isVisible = isExpanded && childPreferences.size > 1
     }
 
     private fun updateChildrenVisibility() {
-        for (i in 1 until childPreferences.size) {
+        for (i in 0 until childPreferences.size) {
             val child = childPreferences[i]
-            child.isVisible = isExpanded
+            if (i == 0) {
+                // Make this explicitly visible when e.g. the first BannerMessagePreference
+                // in the group is dismissed
+                child.isVisible = true
+            } else {
+                child.isVisible = isExpanded
+            }
         }
     }
 
@@ -145,5 +178,9 @@
 
     companion object {
         private const val MAX_CHILDREN = 3
+        // Arbitrary large order numbers for the two preferences
+        // needed to make sure any Banners are added above them
+        private const val EXPAND_ORDER = 99
+        private const val COLLAPSE_ORDER = 100
     }
 }
\ No newline at end of file
diff --git a/packages/SettingsLib/Graph/graph.proto b/packages/SettingsLib/Graph/graph.proto
index a834947..ec287c1 100644
--- a/packages/SettingsLib/Graph/graph.proto
+++ b/packages/SettingsLib/Graph/graph.proto
@@ -93,6 +93,8 @@
   optional PermissionsProto read_permissions = 17;
   // The required permissions to write preference value.
   optional PermissionsProto write_permissions = 18;
+  // Tag constants associated with the preference.
+  repeated string tags = 19;
 
   // Target of an Intent
   message ActionTarget {
diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt
index 4290437..e511bf1 100644
--- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt
+++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt
@@ -412,6 +412,7 @@
         }
         metadata.intent(context)?.let { actionTarget = it.toActionTarget(context) }
         screenMetadata.getLaunchIntent(context, metadata)?.let { launchIntent = it.toProto() }
+        for (tag in metadata.tags(context)) addTags(tag)
     }
     persistent = metadata.isPersistent(context)
     if (persistent) {
diff --git a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
index 4b407c5..af40c64 100644
--- a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
+++ b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
@@ -73,6 +73,7 @@
     private boolean mLottieDynamicColor;
     private CharSequence mContentDescription;
     private boolean mIsTablet;
+    private boolean mIsAnimationPaused;
 
     /**
      * Interface to listen in on when {@link #onBindViewHolder(PreferenceViewHolder)} occurs.
@@ -143,6 +144,16 @@
                 (FrameLayout) holder.findViewById(R.id.middleground_layout);
         final LottieAnimationView illustrationView =
                 (LottieAnimationView) holder.findViewById(R.id.lottie_view);
+        // Pause and resume animation
+        illustrationFrame.setOnClickListener(v -> {
+            mIsAnimationPaused = !mIsAnimationPaused;
+            if (mIsAnimationPaused) {
+                illustrationView.pauseAnimation();
+            } else {
+                illustrationView.resumeAnimation();
+            }
+        });
+
         if (illustrationView != null && !TextUtils.isEmpty(mContentDescription)) {
             illustrationView.setContentDescription(mContentDescription);
             illustrationView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt
index 1e70a32..a8939ab 100644
--- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt
+++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt
@@ -89,11 +89,25 @@
     /**
      * Return the extras Bundle object associated with this preference.
      *
-     * It is used to provide more information for metadata.
+     * It is used to provide more *internal* information for metadata. External app is not expected
+     * to use this information as it could be changed in future. Consider [tags] for external usage.
      */
     fun extras(context: Context): Bundle? = null
 
     /**
+     * Returns the tags associated with this preference.
+     *
+     * Unlike [extras], tags are exposed for external usage. The returned tag list must be constants
+     * and **append only**. Do not edit/delete existing tag strings as it can cause backward
+     * compatibility issue.
+     *
+     * Use cases:
+     * - identify a specific preference
+     * - identify a group of preferences related to network settings
+     */
+    fun tags(context: Context): Array<String> = arrayOf()
+
+    /**
      * Returns if preference is indexable, default value is `true`.
      *
      * Return `false` only when the preference is always unavailable on current device. If it is
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedMode.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedMode.kt
index a140eb8..a848330 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedMode.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedMode.kt
@@ -35,6 +35,7 @@
 
 interface BlockedByEcm : RestrictedMode {
     fun showRestrictedSettingsDetails()
+    fun isBlockedByPhoneCall() = false
 }
 
 internal data class BlockedByAdminImpl(
@@ -72,8 +73,13 @@
     private val context: Context,
     private val intent: Intent,
 ) : BlockedByEcm {
+    private val reasonPhoneState = "phone_state"
 
     override fun showRestrictedSettingsDetails() {
         context.startActivity(intent)
     }
+
+    override fun isBlockedByPhoneCall(): Boolean {
+        return intent.getStringExtra(Intent.EXTRA_REASON) == reasonPhoneState
+    }
 }
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 0bb92ce..fb4880f 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
@@ -163,9 +163,11 @@
 
                 is BlockedByAdmin ->
                     restrictedMode.getSummary(checkedIfBlockedByAdmin ?: checkedIfNoRestricted())
-                is BlockedByEcm ->
+                is BlockedByEcm -> if (restrictedMode.isBlockedByPhoneCall()) {
+                    context.getString(com.android.settingslib.R.string.disabled_in_phone_call_text)
+                } else {
                     context.getString(com.android.settingslib.R.string.disabled)
-
+                }
                 null -> context.getPlaceholder()
             }
         }
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 6a169e9..f6364ff 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Laai vinnig"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Beheer deur administrateur"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Beheer deur Beperkte Instellings"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Gedeaktiveer"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Toegelaat"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nie toegelaat nie"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index be2daa2..d374a9a 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"ፈጣን መሙያ"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"በአስተዳዳሪ ቁጥጥር የተደረገበት"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"በተገደበ ቅንብር ቁጥጥር የሚደረግበት"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"ቦዝኗል"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"ይፈቀዳል"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"አይፈቀድም"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index f334f99..4d359a8 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"جارٍ الشحن السريع"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"إعدادات يتحكم فيها المشرف"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"يتحكّم فيه إعداد محظور"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"غير مفعّل"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"تطبيق مسموح به"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"تطبيق غير مسموح به"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 6e67645..c98d3de 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"দ্ৰুত চাৰ্জিং"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"এডমিনৰ দ্বাৰা নিয়ন্ত্ৰিত"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"প্ৰতিবন্ধিত ছেটিঙৰ দ্বাৰা নিয়ন্ত্ৰিত"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"নিষ্ক্ৰিয়"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"অনুমতি দিয়া হৈছে"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"অনুমতি দিয়া হোৱা নাই"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index b8e7582..db7d162 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Sürətli şarj"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Admin tərəfindən nəzarət olunur"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Məhdudlaşdırılmış Ayar ilə nəzarət edilir"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Deaktiv"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"İcazə verilib"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"İcazə verilməyib"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 295dd83..3f11056 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Brzo punjenje"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontroliše administrator"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolišu ograničena podešavanja"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Dozvoljeno"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nije dozvoljeno"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 90ed686..eb6e0a5 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Ідзе хуткая зарадка"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Кантралюецца адміністратарам"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Пад кіраваннем Абмежаванага наладжвання"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Адключанае"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Дазволена"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Забаронена"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index d450687..ede0a3a 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Зарежда се бързо"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Контролира се от администратор"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Управлява се чрез ограничена настройка"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Деактивирано"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Има разрешение"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Няма разрешение"</string>
diff --git a/packages/SettingsLib/res/values-bn/arrays.xml b/packages/SettingsLib/res/values-bn/arrays.xml
index 2b939d0..6d5da27 100644
--- a/packages/SettingsLib/res/values-bn/arrays.xml
+++ b/packages/SettingsLib/res/values-bn/arrays.xml
@@ -232,7 +232,7 @@
     <item msgid="2464080977843960236">"অ্যানিমেশন স্কেল ১০x"</item>
   </string-array>
   <string-array name="overlay_display_devices_entries">
-    <item msgid="4497393944195787240">"কোনো কিছুই নয়"</item>
+    <item msgid="4497393944195787240">"কোনও কিছুই নয়"</item>
     <item msgid="8461943978957133391">"480p"</item>
     <item msgid="6923083594932909205">"480p (নিরাপদ)"</item>
     <item msgid="1226941831391497335">"720p"</item>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 8cb1542..ab9c34a 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"ফাস্ট চার্জিং"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"প্রশাসকের দ্বারা নিয়ন্ত্রিত"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"এটি বিধিনিষেধ সেটিং থেকে নিয়ন্ত্রণ করা হয়"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"অক্ষম হয়েছে"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"অনুমোদিত"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"অনুমোদিত নয়"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 1847a46..ec3d5e9 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -359,7 +359,7 @@
     <string name="enable_terminal_title" msgid="3834790541986303654">"Lokalni terminal"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Omogući terminalnu aplik. koja nudi pristup lok. kom. okruženju"</string>
     <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Linuxovo okruženje za razvoj"</string>
-    <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentalno) Pokreni Linux terminal na Androidu"</string>
+    <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Eksperimentalno) Pokreni Linux terminal u Androidu"</string>
     <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Ako onemogućite ovo, podaci Linux terminala će se obrisati"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP provjera"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Postavke HDCP provjere"</string>
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Brzo punjenje"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Pod kontrolom administratora"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolira ograničena postavka"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Dozvoljeno"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nije dozvoljeno"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index ad9cc35..ef2920d 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Càrrega ràpida"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlat per l\'administrador"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlat per l\'opció de configuració restringida"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Desactivat"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Amb permís"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Sense permís"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 867ddfd..54a4af8 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Rychlé nabíjení"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Spravováno administrátorem"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Spravováno omezeným nastavením"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Deaktivováno"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Povoleno"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Není povoleno"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 43e9cfd..71c6be1 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Lynopladning"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontrolleret af administratoren"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Styres af en begrænset indstilling"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Deaktiveret"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Tilladt"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Ikke tilladt"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 62aa4a7..1955da0 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Schnelles Laden"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Durch den Administrator verwaltet"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Gesteuert durch eingeschränkte Einstellung"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Deaktiviert"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Zugelassen"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nicht zugelassen"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index ab75a9b..7f9f646 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Γρήγορη φόρτιση"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Ελέγχονται από το διαχειριστή"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Ελέγχεται από τη Ρύθμιση με περιορισμό"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Απενεργοποιημένη"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Επιτρέπεται"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Δεν επιτρέπεται"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 7573543..58bb7d8 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Fast charging"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlled by admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlled by restricted setting"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Disabled"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Allowed"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Not allowed"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 3d5d5c7..3b35b97 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Fast charging"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlled by admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlled by Restricted Setting"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Disabled"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Allowed"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Not allowed"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 7573543..58bb7d8 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Fast charging"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlled by admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlled by restricted setting"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Disabled"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Allowed"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Not allowed"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 7573543..58bb7d8 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Fast charging"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlled by admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlled by restricted setting"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Disabled"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Allowed"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Not allowed"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index bb38f8f..524310d 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -249,9 +249,9 @@
     <string name="apn_settings_not_available" msgid="1147111671403342300">"La configuración del nombre de punto de acceso no está disponible para este usuario."</string>
     <string name="enable_adb" msgid="8072776357237289039">"Depuración por USB"</string>
     <string name="enable_adb_summary" msgid="3711526030096574316">"Modo de depuración cuando se conecta el USB"</string>
-    <string name="clear_adb_keys" msgid="3010148733140369917">"Revocar autorizaciones de depur. USB"</string>
+    <string name="clear_adb_keys" msgid="3010148733140369917">"Revocar autorizaciones de depuración por USB"</string>
     <string name="enable_adb_wireless" msgid="6973226350963971018">"Depuración inalámbrica"</string>
-    <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Modo de depuración cuando la conexión Wi‑Fi está activada"</string>
+    <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Modo de depuración cuando haya conexión Wi‑Fi"</string>
     <string name="adb_wireless_error" msgid="721958772149779856">"Error"</string>
     <string name="adb_wireless_settings" msgid="2295017847215680229">"Depuración inalámbrica"</string>
     <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver y usar los dispositivos disponibles, activa la depuración inalámbrica"</string>
@@ -288,7 +288,7 @@
     <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Permitir que el cargador de inicio se desbloquee"</string>
     <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"¿Permitir desbloqueo de OEM?"</string>
     <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"ADVERTENCIA: Las funciones de protección de dispositivos no funcionarán en este dispositivo mientras esta configuración esté activada."</string>
-    <string name="mock_location_app" msgid="6269380172542248304">"Seleccionar aplicación de ubicación de prueba"</string>
+    <string name="mock_location_app" msgid="6269380172542248304">"Seleccionar app de ubicación ficticia"</string>
     <string name="mock_location_app_not_set" msgid="6972032787262831155">"No se configuró aplicación de ubicación de prueba."</string>
     <string name="mock_location_app_set" msgid="4706722469342913843">"Aplicación de ubicación de prueba: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="debug_networking_category" msgid="6829757985772659599">"Redes"</string>
@@ -424,7 +424,7 @@
     <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>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simular pantallas secundarias"</string>
-    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Posición de visualización de la sombra"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Posición del panel en la pantalla"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplicaciones"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Eliminar actividades"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Descartar todas las actividades en cuanto el usuario las abandona"</string>
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Carga rápida"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlada por el administrador"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Función controlada por configuración restringida"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Inhabilitada"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Con permiso"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"No permitida"</string>
@@ -615,7 +617,7 @@
     <string name="help_label" msgid="3528360748637781274">"Ayuda y comentarios"</string>
     <string name="storage_category" msgid="2287342585424631813">"Almacenamiento"</string>
     <string name="shared_data_title" msgid="1017034836800864953">"Datos compartidos"</string>
-    <string name="shared_data_summary" msgid="5516326713822885652">"Ver y modificar los datos compartidos"</string>
+    <string name="shared_data_summary" msgid="5516326713822885652">"Consulta y modifica los datos compartidos"</string>
     <string name="shared_data_no_blobs_text" msgid="3108114670341737434">"No hay datos compartidos para este usuario."</string>
     <string name="shared_data_query_failure_text" msgid="3489828881998773687">"Se produjo un error al recuperar los datos compartidos. Vuelve a intentarlo."</string>
     <string name="blob_id_text" msgid="8680078988996308061">"ID de datos compartidos: <xliff:g id="BLOB_ID">%d</xliff:g>"</string>
@@ -681,7 +683,7 @@
     <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Salir del modo de invitado"</string>
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Cuando salgas, se borrará toda la actividad"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Puedes guardar o borrar la actividad cuando salgas"</string>
-    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restablece la sesión para eliminar la actividad ahora; o guarda o borra la actividad cuando salgas"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restablece la sesión para eliminar la actividad ahora, o guarda o borra la actividad cuando salgas"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Hubo demasiados intentos incorrectos. Se borrarán los datos de este dispositivo."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Hubo demasiados intentos incorrectos. Se borrará este usuario."</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index eb03083..b881994 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -359,7 +359,7 @@
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Habilitar aplicación de terminal que ofrece acceso a shell local"</string>
     <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Entorno de desarrollo de Linux"</string>
-    <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Ejecutar un terminal de Linux en Android"</string>
+    <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Experimental) Ejecuta un terminal de Linux en Android"</string>
     <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"Si la inhabilitas, se borrarán los datos del terminal de Linux"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Comprobación de HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Establecer comprobación HDCP"</string>
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Carga rápida"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlada por el administrador"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlado por ajustes restringidos"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Inhabilitada"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Autorizadas"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"No autorizadas"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 0628ba3..e089655 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Kiirlaadimine"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Juhib administraator"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Haldavad piiranguga seaded"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Keelatud"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Lubatud"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Pole lubatud"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index b257dd1..a5235cf 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Kargatze bizkorra"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Administratzaileak kontrolatzen du"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Ezarpen mugatuak kontrolatzen du"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Desgaituta"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Baimenduta"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Baimendu gabe"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 60121cc..6d5e42b 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"درحال شارژ سریع"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"توسط سرپرست سیستم کنترل می‌شود"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"با تنظیم «حالت محدود» کنترل می‌شود"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"غیر فعال شد"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"مجاز بودن"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"مجاز نبودن"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index d0d9037..1e2db99 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Nopea lataus"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Järjestelmänvalvoja hallinnoi tätä asetusta."</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Rajoitettujen asetusten mukaisesti"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Pois päältä"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Sallittu"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Ei sallittu"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 27e4906..f2a3454 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -359,7 +359,7 @@
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Activer l\'appli Terminal permettant l\'accès au shell local"</string>
     <string name="enable_linux_terminal_title" msgid="5076044866895670637">"Environnement de développement Linux"</string>
-    <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Expérimental) Exécutez le terminal Linux sur Android"</string>
+    <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(Expérimental) Exécuter le terminal Linux sur Android"</string>
     <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"La désactivation effacera les données du terminal Linux"</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>
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Recharge rapide"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Contrôlé par l\'administrateur"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Contrôlé par les paramètres restreints"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Désactivée"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Autorisée"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Non autorisée"</string>
diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml
index 970e217..36eb52d 100644
--- a/packages/SettingsLib/res/values-fr/arrays.xml
+++ b/packages/SettingsLib/res/values-fr/arrays.xml
@@ -296,7 +296,7 @@
   <string-array name="shade_display_awareness_summaries">
     <item msgid="2964753205732912921">"Afficher le volet sur l\'écran de l\'appareil uniquement"</item>
     <item msgid="7795034287069726554">"Afficher l\'appareil sur un seul écran externe"</item>
-    <item msgid="5280431949814340475">"Afficher l\'appareil sur le dernier écran sélectionné"</item>
+    <item msgid="5280431949814340475">"Afficher l\'appareil sur le dernier écran avec lequel l\'utilisateur a interagi"</item>
   </string-array>
   <string-array name="shade_display_awareness_values">
     <item msgid="3055776101992426514">"default_display"</item>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 87d768a..a017fa7 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Recharge rapide"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Contrôlé par l\'administrateur"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Contrôlé par les paramètres restreints"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Désactivée"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Autorisé"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Non autorisé"</string>
@@ -681,7 +683,7 @@
     <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Quitter la session Invité"</string>
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Toute l\'activité sera supprimée à la fin de la session"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Vous pouvez enregistrer ou supprimer l\'activité en quittant"</string>
-    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Réinitialisez la session pour supprimer immédiatement l\'activité. Vous pourrez aussi l\'enregistrer ou la supprimer en quittant la session."</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Réinitialisez pour supprimer immédiatement l\'activité de la session, ou choisissez d\'enregistrer ou de supprimer l\'activité à la fin de la session."</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Sélectionner une photo"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Trop de tentatives incorrectes. Les données de cet appareil vont être supprimées."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Trop de tentatives incorrectes. Ce compte utilisateur va être supprimé."</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 4e90b53..6b28019 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Carga rápida"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Opción controlada polo administrador"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Baixo o control de opcións restrinxidas"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Desactivada"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Permiso concedido"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Permiso non concedido"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 9b8f627..fbf9afc 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -223,7 +223,7 @@
     <string name="tts_engine_preference_section_title" msgid="3861562305498624904">"મનપસંદ એન્જિન"</string>
     <string name="tts_general_section_title" msgid="8919671529502364567">"સામાન્ય"</string>
     <string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"સ્પીચની પિચ ફરીથી સેટ કરો"</string>
-    <string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"ટેક્સ્ટ બોલાયેલ છે તે પિચને ડિફોલ્ટ પર ફરીથી સેટ કરો."</string>
+    <string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"ટેક્સ્ટ બોલાયેલી છે તે પિચને ડિફૉલ્ટ પર રીસેટ કરો."</string>
   <string-array name="tts_rate_entries">
     <item msgid="4563475121751694801">"60%"</item>
     <item msgid="6323184326270638754">"80%"</item>
@@ -446,7 +446,7 @@
     <string name="local_backup_password_toast_validation_failure" msgid="714669442363647122">"નિષ્ફળતા સેટિંગ બેકઅપ પાસવર્ડ"</string>
     <string name="loading_injected_setting_summary" msgid="8394446285689070348">"લોડ થઈ રહ્યું છે…"</string>
   <string-array name="color_mode_names">
-    <item msgid="3836559907767149216">"વાઇબ્રન્ટ (ડિફોલ્ટ)"</item>
+    <item msgid="3836559907767149216">"વાઇબ્રન્ટ (ડિફૉલ્ટ)"</item>
     <item msgid="9112200311983078311">"કુદરતી"</item>
     <item msgid="6564241960833766170">"સ્ટૅન્ડર્ડ"</item>
   </string-array>
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"ઝડપી ચાર્જિંગ"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"વ્યવસ્થાપક દ્વારા નિયંત્રિત"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"પ્રતિબંધિત સેટિંગ દ્વારા નિયંત્રિત"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"બંધ કરી"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"મંજૂરી છે"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"મંજૂરી નથી"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 1923a72e..4319776 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"फ़ास्ट चार्जिंग"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"इसका नियंत्रण एडमिन के पास है"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"इसे पाबंदी मोड वाली सेटिंग से कंट्रोल किया जाता है"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"बंद किया गया"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"अनुमति है"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"अनुमति नहीं है"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 4c743a9..0763788 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Brzo punjenje"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontrolira administrator"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolira ograničena postavka"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Dopušteno"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nije dopušteno"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index b17dfff..6627cb1 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Gyors töltés…"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Rendszergazda által irányítva"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Korlátozott beállítás vezérli"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Letiltva"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Engedélyezett"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nem engedélyezett"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index abca57c..2248b7b 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Արագ լիցքավորում"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Վերահսկվում է ադմինիստրատորի կողմից"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Կառավարվում է սահմանափակ ռեժիմի կարգավորումներով"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Կասեցված է"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Թույլատրված է"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Արգելված"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 784a758..5798f8d 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Pengisian daya cepat"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Dikontrol oleh admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Dikontrol oleh Setelan Terbatas"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Dinonaktifkan"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Diizinkan"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Tidak diizinkan"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 88f657a..e8e49d0 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Hraðhleðsla"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Stjórnað af kerfisstjóra"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Stýrt af takmarkaði stillingu"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Óvirkt"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Heimilað"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Ekki heimilað"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index a604e5b..b2404cf 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Ricarica rapida"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Gestita dall\'amministratore"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Gestita tramite impostazioni con restrizioni"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Disattivato"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Autorizzazione concessa"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Autorizzazione non concessa"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index be26f71..b520105 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"טעינה מהירה"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"נמצא בשליטת מנהל מערכת"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"בשליטה של הגדרה מוגבלת"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"מושבת"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"מורשה"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"לא מורשה"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 10f1427..114a998 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"急速充電中"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"管理者により管理されています"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"制限付き設定によって管理されています"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"無効"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"許可"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"許可しない"</string>
@@ -666,7 +668,7 @@
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"削除"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"ゲストをリセットしています…"</string>
     <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"ゲスト セッションをリセットしますか?"</string>
-    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"新しいゲスト セッションが開始し、現在のセッションのすべてのアプリとデータが削除されます"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"新しいゲスト セッションが開始され、現在のセッションのすべてのアプリとデータが削除されます"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ゲストモードを終了しますか?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"現在のゲスト セッションからすべてのアプリとデータが削除されます"</string>
     <string name="grant_admin" msgid="4323199171790522574">"はい、管理者にします"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 4473216..8a2fd35 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"სწრაფი დატენა"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"იმართება ადმინისტრატორის მიერ"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"კონტროლდება შეზღუდული რეჟიმის პარამეტრით"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"გამორთული"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"დაშვებულია"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"დაუშვებელია"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index a0a91c8..ebb723c 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Жылдам зарядтау"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Әкімші басқарады"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Шектелген параметрлер арқылы басқарылады."</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Өшірілген"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Рұқсат берілген"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Рұқсат етілмеген"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index bee7772..cd36e49 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"ការសាកថ្មរហ័ស"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"គ្រប់គ្រងដោយអ្នកគ្រប់គ្រង"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"គ្រប់គ្រងដោយការកំណត់ដែលបានរឹតបន្តឹង"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"បិទ"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"បាន​អនុញ្ញាត"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"មិន​បានអនុញ្ញាត​"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index f11dff5..b0b6fca 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"ಫಾಸ್ಟ್ ಚಾರ್ಜಿಂಗ್"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"ನಿರ್ವಾಹಕರ ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗಿದೆ"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ನಿರ್ಬಂಧಿಸಲಾದ ಸೆಟ್ಟಿಂಗ್ ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗುತ್ತದೆ"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"ಅನುಮತಿಸಲಾಗಿದೆ"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"ಅನುಮತಿ ಇಲ್ಲ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 672ad8c..9a2af37 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"급속 충전"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"관리자가 제어"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"제한된 설정으로 제어됨"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"사용 안함"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"허용됨"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"허용되지 않음"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index a9b4a1e..a756d57 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Ыкчам кубаттоо"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Администратор тарабынан көзөмөлдөнөт"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Чектелген параметр аркылуу көзөмөлдөнөт"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Өчүрүлгөн"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Уруксат берилген"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Тыюу салынган"</string>
@@ -690,7 +692,7 @@
     <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Түзмөктүн демейки параметри"</string>
     <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Өчүк"</string>
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Күйүк"</string>
-    <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Бул өзгөрүү күчүнө кириши үчүн, түзмөктү өчүрүп күйгүзүңүз. Азыр же кийинчерээк өчүрүп күйгүзсөңүз болот."</string>
+    <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Бул өзгөрүү күчүнө кириши үчүн түзмөктү өчүрүп күйгүзүңүз. Азыр же кийинчерээк кылсаңыз болот."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Зымдуу гарнитура"</string>
     <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Зымдуу аудио түзмөк"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB аудио"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index cc8e42c..e919f42 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"ກຳລັງສາກໄວ"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"ຄວບຄຸມໂດຍຜູ້ເບິ່ງແຍງ"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ຄວບຄຸມໂດຍການຕັ້ງຄ່າທີ່ຈຳກັດໄວ້"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"ປິດການນຳໃຊ້"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"ອະນຸຍາດແລ້ວ"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"ບໍ່ອະນຸຍາດ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index f81d527..caa5b18 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Spartusis įkrovimas"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Valdo administratorius"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Valdoma pagal apribotą nustatymą"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Neleidžiama"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Leidžiama"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Neleidžiama"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 2738a40..84bf692 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Ātrā uzlāde"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontrolē administrators"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolē ierobežots iestatījums"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Atspējots"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Atļauts"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nav atļauts"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 9ec3bac..a06da85 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Се полни брзо"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Контролирано од администраторот"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Контролирано со ограничени поставки"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Оневозможено"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Со дозвола"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Без дозвола"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index fd8861f..b405963 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"അതിവേഗ ചാർജിംഗ്"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"അഡ്‌മിൻ നിയന്ത്രിക്കുന്നത്"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"നിയന്ത്രിത ക്രമീകരണം ഉപയോഗിച്ച് നിയന്ത്രിക്കുന്നത്"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"പ്രവർത്തനരഹിതമാക്കി"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"അനുവദനീയം"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"അനുവദിച്ചിട്ടില്ല"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index a1ab4f3..c1652132 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Шуурхай цэнэглэх"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Админ удирдсан"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Хязгаарлагдсан тохиргоогоор хянадаг"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Идэвхгүйжүүлсэн"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Зөвшөөрсөн"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Зөвшөөрөөгүй"</string>
diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml
index 2fd2058..959499c 100644
--- a/packages/SettingsLib/res/values-mr/arrays.xml
+++ b/packages/SettingsLib/res/values-mr/arrays.xml
@@ -232,7 +232,7 @@
     <item msgid="2464080977843960236">"ॲनिमेशन स्केल 10x"</item>
   </string-array>
   <string-array name="overlay_display_devices_entries">
-    <item msgid="4497393944195787240">"काहीही नाही"</item>
+    <item msgid="4497393944195787240">"काेणताही नाही"</item>
     <item msgid="8461943978957133391">"480p"</item>
     <item msgid="6923083594932909205">"480p (सुरक्षित)"</item>
     <item msgid="1226941831391497335">"720p"</item>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 1af9286..d47f8ff 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"फास्ट चार्जिंग"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"प्रशासकाने नियंत्रित केलेले"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"प्रतिबंधित केलेल्या सेटिंग द्वारे नियंत्रित"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"अक्षम"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"अनुमती आहे"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"अनुमती नाही"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 97a7b43..478e8d2 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Pengecasan pantas"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Dikawal oleh pentadbir"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Dikawal oleh Tetapan Terhad"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Dilumpuhkan"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Dibenarkan"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Tidak dibenarkan"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 4a31a12..4ba82fd 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"အမြန်အားသွင်းခြင်း"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"စီမံခန့်ခွဲသူမှ ထိန်းချုပ်ပါသည်"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ကန့်သတ်ဆက်တင်ဖြင့် ထိန်းချုပ်ထားသည်"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"ပိတ်ထားပြီး"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"ခွင့်ပြုထားသည်"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"ခွင့်မပြုပါ"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 94a701b..f6de346 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Hurtiglading"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontrollert av administratoren"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrollert av en begrenset innstilling"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Deaktivert"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Tillatt"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Ikke tillatt"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index a2ee640..28d02a1 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"फास्ट चार्जिङ"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"प्रशासकद्वारा नियन्त्रित"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"प्रतिबन्धित सेटिङले नियन्त्रण गरेको"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"असक्षम पारियो"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"अनुमति छ"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"अनुमति छैन"</string>
@@ -615,7 +617,7 @@
     <string name="help_label" msgid="3528360748637781274">"मद्दत र प्रतिक्रिया"</string>
     <string name="storage_category" msgid="2287342585424631813">"भण्डारण"</string>
     <string name="shared_data_title" msgid="1017034836800864953">"सेयर गरिएको डेटा"</string>
-    <string name="shared_data_summary" msgid="5516326713822885652">"साझा डेटा हेर्नुहोस् र परिमार्जन गर्नुहोस्"</string>
+    <string name="shared_data_summary" msgid="5516326713822885652">"सेयर गरिएको डेटा हेर्नुहोस् र परिमार्जन गर्नुहोस्"</string>
     <string name="shared_data_no_blobs_text" msgid="3108114670341737434">"यो प्रयोगकर्तासँग कुनै पनि डेटा सेयर गरिएको छैन।"</string>
     <string name="shared_data_query_failure_text" msgid="3489828881998773687">"सेयर गरिएको डेटा प्राप्त गर्ने क्रममा कुनै त्रुटि भयो। फेरि प्रयास गर्नुहोस्।"</string>
     <string name="blob_id_text" msgid="8680078988996308061">"साझा डेटाको ID: <xliff:g id="BLOB_ID">%d</xliff:g>"</string>
@@ -690,7 +692,7 @@
     <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"डिफल्ट डिभाइस"</string>
     <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"असक्षम पारिएको छ"</string>
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"सक्षम पारिएको छ"</string>
-    <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"यो परिवर्तन लागू गर्न तपाईंको यन्त्र अनिवार्य रूपमा रिबुट गर्नु पर्छ। अहिले रिबुट गर्नुहोस् वा रद्द गर्नुहोस्।"</string>
+    <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"यो परिवर्तन लागू गर्न तपाईंको डिभाइस अनिवार्य रूपमा रिबुट गर्नु पर्छ। अहिले नै रिबुट गर्नुहोस् वा रद्द गर्नुहोस्।"</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"तारयुक्त हेडफोन"</string>
     <string name="media_transfer_headphone_name" msgid="1157798825650178478">"तारयुक्त अडियो"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"USB अडियो"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 63014b6..00917c5 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Snel opladen"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Ingesteld door beheerder"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Beheerd door beperkte instelling"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Uitgezet"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Toegestaan"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Niet toegestaan"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 869d9a1..69d57a6 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"ଫାଷ୍ଟ ଚାର୍ଜିଂ"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"ଆଡ୍‌ମିନ୍‌ ଦ୍ୱାରା ନିୟନ୍ତ୍ରିତ"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ପ୍ରତିବନ୍ଧିତ ସେଟିଂ ଦ୍ୱାରା ନିୟନ୍ତ୍ରଣ କରାଯାଇଛି"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"ଅକ୍ଷମ ହୋଇଛି"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"ଅନୁମତି ଦିଆଯାଇଛି"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"ଅନୁମତି ନାହିଁ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 6c0ce86..ca97244 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"ਤੇਜ਼ ਚਾਰਜਿੰਗ"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਕੰਟਰੋਲ ਕੀਤੀ ਗਈ"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ਪ੍ਰਤਿਬੰਧਿਤ ਸੈਟਿੰਗ ਰਾਹੀਂ ਕੰਟਰੋਲ ਕੀਤੀ ਜਾਂਦੀ ਹੈ"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"ਅਯੋਗ ਬਣਾਇਆ"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"ਮਨਜ਼ੂਰਸ਼ੁਦਾ"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"ਗੈਰ-ਮਨਜ਼ੂਰਸ਼ੁਦਾ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index d789c64..9fc2765 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Szybkie ładowanie"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontrolowane przez administratora"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Obowiązują ustawienia z ograniczonym dostępem"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Wyłączona"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Dozwolone"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Niedozwolone"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index bd08415..1e45965 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -279,7 +279,7 @@
     <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Conecte-se a uma rede Wi-Fi"</string>
     <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string>
     <string name="bugreport_in_power" msgid="8664089072534638709">"Atalho para relatório de bugs"</string>
-    <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Mostrar um botão para gerar relatórios de bugs no menu do botão liga/desliga"</string>
+    <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Mostra um botão para gerar relatórios de bugs no menu do botão liga/desliga"</string>
     <string name="keep_screen_on" msgid="1187161672348797558">"Permanecer ativo"</string>
     <string name="keep_screen_on_summary" msgid="1510731514101925829">"A tela nunca entra em suspensão enquanto está carregando"</string>
     <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Ativar registro de rastreamento de HCI Bluetooth"</string>
@@ -428,11 +428,11 @@
     <string name="debug_applications_category" msgid="5394089406638954196">"Apps"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Não manter atividades"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Destruir todas as atividades quando o usuário sair"</string>
-    <string name="app_process_limit_title" msgid="8361367869453043007">"Limite do processamento em 2º plano"</string>
+    <string name="app_process_limit_title" msgid="8361367869453043007">"Limite de processos em 2º plano"</string>
     <string name="show_all_anrs" msgid="9160563836616468726">"Mostrar ANRs em 2º plano"</string>
     <string name="show_all_anrs_summary" msgid="8562788834431971392">"Exibir a caixa de diálogo \"App não responde\" para apps em segundo plano"</string>
     <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Mostrar avisos de notificações"</string>
-    <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Exibir aviso na tela quando um app posta uma notificação sem um canal válido"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Exibe aviso na tela quando um app posta notificação sem canal válido"</string>
     <string name="force_allow_on_external" msgid="9187902444231637880">"Forçar permissão de apps em armazenamento externo"</string>
     <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>
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Carregamento rápido"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlada pelo admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlada pelas configurações restritas"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Desativado"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Permitido"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Não permitido"</string>
@@ -665,8 +667,8 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Redefinir"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remover"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Redefinindo visitante…"</string>
-    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Redefinir Sessão de visitante?"</string>
-    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Essa ação vai iniciar uma nova Sessão de visitante e excluir todos os apps e dados da sessão atual"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Redefinir sessão de visitante?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Essa ação vai iniciar uma nova sessão de visitante e excluir todos os apps e dados da sessão atual"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Sair do modo visitante?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Essa ação vai excluir apps e dados da Sessão de visitante atual"</string>
     <string name="grant_admin" msgid="4323199171790522574">"Sim, tornar esse usuário um administrador"</string>
@@ -690,7 +692,7 @@
     <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Padrão do dispositivo"</string>
     <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Desativado"</string>
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativado"</string>
-    <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reinicializar o dispositivo para que a mudança seja aplicada. Faça isso agora ou cancele."</string>
+    <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reiniciar o dispositivo para que a mudança seja aplicada. Faça isso agora ou cancele."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Fones de ouvido com fio"</string>
     <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Áudio com fio"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Áudio USB"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 457aacd..bf21463 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Carregamento rápido"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlado pelo gestor"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlado por uma definição restrita"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Desativada"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Autorizada"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Não autorizada"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index bd08415..1e45965 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -279,7 +279,7 @@
     <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Conecte-se a uma rede Wi-Fi"</string>
     <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string>
     <string name="bugreport_in_power" msgid="8664089072534638709">"Atalho para relatório de bugs"</string>
-    <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Mostrar um botão para gerar relatórios de bugs no menu do botão liga/desliga"</string>
+    <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Mostra um botão para gerar relatórios de bugs no menu do botão liga/desliga"</string>
     <string name="keep_screen_on" msgid="1187161672348797558">"Permanecer ativo"</string>
     <string name="keep_screen_on_summary" msgid="1510731514101925829">"A tela nunca entra em suspensão enquanto está carregando"</string>
     <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Ativar registro de rastreamento de HCI Bluetooth"</string>
@@ -428,11 +428,11 @@
     <string name="debug_applications_category" msgid="5394089406638954196">"Apps"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Não manter atividades"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Destruir todas as atividades quando o usuário sair"</string>
-    <string name="app_process_limit_title" msgid="8361367869453043007">"Limite do processamento em 2º plano"</string>
+    <string name="app_process_limit_title" msgid="8361367869453043007">"Limite de processos em 2º plano"</string>
     <string name="show_all_anrs" msgid="9160563836616468726">"Mostrar ANRs em 2º plano"</string>
     <string name="show_all_anrs_summary" msgid="8562788834431971392">"Exibir a caixa de diálogo \"App não responde\" para apps em segundo plano"</string>
     <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Mostrar avisos de notificações"</string>
-    <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Exibir aviso na tela quando um app posta uma notificação sem um canal válido"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Exibe aviso na tela quando um app posta notificação sem canal válido"</string>
     <string name="force_allow_on_external" msgid="9187902444231637880">"Forçar permissão de apps em armazenamento externo"</string>
     <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>
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Carregamento rápido"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlada pelo admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlada pelas configurações restritas"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Desativado"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Permitido"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Não permitido"</string>
@@ -665,8 +667,8 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Redefinir"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remover"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Redefinindo visitante…"</string>
-    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Redefinir Sessão de visitante?"</string>
-    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Essa ação vai iniciar uma nova Sessão de visitante e excluir todos os apps e dados da sessão atual"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Redefinir sessão de visitante?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Essa ação vai iniciar uma nova sessão de visitante e excluir todos os apps e dados da sessão atual"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Sair do modo visitante?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Essa ação vai excluir apps e dados da Sessão de visitante atual"</string>
     <string name="grant_admin" msgid="4323199171790522574">"Sim, tornar esse usuário um administrador"</string>
@@ -690,7 +692,7 @@
     <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"Padrão do dispositivo"</string>
     <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Desativado"</string>
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativado"</string>
-    <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reinicializar o dispositivo para que a mudança seja aplicada. Faça isso agora ou cancele."</string>
+    <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reiniciar o dispositivo para que a mudança seja aplicada. Faça isso agora ou cancele."</string>
     <string name="media_transfer_wired_headphone_name" msgid="8698668536022665254">"Fones de ouvido com fio"</string>
     <string name="media_transfer_headphone_name" msgid="1157798825650178478">"Áudio com fio"</string>
     <string name="media_transfer_usb_audio_name" msgid="1789292056757821355">"Áudio USB"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 1b66145..af09734 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Încărcare rapidă"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlată de administrator"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlată de setarea restricționată"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Dezactivată"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Permise"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nepermise"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 56748fb..b42e4e1 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Быстрая зарядка"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Контролируется администратором"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Контролируется настройками с ограниченным доступом"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Отключено"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Разрешено"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Запрещено"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 5030450..1b02d28 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"වේගවත් ආරෝපණය"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"පරිපාලක විසින් පාලනය කරන ලදී"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"සීමා කළ සැකසීම මගින් පාලනය වේ"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"අබල කර ඇත"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"ඉඩ දුන්"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"ඉඩ නොදෙන"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index b4787f2..267193a 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -288,8 +288,8 @@
     <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Povoliť odblokovanie ponuky bootloader"</string>
     <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"Povoliť odblokovanie OEM?"</string>
     <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"UPOZORNENIE: Dokiaľ bude toto nastavenie zapnuté, funkcie ochrany zariadenia nebudú na tomto zariadení fungovať."</string>
-    <string name="mock_location_app" msgid="6269380172542248304">"Vybrať aplikáciu na simuláciu polohy"</string>
-    <string name="mock_location_app_not_set" msgid="6972032787262831155">"Žiadna aplikácia na simuláciu polohy"</string>
+    <string name="mock_location_app" msgid="6269380172542248304">"Vybrať aplikáciu so skúšobnou polohou"</string>
+    <string name="mock_location_app_not_set" msgid="6972032787262831155">"Žiadna aplikácia so skúšobnou polohou"</string>
     <string name="mock_location_app_set" msgid="4706722469342913843">"Aplikácia na simuláciu polohy: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="debug_networking_category" msgid="6829757985772659599">"Siete"</string>
     <string name="wifi_display_certification" msgid="1805579519992520381">"Certifikácia bezdrôtového zobrazenia"</string>
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Nabíja sa rýchlo"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Ovládané správcom"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Ovládané obmedzeným nastavením"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Deaktivované"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Povolené"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nie je povolené"</string>
@@ -673,7 +675,7 @@
     <string name="not_grant_admin" msgid="3557849576157702485">"Nie, nenastaviť ako správcu"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Ukončiť"</string>
     <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Chcete uložiť aktivitu hosťa?"</string>
-    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Môžte uložiť aktivitu aktuálnej relácie alebo odstrániť všetky aplikácie a údaje"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Môžete uložiť aktivitu aktuálnej relácie alebo odstrániť všetky aplikácie a údaje"</string>
     <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Odstrániť"</string>
     <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Uložiť"</string>
     <string name="guest_exit_button" msgid="5774985819191803960">"Ukončiť režim pre hostí"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index b6eacf8..f85a17d 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Hitro polnjenje"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Nadzira skrbnik"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Pod nadzorom omejene nastavitve"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Onemogočeno"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Dovoljene"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Ni dovoljeno"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index ee31c29..e98046e 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Karikim i shpejtë"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontrolluar nga administratori"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrollohet nga \"Cilësimet e kufizuara\""</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Çaktivizuar"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Lejohet"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nuk lejohet"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index fcf1e4f..693e435 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Брзо пуњење"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Контролише администратор"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Контролишу ограничена подешавања"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Онемогућено"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Дозвољено"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Није дозвољено"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 49d520e..bc110c6 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -507,7 +507,7 @@
     <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – laddas"</string>
     <string name="power_fast_charging_duration_v2" msgid="3797735998640359490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATUS">%2$s</xliff:g> – fulladdad till <xliff:g id="TIME">%3$s</xliff:g>"</string>
     <string name="power_charging_duration_v2" msgid="2938998284074003248">"<xliff:g id="LEVEL">%1$s</xliff:g> – fulladdad till <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only_v2" msgid="5358176435722950193">"Fulladdad till <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only_v2" msgid="5358176435722950193">"Fulladdad kl. <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_fast_charging_duration_only_v2" msgid="6270950195810579563">"Fulladdad till <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Okänd"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Laddar"</string>
@@ -524,6 +524,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Snabbladdning"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Strys av administratören"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Styrs av spärrad inställning"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Inaktiverad"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Tillåts"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Tillåts inte"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index d84d355..2b175f5 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -523,10 +523,12 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Inachaji kwa kasi"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Imedhibitiwa na msimamizi"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Imedhibitiwa na Mpangilio wenye Mipaka"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Imezimwa"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Imeruhusiwa"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Hairuhusiwi"</string>
-    <string name="install_other_apps" msgid="3232595082023199454">"Kusakinisha programu zisizojulikana"</string>
+    <string name="install_other_apps" msgid="3232595082023199454">"Kuweka programu zisizojulikana"</string>
     <string name="home" msgid="973834627243661438">"Ukurasa wa Kwanza wa Mipangilio"</string>
   <string-array name="battery_labels">
     <item msgid="7878690469765357158">"0%"</item>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index b0c25d0..dd5a5a4 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"விரைவு சார்ஜிங்"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"நிர்வாகி கட்டுப்படுத்துகிறார்"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"வரையறுக்கப்பட்ட அமைப்பால் கட்டுப்படுத்தப்படுகிறது"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"முடக்கப்பட்டது"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"அனுமதிக்கப்பட்டது"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"அனுமதிக்கப்படவில்லை"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index d0b7634..12e45c2 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"ఫాస్ట్ ఛార్జింగ్"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"నిర్వాహకుని ద్వారా నియంత్రించబడింది"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"పరిమితం చేసిన సెట్టింగ్ ద్వారా నియంత్రించబడుతుంది"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"డిజేబుల్ చేయబడింది"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"అనుమతించినవి"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"అనుమతించబడలేదు"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index a228e6b..65db653 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"ชาร์จเร็ว"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"ผู้ดูแลระบบเป็นผู้ควบคุม"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ควบคุมโดยการตั้งค่าที่จำกัด"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"ปิดอยู่"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"อนุญาต"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"ไม่อนุญาต"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 6553479..959a0b3 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Fast charging"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Pinapamahalaan ng admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kinokontrol ng Pinaghihigpitang Setting"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Naka-disable"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Pinapayagan"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Hindi pinapayagan"</string>
@@ -614,8 +616,8 @@
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired na audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Tulong at feedback"</string>
     <string name="storage_category" msgid="2287342585424631813">"Storage"</string>
-    <string name="shared_data_title" msgid="1017034836800864953">"Pinaghahatiang data"</string>
-    <string name="shared_data_summary" msgid="5516326713822885652">"Tingnan at baguhin ang pinaghahatiang data"</string>
+    <string name="shared_data_title" msgid="1017034836800864953">"Naka-share na data"</string>
+    <string name="shared_data_summary" msgid="5516326713822885652">"Tingnan at baguhin ang naka-share na data"</string>
     <string name="shared_data_no_blobs_text" msgid="3108114670341737434">"Walang nakabahaging data para sa user na ito."</string>
     <string name="shared_data_query_failure_text" msgid="3489828881998773687">"Nagka-error sa pag-fetch ng nakabahaging data. Subukan ulit."</string>
     <string name="blob_id_text" msgid="8680078988996308061">"ID ng pinaghahatiang data: <xliff:g id="BLOB_ID">%d</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 6a8158b..8dcc48f 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Hızlı şarj"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Yönetici tarafından denetleniyor"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kısıtlanmış ayar tarafından kontrol ediliyor"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Devre dışı"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"İzin verildi"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"İzin verilmiyor"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index d599fb4..259cf6c 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Швидке заряджання"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Керується адміністратором"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Керується налаштуваннями з обмеженнями"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Вимкнено"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Дозволено"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Заборонено"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index f0588ef..425a0ed 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"فاسٹ چارجنگ"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"کنٹرول کردہ بذریعہ منتظم"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"محدود کردہ ترتیب کے زیر انتظام ہے"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"غیر فعال"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"اجازت ہے"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"اجازت نہیں ہے"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 6930278..fbf9b4a 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Tezkor quvvatlash"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Administrator tomonidan boshqariladi"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Cheklangan sozlama tomonidan boshqariladi"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Oʻchiq"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Ruxsat berilgan"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Ruxsat berilmagan"</string>
@@ -660,12 +662,12 @@
     <string name="guest_new_guest" msgid="3482026122932643557">"Mehmon kiritish"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Mehmonni olib tashlash"</string>
     <string name="guest_reset_guest" msgid="6110013010356013758">"Mehmon seansini tiklash"</string>
-    <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Mehmon seansi tiklansinmi?"</string>
+    <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Mehmon seansi tozalansinmi?"</string>
     <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Mehmon olib tashlansinmi?"</string>
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Tiklash"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Olib tashlash"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Mehmon seansi tiklanmoqda…"</string>
-    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Mehmon seansi tiklansinmi?"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Mehmon seansi tozalansinmi?"</string>
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Bunda yangi mehmon seansi ishga tushadi va joriy seans ilova va maʼlumotlari tozalanadi"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Mehmon rejimidan chiqasizmi?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Bunda joriy mehmon seansidagi ilova va ularning maʼlumotlari tozalanadi"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index ffdd479..59d4b4d 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Đang sạc nhanh"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Do quản trị viên kiểm soát"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Do chế độ Cài đặt hạn chế kiểm soát"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Đã tắt"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Được phép"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Không được phép"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 3b42efd..08e931b 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"正在快速充电"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"由管理员控制"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"由受限设置控制"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"已停用"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"允许"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"不允许"</string>
@@ -681,7 +683,7 @@
     <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"退出访客模式"</string>
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"退出时所有活动记录都将被删除"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"您可以在退出时保存或删除您的活动"</string>
-    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"请立即重置以删除会话活动记录;或者,您也可以在退出时保存或删除活动记录"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"重置可立即删除会话活动记录,您也可以在退出时保存或删除活动记录"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"选择照片"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"错误次数过多。系统将删除此设备上的数据。"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"错误次数过多。系统将删除此用户。"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index a6de0d9..8cc65c8 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"快速充電"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"已由管理員停用"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"由「受限設定」控制"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"已停用"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"允許"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"不允許"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index e4d95e8..d639e71 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"快速充電"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"已由管理員停用"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"由受限制的設定控管"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"已停用"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"允許"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"不允許"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 1f9eca4..4fd2c8d 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -523,6 +523,8 @@
     <string name="battery_info_status_charging_fast_v2" msgid="1825439848151256589">"Ishaja ngokushesha"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kulawulwa umqondisi"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kulawulwe Isethingi Elikhawulelwe"</string>
+    <!-- no translation found for disabled_in_phone_call_text (6568931334337318320) -->
+    <skip />
     <string name="disabled" msgid="8017887509554714950">"Akusebenzi"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Kuvumelekile"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Akuvumelekile"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 3da2271..a3e42f1 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1228,6 +1228,8 @@
 
     <!-- Summary for settings preference disabled by app ops [CHAR LIMIT=50] -->
     <string name="disabled_by_app_ops_text">Controlled by Restricted Setting</string>
+    <!-- Summary for settings preference disabled while the device is in a phone call [CHAR LIMIT=50] -->
+    <string name="disabled_in_phone_call_text">Unavailable during calls</string>
 
     <!-- [CHAR LIMIT=25] Manage applications, text telling using an application is disabled. -->
     <string name="disabled">Disabled</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 212e43a..1044750 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -44,6 +44,8 @@
 public class RestrictedPreferenceHelper {
     private static final String TAG = "RestrictedPreferenceHelper";
 
+    private static final String REASON_PHONE_STATE = "phone_state";
+
     private final Context mContext;
     private final Preference mPreference;
     String packageName;
@@ -121,7 +123,7 @@
                 if (mDisabledByAdmin) {
                     summaryView.setText(disabledText);
                 } else if (mDisabledByEcm) {
-                    summaryView.setText(R.string.disabled_by_app_ops_text);
+                    summaryView.setText(getEcmTextResId());
                 } else if (TextUtils.equals(disabledText, summaryView.getText())) {
                     // It's previously set to disabled text, clear it.
                     summaryView.setText(null);
@@ -323,7 +325,16 @@
         }
 
         if (!isEnabled && mDisabledByEcm) {
-            mPreference.setSummary(R.string.disabled_by_app_ops_text);
+            mPreference.setSummary(getEcmTextResId());
+        }
+    }
+
+    private int getEcmTextResId() {
+        if (mDisabledByEcmIntent != null && REASON_PHONE_STATE.equals(
+                mDisabledByEcmIntent.getStringExtra(Intent.EXTRA_REASON))) {
+            return R.string.disabled_in_phone_call_text;
+        } else {
+            return R.string.disabled_by_app_ops_text;
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 4ee9ff0..ceb6f7b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -16,8 +16,6 @@
 package com.android.settingslib.media;
 
 import static android.media.MediaRoute2Info.TYPE_AUX_LINE;
-import static android.media.MediaRoute2Info.TYPE_LINE_ANALOG;
-import static android.media.MediaRoute2Info.TYPE_LINE_DIGITAL;
 import static android.media.MediaRoute2Info.TYPE_BLE_HEADSET;
 import static android.media.MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
 import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
@@ -27,6 +25,8 @@
 import static android.media.MediaRoute2Info.TYPE_HDMI_ARC;
 import static android.media.MediaRoute2Info.TYPE_HDMI_EARC;
 import static android.media.MediaRoute2Info.TYPE_HEARING_AID;
+import static android.media.MediaRoute2Info.TYPE_LINE_ANALOG;
+import static android.media.MediaRoute2Info.TYPE_LINE_DIGITAL;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_AUDIO_VIDEO_RECEIVER;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_CAR;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_COMPUTER;
@@ -254,6 +254,10 @@
     protected abstract List<MediaRoute2Info> getSelectableRoutes(@NonNull RoutingSessionInfo info);
 
     @NonNull
+    protected abstract List<MediaRoute2Info> getTransferableRoutes(
+            @NonNull RoutingSessionInfo info);
+
+    @NonNull
     protected abstract List<MediaRoute2Info> getDeselectableRoutes(
             @NonNull RoutingSessionInfo info);
 
@@ -519,6 +523,22 @@
     }
 
     /**
+     * Returns the list of {@link MediaDevice media devices} that can be transferred to with the
+     * current {@link RoutingSessionInfo routing session} by the media route provider.
+     */
+    @NonNull
+    List<MediaDevice> getTransferableMediaDevices() {
+        final RoutingSessionInfo info = getActiveRoutingSession();
+
+        final List<MediaDevice> deviceList = new ArrayList<>();
+        for (MediaRoute2Info route : getTransferableRoutes(info)) {
+            deviceList.add(
+                    new InfoMediaDevice(mContext, route, mPreferenceItemMap.get(route.getId())));
+        }
+        return deviceList;
+    }
+
+    /**
      * Returns the list of {@link MediaDevice media devices} that can be deselected from the current
      * {@link RoutingSessionInfo routing session}.
      */
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index fe6659d1..76f366d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -352,6 +352,17 @@
     }
 
     /**
+     * Gets the MediaDevice list that can be transferred to with the current media session by the
+     * media route provider.
+     *
+     * @return list of MediaDevice
+     */
+    @NonNull
+    public List<MediaDevice> getTransferableMediaDevices() {
+        return mInfoMediaManager.getTransferableMediaDevices();
+    }
+
+    /**
      * Get the MediaDevice list that can be removed from current media session.
      *
      * @return list of MediaDevice
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/ManagerInfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/ManagerInfoMediaManager.java
index 82b1976..9e511ff 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/ManagerInfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/ManagerInfoMediaManager.java
@@ -117,6 +117,12 @@
 
     @Override
     @NonNull
+    protected List<MediaRoute2Info> getTransferableRoutes(@NonNull RoutingSessionInfo info) {
+        return mRouterManager.getTransferableRoutes(info);
+    }
+
+    @Override
+    @NonNull
     protected List<MediaRoute2Info> getDeselectableRoutes(@NonNull RoutingSessionInfo info) {
         return mRouterManager.getDeselectableRoutes(info);
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index b01b7c9..d018d14 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -15,6 +15,7 @@
  */
 package com.android.settingslib.media;
 
+import static android.media.MediaRoute2Info.TYPE_AUX_LINE;
 import static android.media.MediaRoute2Info.TYPE_BLE_HEADSET;
 import static android.media.MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
 import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
@@ -24,6 +25,8 @@
 import static android.media.MediaRoute2Info.TYPE_HDMI_ARC;
 import static android.media.MediaRoute2Info.TYPE_HDMI_EARC;
 import static android.media.MediaRoute2Info.TYPE_HEARING_AID;
+import static android.media.MediaRoute2Info.TYPE_LINE_ANALOG;
+import static android.media.MediaRoute2Info.TYPE_LINE_DIGITAL;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_AUDIO_VIDEO_RECEIVER;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
@@ -33,9 +36,6 @@
 import static android.media.MediaRoute2Info.TYPE_USB_HEADSET;
 import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
 import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
-import static android.media.MediaRoute2Info.TYPE_LINE_DIGITAL;
-import static android.media.MediaRoute2Info.TYPE_LINE_ANALOG;
-import static android.media.MediaRoute2Info.TYPE_AUX_LINE;
 import static android.media.RouteListingPreference.Item.FLAG_ONGOING_SESSION;
 import static android.media.RouteListingPreference.Item.FLAG_ONGOING_SESSION_MANAGED;
 import static android.media.RouteListingPreference.Item.FLAG_SUGGESTED;
@@ -244,6 +244,11 @@
      */
     public abstract String getId();
 
+    /** Returns {@code true} if the device has a non-null {@link RouteListingPreference.Item}. */
+    public boolean hasRouteListingPreferenceItem() {
+        return mItem != null;
+    }
+
     /**
      * Get selection behavior of device
      *
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java
index 2c7ec93..9fe5b1d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java
@@ -114,6 +114,12 @@
 
     @NonNull
     @Override
+    protected List<MediaRoute2Info> getTransferableRoutes(@NonNull RoutingSessionInfo info) {
+        return Collections.emptyList();
+    }
+
+    @NonNull
+    @Override
     protected List<MediaRoute2Info> getDeselectableRoutes(@NonNull RoutingSessionInfo info) {
         return Collections.emptyList();
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java
index eced7b3..6a2da18 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java
@@ -203,6 +203,13 @@
 
     @NonNull
     @Override
+    protected List<MediaRoute2Info> getTransferableRoutes(@NonNull RoutingSessionInfo info) {
+        RoutingController controller = getControllerForSession(info);
+        return getTransferableRoutes(controller);
+    }
+
+    @NonNull
+    @Override
     protected List<MediaRoute2Info> getSelectedRoutes(@NonNull RoutingSessionInfo info) {
         RoutingController controller = getControllerForSession(info);
         if (controller == null) {
@@ -272,22 +279,27 @@
     protected List<MediaRoute2Info> getTransferableRoutes(@NonNull String packageName) {
         List<RoutingController> controllers = mRouter.getControllers();
         RoutingController activeController = controllers.get(controllers.size() - 1);
+        return getTransferableRoutes(activeController);
+    }
+
+    @NonNull
+    private List<MediaRoute2Info> getTransferableRoutes(@Nullable RoutingController controller) {
         HashMap<String, MediaRoute2Info> transferableRoutes = new HashMap<>();
-
-        activeController
-                .getTransferableRoutes()
-                .forEach(route -> transferableRoutes.put(route.getId(), route));
-
-        if (activeController.getRoutingSessionInfo().isSystemSession()) {
-            mRouter.getRoutes().stream()
-                    .filter(route -> !route.isSystemRoute())
+        if (controller != null) {
+            controller
+                    .getTransferableRoutes()
                     .forEach(route -> transferableRoutes.put(route.getId(), route));
-        } else {
-            mRouter.getRoutes().stream()
-                    .filter(route -> route.isSystemRoute())
-                    .forEach(route -> transferableRoutes.put(route.getId(), route));
+
+            if (controller.getRoutingSessionInfo().isSystemSession()) {
+                mRouter.getRoutes().stream()
+                        .filter(route -> !route.isSystemRoute())
+                        .forEach(route -> transferableRoutes.put(route.getId(), route));
+            } else {
+                mRouter.getRoutes().stream()
+                        .filter(route -> route.isSystemRoute())
+                        .forEach(route -> transferableRoutes.put(route.getId(), route));
+            }
         }
-
         return new ArrayList<>(transferableRoutes.values());
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/TestModeBuilder.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/TestModeBuilder.java
index 64a2de5..ecea5fd 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/TestModeBuilder.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/TestModeBuilder.java
@@ -33,10 +33,12 @@
 import androidx.annotation.DrawableRes;
 import androidx.annotation.Nullable;
 
-import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
 
 public class TestModeBuilder {
 
+    private static final AtomicInteger sNextId = new AtomicInteger(0);
+
     private String mId;
     private AutomaticZenRule mRule;
     private ZenModeConfig.ZenRule mConfigZenRule;
@@ -47,7 +49,7 @@
 
     public TestModeBuilder() {
         // Reasonable defaults
-        int id = new Random().nextInt(1000);
+        int id = sNextId.incrementAndGet();
         mId = "rule_" + id;
         mRule = new AutomaticZenRule.Builder("Test Rule #" + id, Uri.parse("rule://" + id))
                 .setPackage("some_package")
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 1a83f0a..219ad6c 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
@@ -65,7 +65,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
@@ -78,6 +79,7 @@
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = {ShadowRouter2Manager.class})
 public class InfoMediaManagerTest {
+    @Rule public final MockitoRule mockito = MockitoJUnit.rule();
 
     private static final String TEST_PACKAGE_NAME = "com.test.packagename";
     private static final String TEST_PACKAGE_NAME_2 = "com.test.packagename2";
@@ -146,7 +148,6 @@
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
         mContext = spy(RuntimeEnvironment.application);
 
         doReturn(mMediaSessionManager).when(mContext).getSystemService(
@@ -663,6 +664,26 @@
     }
 
     @Test
+    public void getTransferableMediaDevice_checkList() {
+        final List<MediaRoute2Info> mediaRoute2Infos = new ArrayList<>();
+        final MediaRoute2Info mediaRoute2Info = mock(MediaRoute2Info.class);
+        mediaRoute2Infos.add(mediaRoute2Info);
+        mShadowRouter2Manager.setTransferableRoutes(mediaRoute2Infos);
+        when(mediaRoute2Info.getName()).thenReturn(TEST_NAME);
+        when(mediaRoute2Info.getId()).thenReturn(TEST_ID);
+        mInfoMediaManager.mRouterManager = mRouterManager;
+        when(mRouterManager.getRoutingSessions(TEST_PACKAGE_NAME))
+                .thenReturn(List.of(TEST_REMOTE_ROUTING_SESSION));
+        when(mRouterManager.getTransferableRoutes(any(RoutingSessionInfo.class)))
+                .thenReturn(mediaRoute2Infos);
+
+        final List<MediaDevice> mediaDevices = mInfoMediaManager.getTransferableMediaDevices();
+
+        assertThat(mediaDevices.size()).isEqualTo(1);
+        assertThat(mediaDevices.get(0).getName()).isEqualTo(TEST_NAME);
+    }
+
+    @Test
     public void getDeselectableMediaDevice_checkList() {
         final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
         final RoutingSessionInfo info = mock(RoutingSessionInfo.class);
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 9ab8aa8..55f7317 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -997,6 +997,12 @@
     <uses-permission android:name="android.permission.health.READ_SKIN_TEMPERATURE"
         android:featureFlag="android.permission.flags.replace_body_sensor_permission_enabled"/>
 
+    <!-- Permissions required for CTS test - CtsHealthFitnessDeviceTestCases-->
+    <uses-permission android:name="android.permission.BACKUP_HEALTH_CONNECT_DATA_AND_SETTINGS"
+        android:featureFlag="android.permission.flags.health_connect_backup_restore_permission_enabled"/>
+    <uses-permission android:name="android.permission.RESTORE_HEALTH_CONNECT_DATA_AND_SETTINGS"
+        android:featureFlag="android.permission.flags.health_connect_backup_restore_permission_enabled"/>
+
     <!-- Permission for TestClassifier tests to get access to classifier by type -->
     <uses-permission android:name="android.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE"
         android:featureFlag="android.permission.flags.text_classifier_choice_api_enabled"/>
@@ -1009,6 +1015,9 @@
     <uses-permission android:name="android.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE" />
     <uses-permission android:name="android.permission.READ_COLOR_ZONES" />
 
+    <!-- Permission required for trade-in mode testing -->
+    <uses-permission android:name="android.permission.ENTER_TRADE_IN_MODE" />
+
     <application
         android:label="@string/app_label"
         android:theme="@android:style/Theme.DeviceDefault.DayNight"
diff --git a/packages/SoundPicker/res/values-gu/strings.xml b/packages/SoundPicker/res/values-gu/strings.xml
index 209769f..d809638 100644
--- a/packages/SoundPicker/res/values-gu/strings.xml
+++ b/packages/SoundPicker/res/values-gu/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="ringtone_default" msgid="798836092118824500">"ડિફોલ્ટ રિંગટોન"</string>
+    <string name="ringtone_default" msgid="798836092118824500">"ડિફૉલ્ટ રિંગટોન"</string>
     <string name="notification_sound_default" msgid="8133121186242636840">"ડિફૉલ્ટ નોટિફિકેશન સાઉન્ડ"</string>
     <string name="alarm_sound_default" msgid="4787646764557462649">"ડિફૉલ્ટ અલાર્મ સાઉન્ડ"</string>
     <string name="add_ringtone_text" msgid="6642389991738337529">"રિંગટોન ઉમેરો"</string>
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 0a7d880..744388f 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -314,6 +314,7 @@
         "tests/src/**/systemui/statusbar/policy/WalletControllerImplTest.kt",
         "tests/src/**/keyguard/ClockEventControllerTest.kt",
         "tests/src/**/systemui/bluetooth/qsdialog/BluetoothStateInteractorTest.kt",
+        "tests/src/**/systemui/bluetooth/qsdialog/BluetoothDetailsContentManagerTest.kt",
         "tests/src/**/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegateTest.kt",
         "tests/src/**/systemui/bluetooth/qsdialog/BluetoothTileDialogRepositoryTest.kt",
         "tests/src/**/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt",
@@ -424,7 +425,6 @@
     manifest: "AndroidManifest-res.xml",
     flags_packages: [
         "android.app.flags-aconfig",
-        "com_android_systemui_flags",
     ],
 }
 
diff --git a/packages/SystemUI/aconfig/accessibility.aconfig b/packages/SystemUI/aconfig/accessibility.aconfig
index fb21be4..3cb3025 100644
--- a/packages/SystemUI/aconfig/accessibility.aconfig
+++ b/packages/SystemUI/aconfig/accessibility.aconfig
@@ -120,6 +120,16 @@
 }
 
 flag {
+    name: "update_window_magnifier_bottom_boundary"
+    namespace: "accessibility"
+    description: "Update the window magnifier boundary at the bottom to the top of the system gesture inset."
+    bug: "380320995"
+    metadata {
+      purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
     name: "hearing_devices_dialog_related_tools"
     namespace: "accessibility"
     description: "Shows the related tools for hearing devices dialog."
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index bb0d5d7..ac53dcb 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -1697,13 +1697,6 @@
 }
 
 flag {
-   name: "magic_portrait_wallpapers"
-   namespace: "systemui"
-   description: "Magic Portrait related changes in systemui"
-   bug: "370863642"
-}
-
-flag {
   name: "notes_role_qs_tile"
   namespace: "systemui"
   description: "Enables notes role qs tile which opens default notes role app in app bubbles"
@@ -2020,3 +2013,10 @@
     description: "Show a Locked by your watch indicator on the keyguard when the device is locked by the watch."
     bug: "387322459"
 }
+
+flag {
+    name: "decouple_view_controller_in_animlib"
+    namespace: "systemui"
+    description: "Decouple view and controller in AnimLib."
+    bug: "393241010"
+}
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 c8d3430..f03bd3d 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
@@ -73,6 +73,9 @@
 import com.android.wm.shell.shared.TransitionUtil
 import java.util.concurrent.Executor
 import kotlin.math.roundToInt
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withTimeoutOrNull
 
 private const val TAG = "ActivityTransitionAnimator"
 
@@ -241,7 +244,7 @@
 
             override fun onTransitionAnimationProgress(linearProgress: Float) {
                 LinkedHashSet(listeners).forEach {
-                     it.onTransitionAnimationProgress(linearProgress)
+                    it.onTransitionAnimationProgress(linearProgress)
                 }
             }
 
@@ -494,15 +497,19 @@
 
     /**
      * Create a new animation [Runner] controlled by the [Controller] that [controllerFactory] can
-     * create based on [forLaunch].
+     * create based on [forLaunch] and within the given [scope].
      *
      * This method must only be used for long-lived registrations. Otherwise, use
      * [createEphemeralRunner].
      */
     @VisibleForTesting
-    fun createLongLivedRunner(controllerFactory: ControllerFactory, forLaunch: Boolean): Runner {
+    fun createLongLivedRunner(
+        controllerFactory: ControllerFactory,
+        scope: CoroutineScope,
+        forLaunch: Boolean,
+    ): Runner {
         assertLongLivedReturnAnimations()
-        return Runner(callback!!, transitionAnimator, lifecycleListener) {
+        return Runner(scope, callback!!, transitionAnimator, lifecycleListener) {
             controllerFactory.createController(forLaunch)
         }
     }
@@ -564,7 +571,7 @@
          * Creates a [Controller] for launching or returning from the activity linked to [cookie]
          * and [component].
          */
-        abstract fun createController(forLaunch: Boolean): Controller
+        abstract suspend fun createController(forLaunch: Boolean): Controller
     }
 
     /**
@@ -691,9 +698,14 @@
      * animations.
      *
      * The [Controller]s created by [controllerFactory] will only be used for transitions matching
-     * the [cookie], or the [ComponentName] defined within it if the cookie matching fails.
+     * the [cookie], or the [ComponentName] defined within it if the cookie matching fails. These
+     * [Controller]s can only be created within [scope].
      */
-    fun register(cookie: TransitionCookie, controllerFactory: ControllerFactory) {
+    fun register(
+        cookie: TransitionCookie,
+        controllerFactory: ControllerFactory,
+        scope: CoroutineScope,
+    ) {
         assertLongLivedReturnAnimations()
 
         if (transitionRegister == null) {
@@ -725,7 +737,7 @@
             }
         val launchRemoteTransition =
             RemoteTransition(
-                OriginTransition(createLongLivedRunner(controllerFactory, forLaunch = true)),
+                OriginTransition(createLongLivedRunner(controllerFactory, scope, forLaunch = true)),
                 "${cookie}_launchTransition",
             )
         transitionRegister.register(launchFilter, launchRemoteTransition, includeTakeover = true)
@@ -749,7 +761,9 @@
             }
         val returnRemoteTransition =
             RemoteTransition(
-                OriginTransition(createLongLivedRunner(controllerFactory, forLaunch = false)),
+                OriginTransition(
+                    createLongLivedRunner(controllerFactory, scope, forLaunch = false)
+                ),
                 "${cookie}_returnTransition",
             )
         transitionRegister.register(returnFilter, returnRemoteTransition, includeTakeover = true)
@@ -952,7 +966,9 @@
          * Reusable factory to generate single-use controllers. In case of an ephemeral [Runner],
          * this must be null and [controller] must be defined instead.
          */
-        private val controllerFactory: (() -> Controller)?,
+        private val controllerFactory: (suspend () -> Controller)?,
+        /** The scope to use when this runner is based on [controllerFactory]. */
+        private val scope: CoroutineScope? = null,
         private val callback: Callback,
         /** The animator to use to animate the window transition. */
         private val transitionAnimator: TransitionAnimator,
@@ -973,13 +989,15 @@
         )
 
         constructor(
+            scope: CoroutineScope,
             callback: Callback,
             transitionAnimator: TransitionAnimator,
             listener: Listener? = null,
-            controllerFactory: () -> Controller,
+            controllerFactory: suspend () -> Controller,
         ) : this(
             controller = null,
             controllerFactory = controllerFactory,
+            scope = scope,
             callback = callback,
             transitionAnimator = transitionAnimator,
             listener = listener,
@@ -994,12 +1012,12 @@
             assert((controller != null).xor(controllerFactory != null))
 
             delegate = null
-            if (controller != null) {
+            controller?.let {
                 // Ephemeral launches bundle the runner with the launch request (instead of being
                 // registered ahead of time for later use). This means that there could be a timeout
                 // between creation and invocation, so the delegate needs to exist from the
                 // beginning in order to handle such timeout.
-                createDelegate()
+                createDelegate(it)
             }
         }
 
@@ -1040,49 +1058,79 @@
             finishedCallback: IRemoteAnimationFinishedCallback?,
             performAnimation: (AnimationDelegate) -> Unit,
         ) {
-            maybeSetUp()
-            val delegate = delegate
-            mainExecutor.execute {
-                if (delegate == null) {
-                    Log.i(TAG, "onAnimationStart called after completion")
-                    // Animation started too late and timed out already. We need to still
-                    // signal back that we're done with it.
-                    finishedCallback?.onAnimationFinished()
-                } else {
-                    performAnimation(delegate)
+            val controller = controller
+            val controllerFactory = controllerFactory
+
+            if (controller != null) {
+                maybeSetUp(controller)
+                val success = startAnimation(performAnimation)
+                if (!success) finishedCallback?.onAnimationFinished()
+            } else if (controllerFactory != null) {
+                scope?.launch {
+                    val success =
+                        withTimeoutOrNull(TRANSITION_TIMEOUT) {
+                            setUp(controllerFactory)
+                            startAnimation(performAnimation)
+                        } ?: false
+                    if (!success) finishedCallback?.onAnimationFinished()
                 }
+            } else {
+                // This should never happen, as either the controller or factory should always be
+                // defined. This final call is for safety in case something goes wrong.
+                Log.wtf(TAG, "initAndRun with neither a controller nor factory")
+                finishedCallback?.onAnimationFinished()
+            }
+        }
+
+        /** Tries to start the animation on the main thread and returns whether it succeeded. */
+        @BinderThread
+        private fun startAnimation(performAnimation: (AnimationDelegate) -> Unit): Boolean {
+            val delegate = delegate
+            return if (delegate != null) {
+                mainExecutor.execute { performAnimation(delegate) }
+                true
+            } else {
+                // Animation started too late and timed out already.
+                Log.i(TAG, "startAnimation called after completion")
+                false
             }
         }
 
         @BinderThread
         override fun onAnimationCancelled() {
             val delegate = delegate
-            mainExecutor.execute {
-                delegate ?: Log.wtf(TAG, "onAnimationCancelled called after completion")
-                delegate?.onAnimationCancelled()
+            if (delegate != null) {
+                mainExecutor.execute { delegate.onAnimationCancelled() }
+            } else {
+                Log.wtf(TAG, "onAnimationCancelled called after completion")
             }
         }
 
+        /**
+         * Posts the default animation timeouts. Since this only applies to ephemeral launches, this
+         * method is a no-op if [controller] is not defined.
+         */
         @VisibleForTesting
         @UiThread
         fun postTimeouts() {
-            maybeSetUp()
+            controller?.let { maybeSetUp(it) }
             delegate?.postTimeouts()
         }
 
         @AnyThread
-        private fun maybeSetUp() {
-            if (controllerFactory == null || delegate != null) return
-            createDelegate()
+        private fun maybeSetUp(controller: Controller) {
+            if (delegate != null) return
+            createDelegate(controller)
         }
 
         @AnyThread
-        private fun createDelegate() {
-            var controller = controller
-            val factory = controllerFactory
-            if (controller == null && factory == null) return
+        private suspend fun setUp(createController: suspend () -> Controller) {
+            val controller = createController()
+            createDelegate(controller)
+        }
 
-            controller = controller ?: factory!!.invoke()
+        @AnyThread
+        private fun createDelegate(controller: Controller) {
             delegate =
                 AnimationDelegate(
                     mainExecutor,
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
index 103a9b5..c5d2802 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
@@ -319,7 +319,7 @@
 
             override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) {
                 delegate.onTransitionAnimationStart(isExpandingFullyAbove)
-                overlay.value = composeViewRoot.rootView.overlay as ViewGroupOverlay
+                overlay.value = transitionContainer.overlay as ViewGroupOverlay
                 cujType?.let { InteractionJankMonitor.getInstance().begin(composeViewRoot, it) }
             }
 
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
index 195b060..20f1cdf 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
@@ -296,13 +296,6 @@
 
         awaitEachGesture {
             val down = awaitFirstDown(requireUnconsumed = false)
-            check(down.position == lastFirstDown) {
-                "Position from detectDrags() is not the same as position in trackDownPosition()"
-            }
-            check(pointersDown.size == 1 && pointersDown.keys.first() == down.id) {
-                "pointersDown should only contain $down but it contains $pointersDown"
-            }
-
             var overSlop = 0f
             val onTouchSlopReached = { change: PointerInputChange, over: Float ->
                 if (draggable.shouldStartDrag(change)) {
@@ -342,7 +335,12 @@
 
                 check(pointersDown.size > 0) { "pointersDown is empty" }
                 val controller =
-                    draggable.onDragStarted(down.position, sign, pointersDown.size, drag.type)
+                    draggable.onDragStarted(
+                        down.position,
+                        sign,
+                        pointersDown.size.coerceAtLeast(1),
+                        drag.type,
+                    )
                 if (overSlop != 0f) {
                     onDrag(controller, drag, overSlop, velocityTracker)
                 }
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/gesture/effect/ContentOverscrollEffect.kt b/packages/SystemUI/compose/core/src/com/android/compose/gesture/effect/ContentOverscrollEffect.kt
index 49e5107..cb713ec 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/gesture/effect/ContentOverscrollEffect.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/gesture/effect/ContentOverscrollEffect.kt
@@ -18,6 +18,8 @@
 
 import androidx.compose.animation.core.Animatable
 import androidx.compose.animation.core.AnimationSpec
+import androidx.compose.animation.core.SpringSpec
+import androidx.compose.animation.core.spring
 import androidx.compose.foundation.OverscrollEffect
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.ui.geometry.Offset
@@ -46,7 +48,7 @@
     private val animationSpec: AnimationSpec<Float>,
 ) : ContentOverscrollEffect {
     /** The [Animatable] that holds the current overscroll value. */
-    private val animatable = Animatable(initialValue = 0f, visibilityThreshold = 0.5f)
+    private val animatable = Animatable(initialValue = 0f)
     private var lastConverter: SpaceVectorConverter? = null
 
     override val overscrollDistance: Float
@@ -131,11 +133,29 @@
             launch {
                 val consumed = performFling(velocity)
                 val remaining = velocity - consumed
-                animatable.animateTo(0f, animationSpec, remaining.toFloat())
+                animatable.animateTo(
+                    0f,
+                    animationSpec.withVisibilityThreshold(1f),
+                    remaining.toFloat(),
+                )
             }
         }
     }
 
+    private fun <T> AnimationSpec<T>.withVisibilityThreshold(
+        visibilityThreshold: T
+    ): AnimationSpec<T> {
+        return when (this) {
+            is SpringSpec ->
+                spring(
+                    stiffness = stiffness,
+                    dampingRatio = dampingRatio,
+                    visibilityThreshold = visibilityThreshold,
+                )
+            else -> this
+        }
+    }
+
     protected fun requireConverter(): SpaceVectorConverter {
         return checkNotNull(lastConverter) {
             "lastConverter is null, make sure to call requireConverter() only when " +
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/modifiers/MeasureTracing.kt b/packages/SystemUI/compose/core/src/com/android/compose/modifiers/MeasureTracing.kt
deleted file mode 100644
index 9ce6cd1..0000000
--- a/packages/SystemUI/compose/core/src/com/android/compose/modifiers/MeasureTracing.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.compose.modifiers
-
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.layout.layout
-import androidx.compose.ui.unit.IntOffset
-import com.android.app.tracing.traceSection
-
-/** Adds perfetto markers for the measure + layout stages. */
-inline fun Modifier.measureTracer(crossinline traceNameProducer: () -> String): Modifier {
-    return layout { measurable, constraints ->
-        traceSection(traceNameProducer) {
-            val placeable = measurable.measure(constraints)
-            layout(placeable.width, placeable.height) { placeable.placeRelative(IntOffset.Zero) }
-        }
-    }
-}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/ContentDescription.kt b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/ContentDescription.kt
index 4a5ad65..b254963 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/ContentDescription.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/ContentDescription.kt
@@ -17,11 +17,13 @@
 package com.android.systemui.common.ui.compose
 
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.ReadOnlyComposable
 import androidx.compose.ui.res.stringResource
 import com.android.systemui.common.shared.model.ContentDescription
 
 /** Returns the loaded [String] or `null` if there isn't one. */
 @Composable
+@ReadOnlyComposable
 fun ContentDescription.load(): String? {
     return when (this) {
         is ContentDescription.Loaded -> description
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/Icon.kt b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/Icon.kt
index 82d1436..8b0c005 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/Icon.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/Icon.kt
@@ -21,9 +21,8 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.asImageBitmap
 import androidx.compose.ui.res.painterResource
-import androidx.core.graphics.drawable.toBitmap
+import com.android.compose.ui.graphics.painter.rememberDrawablePainter
 import com.android.systemui.common.shared.model.Icon
 
 /**
@@ -36,7 +35,7 @@
     val contentDescription = icon.contentDescription?.load()
     when (icon) {
         is Icon.Loaded -> {
-            Icon(icon.drawable.toBitmap().asImageBitmap(), contentDescription, modifier, tint)
+            Icon(rememberDrawablePainter(icon.drawable), contentDescription, modifier, tint)
         }
         is Icon.Resource -> Icon(painterResource(icon.res), contentDescription, modifier, tint)
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/TextExt.kt b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/TextExt.kt
index 4e8121f..19adba0 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/TextExt.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/TextExt.kt
@@ -19,6 +19,7 @@
 
 import android.content.Context
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.ReadOnlyComposable
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.text.AnnotatedString
 import com.android.systemui.common.shared.model.Text
@@ -26,6 +27,7 @@
 
 /** Returns the loaded [String] or `null` if there isn't one. */
 @Composable
+@ReadOnlyComposable
 fun Text.load(): String? {
     return when (this) {
         is Text.Loaded -> text
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 3ffbabb..4a4607b 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
@@ -159,8 +159,7 @@
     content: CommunalContent,
 ) {
     val coroutineScope = rememberCoroutineScope()
-    val currentSceneKey: SceneKey by
-        viewModel.currentScene.collectAsStateWithLifecycle(CommunalScenes.Blank)
+    val currentSceneKey: SceneKey by viewModel.currentScene.collectAsStateWithLifecycle()
     val touchesAllowed by viewModel.touchesAllowed.collectAsStateWithLifecycle()
     val backgroundType by
         viewModel.communalBackground.collectAsStateWithLifecycle(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalToDreamButtonSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalToDreamButtonSection.kt
index 13d551a..a840a6f 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalToDreamButtonSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalToDreamButtonSection.kt
@@ -39,6 +39,7 @@
 import androidx.compose.ui.graphics.Path
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.res.dimensionResource
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.Dp
@@ -71,6 +72,8 @@
             return
         }
 
+        val buttonSize = dimensionResource(R.dimen.communal_to_dream_button_size)
+
         if (viewModel.shouldShowTooltip) {
             Column(
                 modifier =
@@ -96,7 +99,6 @@
     }
 
     companion object {
-        private val buttonSize = 64.dp
         private val tooltipMaxWidth = 350.dp
     }
 }
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 d341702..fa5e8ac 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
@@ -109,15 +109,22 @@
                             }
                             if (isShadeLayoutWide && !isBypassEnabled) {
                                 with(notificationSection) {
-                                    Notifications(
-                                        areNotificationsVisible = areNotificationsVisible,
-                                        isShadeLayoutWide = true,
-                                        burnInParams = null,
-                                        modifier =
-                                            Modifier.fillMaxWidth(0.5f)
-                                                .fillMaxHeight()
-                                                .align(alignment = Alignment.TopEnd),
-                                    )
+                                    Box(modifier = Modifier.fillMaxHeight()) {
+                                        AodPromotedNotificationArea(
+                                            modifier =
+                                                Modifier.fillMaxWidth(0.5f)
+                                                    .align(alignment = Alignment.TopStart)
+                                        )
+                                        Notifications(
+                                            areNotificationsVisible = areNotificationsVisible,
+                                            isShadeLayoutWide = true,
+                                            burnInParams = null,
+                                            modifier =
+                                                Modifier.fillMaxWidth(0.5f)
+                                                    .fillMaxHeight()
+                                                    .align(alignment = Alignment.TopEnd),
+                                        )
+                                    }
                                 }
                             }
                         }
@@ -142,9 +149,18 @@
                                 }
                             } else {
                                 Column {
-                                    AodPromotedNotificationArea()
+                                    if (!isShadeLayoutWide) {
+                                        AodPromotedNotificationArea()
+                                    }
                                     AodNotificationIcons(
-                                        modifier = Modifier.padding(start = aodIconPadding)
+                                        modifier =
+                                            Modifier.padding(
+                                                top =
+                                                    dimensionResource(
+                                                        R.dimen.keyguard_status_view_bottom_margin
+                                                    ),
+                                                start = aodIconPadding,
+                                            )
                                     )
                                 }
                             }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt
index 34c0bca..ae541dd 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt
@@ -26,8 +26,8 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.key
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.dimensionResource
 import androidx.compose.ui.viewinterop.AndroidView
 import androidx.core.view.contains
@@ -46,6 +46,28 @@
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
 import javax.inject.Inject
 
+@Composable
+fun ClockView(view: View?, modifier: Modifier = Modifier) {
+    AndroidView(
+        factory = {
+            FrameLayout(it).apply {
+                // Clip nothing. The clock views at times render outside their bounds. Compose does
+                // not clip by default, so only this layer needs clipping to be explicitly disabled.
+                clipChildren = false
+                clipToPadding = false
+            }
+        },
+        update = { parent ->
+            view?.let {
+                parent.removeAllViews()
+                (view.parent as? ViewGroup)?.removeView(view)
+                parent.addView(view)
+            } ?: run { parent.removeAllViews() }
+        },
+        modifier = modifier,
+    )
+}
+
 /** Provides small clock and large clock composables for the default clock face. */
 class DefaultClockSection
 @Inject
@@ -67,14 +89,9 @@
         if (currentClock?.smallClock?.view == null) {
             return
         }
-        val context = LocalContext.current
-        AndroidView(
-            factory = { context ->
-                FrameLayout(context).apply {
-                    ensureClockViewExists(checkNotNull(currentClock).smallClock.view)
-                }
-            },
-            update = { it.ensureClockViewExists(checkNotNull(currentClock).smallClock.view) },
+
+        ClockView(
+            checkNotNull(currentClock).smallClock.view,
             modifier =
                 modifier
                     .height(dimensionResource(R.dimen.small_clock_height))
@@ -116,25 +133,8 @@
 
         Element(key = largeClockElementKey, modifier = modifier) {
             content {
-                AndroidView(
-                    factory = { context ->
-                        FrameLayout(context).apply {
-                            // By default, ViewGroups like FrameLayout clip their children. Turning
-                            // off the clipping allows the child view to render outside of its
-                            // bounds - letting the step animation of the clock push the digits out
-                            // when needed.
-                            //
-                            // Note that, in Compose, clipping is actually disabled by default so
-                            // there's no need to propagate this up the composable hierarchy.
-                            clipChildren = false
-                            clipToPadding = false
-
-                            ensureClockViewExists(checkNotNull(currentClock).largeClock.view)
-                        }
-                    },
-                    update = {
-                        it.ensureClockViewExists(checkNotNull(currentClock).largeClock.view)
-                    },
+                ClockView(
+                    checkNotNull(currentClock).largeClock.view,
                     modifier =
                         Modifier.fillMaxSize()
                             .burnInAware(
@@ -147,15 +147,6 @@
         }
     }
 
-    private fun FrameLayout.ensureClockViewExists(clockView: View) {
-        if (contains(clockView)) {
-            return
-        }
-        removeAllViews()
-        (clockView.parent as? ViewGroup)?.removeView(clockView)
-        addView(clockView)
-    }
-
     fun getClockCenteringDistance(): Float {
         return Resources.getSystem().displayMetrics.widthPixels / 4f
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/WeatherClockSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/WeatherClockSection.kt
index 6250da3..4fcb5ca 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/WeatherClockSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/WeatherClockSection.kt
@@ -16,8 +16,6 @@
 
 package com.android.systemui.keyguard.ui.composable.section
 
-import android.view.View
-import android.view.ViewGroup
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.IntrinsicSize
 import androidx.compose.foundation.layout.Row
@@ -26,10 +24,10 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.key
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.res.dimensionResource
-import androidx.compose.ui.viewinterop.AndroidView
 import com.android.compose.animation.scene.ContentScope
 import com.android.compose.animation.scene.ElementKey
 import com.android.systemui.customization.R as customR
@@ -112,21 +110,11 @@
     ) {
         Element(key = elementKey, modifier) {
             content {
-                AndroidView(
-                    factory = {
-                        try {
-                            val view =
-                                clock.largeClock.layout.views.first {
-                                    it.id == weatherClockElementViewId
-                                }
-                            (view.parent as? ViewGroup)?.removeView(view)
-                            view
-                        } catch (e: NoSuchElementException) {
-                            View(it)
-                        }
+                ClockView(
+                    clock.largeClock.layout.views.firstOrNull {
+                        it.id == weatherClockElementViewId
                     },
-                    update = {},
-                    modifier = modifier,
+                    modifier,
                 )
             }
         }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt
index 9311347..7c50d6f 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt
@@ -29,7 +29,6 @@
 import com.android.compose.animation.scene.ElementKey
 import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
-import com.android.systemui.battery.BatteryMeterViewController
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
 import com.android.systemui.keyguard.ui.composable.blueprint.rememberBurnIn
@@ -44,10 +43,7 @@
 import com.android.systemui.shade.ui.composable.OverlayShade
 import com.android.systemui.shade.ui.composable.OverlayShadeHeader
 import com.android.systemui.shade.ui.composable.SingleShadeMeasurePolicy
-import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerStatusBarViewBinder
 import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
-import com.android.systemui.statusbar.phone.ui.StatusBarIconController
-import com.android.systemui.statusbar.phone.ui.TintedIconManager
 import dagger.Lazy
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
@@ -58,11 +54,6 @@
 constructor(
     private val actionsViewModelFactory: NotificationsShadeOverlayActionsViewModel.Factory,
     private val contentViewModelFactory: NotificationsShadeOverlayContentViewModel.Factory,
-    private val tintedIconManagerFactory: TintedIconManager.Factory,
-    private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory,
-    private val statusBarIconController: StatusBarIconController,
-    private val notificationIconContainerStatusBarViewBinder:
-        NotificationIconContainerStatusBarViewBinder,
     private val shadeSession: SaveableSession,
     private val stackScrollView: Lazy<NotificationScrollView>,
     private val clockSection: DefaultClockSection,
@@ -94,18 +85,17 @@
             }
 
         OverlayShade(
-            isShadeLayoutWide = viewModel.isShadeLayoutWide,
+            panelElement = NotificationsShade.Elements.Panel,
             panelAlignment = Alignment.TopStart,
             modifier = modifier,
             onScrimClicked = viewModel::onScrimClicked,
             header = {
+                val headerViewModel =
+                    rememberViewModel("NotificationsShadeOverlayHeader") {
+                        viewModel.shadeHeaderViewModelFactory.create()
+                    }
                 OverlayShadeHeader(
-                    viewModelFactory = viewModel.shadeHeaderViewModelFactory,
-                    createTintedIconManager = tintedIconManagerFactory::create,
-                    createBatteryMeterViewController = batteryMeterViewControllerFactory::create,
-                    statusBarIconController = statusBarIconController,
-                    notificationIconContainerStatusBarViewBinder =
-                        notificationIconContainerStatusBarViewBinder,
+                    viewModel = headerViewModel,
                     modifier =
                         Modifier.element(NotificationsShade.Elements.StatusBar)
                             .layoutId(SingleShadeMeasurePolicy.LayoutId.ShadeHeader),
@@ -114,7 +104,7 @@
         ) {
             Box {
                 Column {
-                    if (viewModel.showHeader) {
+                    if (viewModel.showClock) {
                         val burnIn = rememberBurnIn(clockInteractor)
 
                         with(clockSection) {
@@ -140,8 +130,7 @@
                         modifier = Modifier.fillMaxWidth(),
                     )
                 }
-                // Communicates the bottom position of the drawable area within the shade to
-                // NSSL.
+                // Communicates the bottom position of the drawable area within the shade to NSSL.
                 NotificationStackCutoffGuideline(
                     stackScrollView = stackScrollView.get(),
                     viewModel = placeholderViewModel,
@@ -156,6 +145,7 @@
 
 object NotificationsShade {
     object Elements {
-        val StatusBar = ElementKey("NotificationsShadeStatusBar")
+        val Panel = ElementKey("NotificationsShadeOverlayPanel")
+        val StatusBar = ElementKey("NotificationsShadeOverlayStatusBar")
     }
 }
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 4bfbb3a..62a8cc5 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
@@ -16,7 +16,6 @@
 
 package com.android.systemui.qs.ui.composable
 
-import android.view.ViewGroup
 import androidx.activity.compose.BackHandler
 import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.animation.core.animateDpAsState
@@ -76,7 +75,6 @@
 import com.android.compose.animation.scene.content.state.TransitionState
 import com.android.compose.modifiers.thenIf
 import com.android.compose.windowsizeclass.LocalWindowSizeClass
-import com.android.systemui.battery.BatteryMeterViewController
 import com.android.systemui.common.ui.compose.windowinsets.CutoutLocation
 import com.android.systemui.common.ui.compose.windowinsets.LocalDisplayCutout
 import com.android.systemui.compose.modifiers.sysuiResTag
@@ -100,15 +98,14 @@
 import com.android.systemui.scene.session.ui.composable.SaveableSession
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.composable.Scene
+import com.android.systemui.settings.brightness.ui.viewModel.BrightnessMirrorViewModel
 import com.android.systemui.shade.ui.composable.CollapsedShadeHeader
 import com.android.systemui.shade.ui.composable.ExpandedShadeHeader
 import com.android.systemui.shade.ui.composable.Shade
 import com.android.systemui.shade.ui.composable.ShadeHeader
+import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel
 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
 import dagger.Lazy
 import javax.inject.Inject
 import javax.inject.Named
@@ -125,9 +122,6 @@
     private val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory,
     private val actionsViewModelFactory: QuickSettingsUserActionsViewModel.Factory,
     private val contentViewModelFactory: QuickSettingsSceneContentViewModel.Factory,
-    private val tintedIconManagerFactory: TintedIconManager.Factory,
-    private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory,
-    private val statusBarIconController: StatusBarIconController,
     private val mediaCarouselController: MediaCarouselController,
     @Named(MediaModule.QS_PANEL) private val mediaHost: MediaHost,
 ) : ExclusiveActivatable(), Scene {
@@ -145,16 +139,26 @@
 
     @Composable
     override fun ContentScope.Content(modifier: Modifier) {
+        val viewModel =
+            rememberViewModel("QuickSettingsScene-viewModel") { contentViewModelFactory.create() }
+        val headerViewModel =
+            rememberViewModel("QuickSettingsScene-headerViewModel") {
+                viewModel.shadeHeaderViewModelFactory.create()
+            }
+        val brightnessMirrorViewModel =
+            rememberViewModel("QuickSettingsScene-brightnessMirrorViewModel") {
+                viewModel.brightnessMirrorViewModelFactory.create()
+            }
+        val notificationsPlaceholderViewModel =
+            rememberViewModel("QuickSettingsScene-notifPlaceholderViewModel") {
+                notificationsPlaceholderViewModelFactory.create()
+            }
         QuickSettingsScene(
             notificationStackScrollView = notificationStackScrollView.get(),
-            viewModelFactory = contentViewModelFactory,
-            notificationsPlaceholderViewModel =
-                rememberViewModel("QuickSettingsScene-notifPlaceholderViewModel") {
-                    notificationsPlaceholderViewModelFactory.create()
-                },
-            createTintedIconManager = tintedIconManagerFactory::create,
-            createBatteryMeterViewController = batteryMeterViewControllerFactory::create,
-            statusBarIconController = statusBarIconController,
+            viewModel = viewModel,
+            headerViewModel = headerViewModel,
+            brightnessMirrorViewModel = brightnessMirrorViewModel,
+            notificationsPlaceholderViewModel = notificationsPlaceholderViewModel,
             mediaCarouselController = mediaCarouselController,
             mediaHost = mediaHost,
             modifier = modifier,
@@ -166,23 +170,16 @@
 @Composable
 private fun ContentScope.QuickSettingsScene(
     notificationStackScrollView: NotificationScrollView,
-    viewModelFactory: QuickSettingsSceneContentViewModel.Factory,
+    viewModel: QuickSettingsSceneContentViewModel,
+    headerViewModel: ShadeHeaderViewModel,
+    brightnessMirrorViewModel: BrightnessMirrorViewModel,
     notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel,
-    createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
-    createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
-    statusBarIconController: StatusBarIconController,
     mediaCarouselController: MediaCarouselController,
     mediaHost: MediaHost,
     modifier: Modifier = Modifier,
     shadeSession: SaveableSession,
 ) {
     val cutoutLocation = LocalDisplayCutout.current.location
-
-    val viewModel = rememberViewModel("QuickSettingsScene-viewModel") { viewModelFactory.create() }
-    val brightnessMirrorViewModel =
-        rememberViewModel("QuickSettingsScene-brightnessMirrorViewModel") {
-            viewModel.brightnessMirrorViewModelFactory.create()
-        }
     val brightnessMirrorShowing by brightnessMirrorViewModel.isShowing.collectAsStateWithLifecycle()
     val contentAlpha by
         animateFloatAsState(
@@ -222,8 +219,7 @@
                 .graphicsLayer { alpha = contentAlpha }
                 .thenIf(shouldPunchHoleBehindScrim) {
                     // Render the scene to an offscreen buffer so that BlendMode.DstOut only clears
-                    // this
-                    // scene (and not the one under it) during a scene transition.
+                    // this scene (and not the one under it) during a scene transition.
                     Modifier.graphicsLayer(compositingStrategy = CompositingStrategy.Offscreen)
                 }
                 .thenIf(cutoutLocation != CutoutLocation.CENTER) { Modifier.displayCutoutPadding() }
@@ -348,21 +344,11 @@
                                         fadeOut(tween(customizingAnimationDuration)),
                             ) {
                                 ExpandedShadeHeader(
-                                    viewModelFactory = viewModel.shadeHeaderViewModelFactory,
-                                    createTintedIconManager = createTintedIconManager,
-                                    createBatteryMeterViewController =
-                                        createBatteryMeterViewController,
-                                    statusBarIconController = statusBarIconController,
+                                    viewModel = headerViewModel,
                                     modifier = Modifier.padding(horizontal = 16.dp),
                                 )
                             }
-                        else ->
-                            CollapsedShadeHeader(
-                                viewModelFactory = viewModel.shadeHeaderViewModelFactory,
-                                createTintedIconManager = createTintedIconManager,
-                                createBatteryMeterViewController = createBatteryMeterViewController,
-                                statusBarIconController = statusBarIconController,
-                            )
+                        else -> CollapsedShadeHeader(viewModel = headerViewModel)
                     }
                     Spacer(modifier = Modifier.height(16.dp))
                     // This view has its own horizontal padding
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
index 3ec14a2..818d8e2 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
@@ -43,14 +43,13 @@
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.compose.animation.scene.ContentScope
+import com.android.compose.animation.scene.ElementKey
 import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
-import com.android.systemui.battery.BatteryMeterViewController
 import com.android.systemui.brightness.ui.compose.BrightnessSliderContainer
 import com.android.systemui.compose.modifiers.sysuiResTag
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.lifecycle.rememberViewModel
-import com.android.systemui.notifications.ui.composable.NotificationsShade
 import com.android.systemui.notifications.ui.composable.SnoozeableHeadsUpNotificationSpace
 import com.android.systemui.qs.composefragment.ui.GridAnchor
 import com.android.systemui.qs.flags.QsDetailedView
@@ -67,13 +66,10 @@
 import com.android.systemui.shade.ui.composable.OverlayShadeHeader
 import com.android.systemui.shade.ui.composable.QuickSettingsOverlayHeader
 import com.android.systemui.shade.ui.composable.SingleShadeMeasurePolicy
-import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerStatusBarViewBinder
 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.view.NotificationScrollView
 import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
-import com.android.systemui.statusbar.phone.ui.StatusBarIconController
-import com.android.systemui.statusbar.phone.ui.TintedIconManager
 import dagger.Lazy
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
@@ -84,11 +80,7 @@
 constructor(
     private val actionsViewModelFactory: QuickSettingsShadeOverlayActionsViewModel.Factory,
     private val contentViewModelFactory: QuickSettingsShadeOverlayContentViewModel.Factory,
-    private val tintedIconManagerFactory: TintedIconManager.Factory,
-    private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory,
-    private val statusBarIconController: StatusBarIconController,
-    private val notificationIconContainerStatusBarViewBinder:
-        NotificationIconContainerStatusBarViewBinder,
+    private val quickSettingsContainerViewModelFactory: QuickSettingsContainerViewModel.Factory,
     private val notificationStackScrollView: Lazy<NotificationScrollView>,
     private val notificationsPlaceholderViewModelFactory: NotificationsPlaceholderViewModel.Factory,
 ) : Overlay {
@@ -107,43 +99,44 @@
 
     @Composable
     override fun ContentScope.Content(modifier: Modifier) {
-        val viewModel =
-            rememberViewModel("QuickSettingsShadeOverlay") { contentViewModelFactory.create() }
+        val contentViewModel =
+            rememberViewModel("QuickSettingsShadeOverlayContent") {
+                contentViewModelFactory.create()
+            }
+        val quickSettingsContainerViewModel =
+            rememberViewModel("QuickSettingsShadeOverlayContainer") {
+                // TODO(b/393054014): Add support for brightness mirroring.
+                quickSettingsContainerViewModelFactory.create(supportsBrightnessMirroring = false)
+            }
         val panelCornerRadius =
             with(LocalDensity.current) { OverlayShade.Dimensions.PanelCornerRadius.toPx().toInt() }
 
-        // set the bounds to null when the QuickSettings overlay disappears
-        DisposableEffect(Unit) { onDispose { viewModel.onPanelShapeChanged(null) } }
+        // Set the bounds to null when the QuickSettings overlay disappears.
+        DisposableEffect(Unit) { onDispose { contentViewModel.onPanelShapeChanged(null) } }
 
         Box(modifier = modifier) {
             SnoozeableHeadsUpNotificationSpace(
                 stackScrollView = notificationStackScrollView.get(),
                 viewModel =
-                    rememberViewModel("QuickSettingsShadeOverlay") {
+                    rememberViewModel("QuickSettingsShadeOverlayPlaceholder") {
                         notificationsPlaceholderViewModelFactory.create()
                     },
             )
             OverlayShade(
-                isShadeLayoutWide = viewModel.isShadeLayoutWide,
+                panelElement = QuickSettingsShade.Elements.Panel,
                 panelAlignment = Alignment.TopEnd,
-                onScrimClicked = viewModel::onScrimClicked,
+                onScrimClicked = contentViewModel::onScrimClicked,
                 header = {
                     OverlayShadeHeader(
-                        viewModelFactory = viewModel.shadeHeaderViewModelFactory,
-                        createTintedIconManager = tintedIconManagerFactory::create,
-                        createBatteryMeterViewController =
-                            batteryMeterViewControllerFactory::create,
-                        statusBarIconController = statusBarIconController,
-                        notificationIconContainerStatusBarViewBinder =
-                            notificationIconContainerStatusBarViewBinder,
+                        viewModel = quickSettingsContainerViewModel.shadeHeaderViewModel,
                         modifier =
-                            Modifier.element(NotificationsShade.Elements.StatusBar)
+                            Modifier.element(QuickSettingsShade.Elements.StatusBar)
                                 .layoutId(SingleShadeMeasurePolicy.LayoutId.ShadeHeader),
                     )
                 },
             ) {
                 ShadeBody(
-                    viewModel = viewModel.quickSettingsContainerViewModel,
+                    viewModel = quickSettingsContainerViewModel,
                     modifier =
                         Modifier.onPlaced { coordinates ->
                             val boundsInWindow = coordinates.boundsInWindow()
@@ -160,16 +153,15 @@
                                     topRadius = 0,
                                     bottomRadius = panelCornerRadius,
                                 )
-                            viewModel.onPanelShapeChanged(shape)
+                            contentViewModel.onPanelShapeChanged(shape)
                         },
                     header = {
-                        if (viewModel.isShadeLayoutWide) {
+                        if (quickSettingsContainerViewModel.showHeader) {
                             QuickSettingsOverlayHeader(
-                                viewModelFactory = viewModel.shadeHeaderViewModelFactory,
-                                createBatteryMeterViewController =
-                                    batteryMeterViewControllerFactory::create,
+                                viewModel = quickSettingsContainerViewModel.shadeHeaderViewModel,
                                 modifier =
-                                    Modifier.padding(top = QuickSettingsShade.Dimensions.Padding),
+                                    Modifier.element(QuickSettingsShade.Elements.Header)
+                                        .padding(top = QuickSettingsShade.Dimensions.Padding),
                             )
                         }
                     },
@@ -277,6 +269,11 @@
 }
 
 object QuickSettingsShade {
+    object Elements {
+        val StatusBar = ElementKey("QuickSettingsShadeOverlayStatusBar")
+        val Panel = ElementKey("QuickSettingsShadeOverlayPanel")
+        val Header = ElementKey("QuickSettingsShadeOverlayHeader")
+    }
 
     object Dimensions {
         val Padding = 16.dp
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/ribbon/ui/composable/Ribbon.kt b/packages/SystemUI/compose/features/src/com/android/systemui/ribbon/ui/composable/Ribbon.kt
index daa1592..377bebc 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/ribbon/ui/composable/Ribbon.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/ribbon/ui/composable/Ribbon.kt
@@ -20,8 +20,12 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.drawWithCache
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorFilter
+import androidx.compose.ui.graphics.ColorMatrix
 import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.graphics.layer.drawLayer
 import androidx.compose.ui.layout.layout
 import com.android.compose.modifiers.thenIf
 import kotlin.math.PI
@@ -39,6 +43,9 @@
  * The background color of the strip can be modified by passing a value to the [backgroundColor] or
  * `null` to remove the strip background.
  *
+ * The [colorSaturation] is a function that returns that amount of color saturation to apply to the
+ * entire ribbon. If it's `1`, the full color will be used, if it's `0` it will be greyscale.
+ *
  * Note: this function assumes that it's been placed at the bottom right of its parent by its
  * caller. It's the caller's responsibility to meet that assumption by actually placing this
  * composable element at the bottom right.
@@ -49,6 +56,7 @@
     modifier: Modifier = Modifier,
     degrees: Int = 45,
     alpha: Float = 0.6f,
+    colorSaturation: () -> Float = { 1f },
     backgroundColor: Color? = Color.Red,
 ) {
     check(degrees in 1..89)
@@ -73,6 +81,22 @@
                     translationY = (h - w * sine + h * cosine) / 2f
                     rotationZ = 360f - degrees
                 }
+                .drawWithCache {
+                    val layer =
+                        obtainGraphicsLayer().apply {
+                            record {
+                                colorFilter =
+                                    ColorFilter.colorMatrix(
+                                        colorMatrix =
+                                            ColorMatrix().apply {
+                                                setToSaturation(colorSaturation())
+                                            }
+                                    )
+                                drawContent()
+                            }
+                        }
+                    onDrawWithContent { drawLayer(layer) }
+                }
                 .thenIf(backgroundColor != null) { Modifier.background(backgroundColor!!) }
                 .layout { measurable, constraints ->
                     val placeable = measurable.measure(constraints)
@@ -87,6 +111,6 @@
                     ) {
                         placeable.place(leftPadding, 0)
                     }
-                }
+                },
     )
 }
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 6c0c5c7..da4e582 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,13 +34,13 @@
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalHapticFeedback
 import androidx.compose.ui.platform.LocalView
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.compose.animation.scene.ContentKey
 import com.android.compose.animation.scene.OverlayKey
 import com.android.compose.animation.scene.SceneKey
 import com.android.compose.animation.scene.SceneTransitionLayout
-import com.android.compose.animation.scene.SceneTransitions
 import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
 import com.android.compose.animation.scene.observableTransitionState
@@ -85,7 +85,7 @@
     sceneByKey: Map<SceneKey, Scene>,
     overlayByKey: Map<OverlayKey, Overlay>,
     initialSceneKey: SceneKey,
-    sceneTransitions: SceneTransitions,
+    transitionsBuilder: SceneContainerTransitionsBuilder,
     dataSourceDelegator: SceneDataSourceDelegator,
     qsSceneAdapter: Provider<QSSceneAdapter>,
     sceneJankMonitorFactory: SceneJankMonitor.Factory,
@@ -97,6 +97,12 @@
     val sceneJankMonitor =
         rememberActivated(traceName = "sceneJankMonitor") { sceneJankMonitorFactory.create() }
 
+    val hapticFeedback = LocalHapticFeedback.current
+    val sceneTransitions =
+        remember(hapticFeedback) {
+            transitionsBuilder.build(viewModel.hapticsViewModel.getRevealHaptics(hapticFeedback))
+        }
+
     val state =
         rememberMutableSceneTransitionLayoutState(
             initialScene = initialSceneKey,
@@ -161,7 +167,7 @@
         if (isFullWidthShade()) stretchOverscrollEffectFactory else offsetOverscrollEffectFactory
 
     // Inflate qsView here so that shade has the correct qqs height in the first measure pass after
-    // rebooting
+    // rebooting.
     if (
         viewModel.allContentKeys.contains(Scenes.QuickSettings) ||
             viewModel.allContentKeys.contains(Scenes.Shade)
@@ -232,6 +238,7 @@
 
         BottomRightCornerRibbon(
             content = { Text(text = "flexi\uD83E\uDD43", color = Color.White) },
+            colorSaturation = { viewModel.ribbonColorSaturation },
             modifier = Modifier.align(Alignment.BottomEnd),
         )
     }
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 2255677..2ad9b7a 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,6 +1,8 @@
 package com.android.systemui.scene.ui.composable
 
+import com.android.compose.animation.scene.SceneTransitions
 import com.android.compose.animation.scene.TransitionKey
+import com.android.compose.animation.scene.reveal.ContainerRevealHaptics
 import com.android.compose.animation.scene.transitions
 import com.android.internal.jank.Cuj
 import com.android.systemui.notifications.ui.composable.Notifications
@@ -32,7 +34,7 @@
 import com.android.systemui.shade.ui.composable.Shade
 
 /**
- * Comprehensive definition of all transitions between scenes in [SceneContainer].
+ * Comprehensive definition of all transitions between scenes and overlays in [SceneContainer].
  *
  * Transitions are automatically reversible, so define only one transition per scene pair. By\
  * convention, use the more common transition direction when defining the pair order, e.g.
@@ -43,163 +45,199 @@
  *
  * Please keep the list sorted alphabetically.
  */
-val SceneContainerTransitions = transitions {
-    interruptionHandler = SceneContainerInterruptionHandler
+class SceneContainerTransitions : SceneContainerTransitionsBuilder {
+    override fun build(revealHaptics: ContainerRevealHaptics): SceneTransitions {
+        return transitions {
+            interruptionHandler = SceneContainerInterruptionHandler
 
-    // Scene transitions
+            // Scene transitions
 
-    from(Scenes.Bouncer, to = Scenes.Gone) { bouncerToGoneTransition() }
-    from(Scenes.Dream, to = Scenes.Bouncer) { dreamToBouncerTransition() }
-    from(Scenes.Dream, to = Scenes.Communal) { dreamToCommunalTransition() }
-    from(Scenes.Dream, to = Scenes.Gone) { dreamToGoneTransition() }
-    from(Scenes.Dream, to = Scenes.Shade, cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE) {
-        dreamToShadeTransition()
-    }
-    from(Scenes.Gone, to = Scenes.Shade, cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE) {
-        goneToShadeTransition()
-    }
-    from(
-        Scenes.Gone,
-        to = Scenes.Shade,
-        key = ToSplitShade,
-        cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE,
-    ) {
-        goneToSplitShadeTransition()
-    }
-    from(
-        Scenes.Gone,
-        to = Scenes.Shade,
-        key = SlightlyFasterShadeCollapse,
-        cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE,
-    ) {
-        goneToShadeTransition(durationScale = 0.9)
-    }
-    from(
-        Scenes.Gone,
-        to = Scenes.QuickSettings,
-        cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE,
-    ) {
-        goneToQuickSettingsTransition()
-    }
-    from(
-        Scenes.Gone,
-        to = Scenes.QuickSettings,
-        key = SlightlyFasterShadeCollapse,
-        cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE,
-    ) {
-        goneToQuickSettingsTransition(durationScale = 0.9)
-    }
+            from(Scenes.Bouncer, to = Scenes.Gone) { bouncerToGoneTransition() }
+            from(Scenes.Dream, to = Scenes.Bouncer) { dreamToBouncerTransition() }
+            from(Scenes.Dream, to = Scenes.Communal) { dreamToCommunalTransition() }
+            from(Scenes.Dream, to = Scenes.Gone) { dreamToGoneTransition() }
+            from(
+                Scenes.Dream,
+                to = Scenes.Shade,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                dreamToShadeTransition()
+            }
+            from(
+                Scenes.Gone,
+                to = Scenes.Shade,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                goneToShadeTransition()
+            }
+            from(
+                Scenes.Gone,
+                to = Scenes.Shade,
+                key = ToSplitShade,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                goneToSplitShadeTransition()
+            }
+            from(
+                Scenes.Gone,
+                to = Scenes.Shade,
+                key = SlightlyFasterShadeCollapse,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                goneToShadeTransition(durationScale = 0.9)
+            }
+            from(
+                Scenes.Gone,
+                to = Scenes.QuickSettings,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                goneToQuickSettingsTransition()
+            }
+            from(
+                Scenes.Gone,
+                to = Scenes.QuickSettings,
+                key = SlightlyFasterShadeCollapse,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                goneToQuickSettingsTransition(durationScale = 0.9)
+            }
 
-    from(Scenes.Lockscreen, to = Scenes.Bouncer) { lockscreenToBouncerTransition() }
-    from(
-        Scenes.Lockscreen,
-        to = Scenes.Bouncer,
-        key = TransitionKey.PredictiveBack,
-        reversePreview = { bouncerToLockscreenPreview() },
-    ) {
-        lockscreenToBouncerTransition()
-    }
-    from(Scenes.Lockscreen, to = Scenes.Communal) { lockscreenToCommunalTransition() }
-    from(Scenes.Lockscreen, to = Scenes.Dream) { lockscreenToDreamTransition() }
-    from(Scenes.Lockscreen, to = Scenes.Shade, cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE) {
-        lockscreenToShadeTransition()
-    }
-    from(
-        Scenes.Lockscreen,
-        to = Scenes.Shade,
-        key = ToSplitShade,
-        cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE,
-    ) {
-        lockscreenToSplitShadeTransition()
-        sharedElement(Shade.Elements.BackgroundScrim, enabled = false)
-    }
-    from(
-        Scenes.Lockscreen,
-        to = Scenes.Shade,
-        key = SlightlyFasterShadeCollapse,
-        cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE,
-    ) {
-        lockscreenToShadeTransition(durationScale = 0.9)
-    }
-    from(
-        Scenes.Lockscreen,
-        to = Scenes.QuickSettings,
-        cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE,
-    ) {
-        lockscreenToQuickSettingsTransition()
-    }
-    from(Scenes.Lockscreen, to = Scenes.Gone) { lockscreenToGoneTransition() }
-    from(
-        Scenes.QuickSettings,
-        to = Scenes.Shade,
-        cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE,
-    ) {
-        reversed { shadeToQuickSettingsTransition() }
-        sharedElement(Notifications.Elements.HeadsUpNotificationPlaceholder, enabled = false)
-    }
-    from(
-        Scenes.Shade,
-        to = Scenes.QuickSettings,
-        cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE,
-    ) {
-        shadeToQuickSettingsTransition()
-    }
-    from(Scenes.Shade, to = Scenes.Lockscreen, cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE) {
-        reversed { lockscreenToShadeTransition() }
-        sharedElement(Notifications.Elements.NotificationStackPlaceholder, enabled = false)
-        sharedElement(Notifications.Elements.HeadsUpNotificationPlaceholder, enabled = false)
-    }
-    from(
-        Scenes.Shade,
-        to = Scenes.Lockscreen,
-        key = ToSplitShade,
-        cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE,
-    ) {
-        reversed { lockscreenToSplitShadeTransition() }
-    }
-    from(Scenes.Communal, to = Scenes.Shade, cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE) {
-        communalToShadeTransition()
-    }
-    from(Scenes.Communal, to = Scenes.Bouncer) { communalToBouncerTransition() }
+            from(Scenes.Lockscreen, to = Scenes.Bouncer) { lockscreenToBouncerTransition() }
+            from(
+                Scenes.Lockscreen,
+                to = Scenes.Bouncer,
+                key = TransitionKey.PredictiveBack,
+                reversePreview = { bouncerToLockscreenPreview() },
+            ) {
+                lockscreenToBouncerTransition()
+            }
+            from(Scenes.Lockscreen, to = Scenes.Communal) { lockscreenToCommunalTransition() }
+            from(Scenes.Lockscreen, to = Scenes.Dream) { lockscreenToDreamTransition() }
+            from(
+                Scenes.Lockscreen,
+                to = Scenes.Shade,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                lockscreenToShadeTransition()
+            }
+            from(
+                Scenes.Lockscreen,
+                to = Scenes.Shade,
+                key = ToSplitShade,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                lockscreenToSplitShadeTransition()
+                sharedElement(Shade.Elements.BackgroundScrim, enabled = false)
+            }
+            from(
+                Scenes.Lockscreen,
+                to = Scenes.Shade,
+                key = SlightlyFasterShadeCollapse,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                lockscreenToShadeTransition(durationScale = 0.9)
+            }
+            from(
+                Scenes.Lockscreen,
+                to = Scenes.QuickSettings,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                lockscreenToQuickSettingsTransition()
+            }
+            from(Scenes.Lockscreen, to = Scenes.Gone) { lockscreenToGoneTransition() }
+            from(
+                Scenes.QuickSettings,
+                to = Scenes.Shade,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                reversed { shadeToQuickSettingsTransition() }
+                sharedElement(
+                    Notifications.Elements.HeadsUpNotificationPlaceholder,
+                    enabled = false,
+                )
+            }
+            from(
+                Scenes.Shade,
+                to = Scenes.QuickSettings,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                shadeToQuickSettingsTransition()
+            }
+            from(
+                Scenes.Shade,
+                to = Scenes.Lockscreen,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                reversed { lockscreenToShadeTransition() }
+                sharedElement(Notifications.Elements.NotificationStackPlaceholder, enabled = false)
+                sharedElement(
+                    Notifications.Elements.HeadsUpNotificationPlaceholder,
+                    enabled = false,
+                )
+            }
+            from(
+                Scenes.Shade,
+                to = Scenes.Lockscreen,
+                key = ToSplitShade,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                reversed { lockscreenToSplitShadeTransition() }
+            }
+            from(
+                Scenes.Communal,
+                to = Scenes.Shade,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                communalToShadeTransition()
+            }
+            from(Scenes.Communal, to = Scenes.Bouncer) { communalToBouncerTransition() }
 
-    // Overlay transitions
+            // Overlay transitions
 
-    to(Overlays.NotificationsShade, cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE) {
-        toNotificationsShadeTransition()
-    }
-    to(Overlays.QuickSettingsShade, cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE) {
-        toQuickSettingsShadeTransition()
-    }
-    from(
-        Scenes.Gone,
-        to = Overlays.NotificationsShade,
-        key = SlightlyFasterShadeCollapse,
-        cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE,
-    ) {
-        toNotificationsShadeTransition(durationScale = 0.9)
-    }
-    from(
-        Scenes.Gone,
-        to = Overlays.QuickSettingsShade,
-        key = SlightlyFasterShadeCollapse,
-        cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE,
-    ) {
-        toQuickSettingsShadeTransition(durationScale = 0.9)
-    }
-    from(
-        Scenes.Lockscreen,
-        to = Overlays.NotificationsShade,
-        key = SlightlyFasterShadeCollapse,
-        cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE,
-    ) {
-        toNotificationsShadeTransition(durationScale = 0.9)
-    }
-    from(
-        Scenes.Lockscreen,
-        to = Overlays.QuickSettingsShade,
-        key = SlightlyFasterShadeCollapse,
-        cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE,
-    ) {
-        toQuickSettingsShadeTransition(durationScale = 0.9)
+            to(
+                Overlays.NotificationsShade,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                toNotificationsShadeTransition(revealHaptics = revealHaptics)
+            }
+            to(
+                Overlays.QuickSettingsShade,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                toQuickSettingsShadeTransition(revealHaptics = revealHaptics)
+            }
+            from(
+                Scenes.Gone,
+                to = Overlays.NotificationsShade,
+                key = SlightlyFasterShadeCollapse,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                toNotificationsShadeTransition(durationScale = 0.9, revealHaptics = revealHaptics)
+            }
+            from(
+                Scenes.Gone,
+                to = Overlays.QuickSettingsShade,
+                key = SlightlyFasterShadeCollapse,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                toQuickSettingsShadeTransition(durationScale = 0.9, revealHaptics = revealHaptics)
+            }
+            from(
+                Scenes.Lockscreen,
+                to = Overlays.NotificationsShade,
+                key = SlightlyFasterShadeCollapse,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                toNotificationsShadeTransition(durationScale = 0.9, revealHaptics = revealHaptics)
+            }
+            from(
+                Scenes.Lockscreen,
+                to = Overlays.QuickSettingsShade,
+                key = SlightlyFasterShadeCollapse,
+                cuj = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE, // NOTYPO
+            ) {
+                toQuickSettingsShadeTransition(durationScale = 0.9, revealHaptics = revealHaptics)
+            }
+        }
     }
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitionsBuilder.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitionsBuilder.kt
new file mode 100644
index 0000000..13d3456
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitionsBuilder.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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.ui.composable
+
+import com.android.compose.animation.scene.SceneTransitions
+import com.android.compose.animation.scene.reveal.ContainerRevealHaptics
+import com.android.compose.animation.scene.transitions
+
+/**
+ * Builder of the comprehensive definition of all transitions between scenes and overlays in the
+ * scene container.
+ */
+interface SceneContainerTransitionsBuilder {
+
+    /** Build the [SceneContainer] transitions spec. */
+    fun build(revealHaptics: ContainerRevealHaptics): SceneTransitions
+}
+
+/**
+ * Implementation of [SceneContainerTransitionsBuilder] that returns a constant [SceneTransitions]
+ * instance, ignoring any parameters passed to [build].
+ */
+class ConstantSceneContainerTransitionsBuilder(
+    private val transitions: SceneTransitions = transitions { /* No transitions */ }
+) : SceneContainerTransitionsBuilder {
+    override fun build(revealHaptics: ContainerRevealHaptics): SceneTransitions = transitions
+}
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 73b0750..9762414 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
@@ -17,16 +17,18 @@
 package com.android.systemui.scene.ui.composable.transitions
 
 import androidx.compose.animation.core.tween
-import com.android.compose.animation.scene.Edge
 import com.android.compose.animation.scene.TransitionBuilder
+import com.android.compose.animation.scene.reveal.ContainerRevealHaptics
+import com.android.compose.animation.scene.reveal.verticalContainerReveal
 import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys
-import com.android.systemui.notifications.ui.composable.Notifications
 import com.android.systemui.notifications.ui.composable.NotificationsShade
 import com.android.systemui.scene.shared.model.Overlays
-import com.android.systemui.shade.ui.composable.OverlayShade
 import kotlin.time.Duration.Companion.milliseconds
 
-fun TransitionBuilder.toNotificationsShadeTransition(durationScale: Double = 1.0) {
+fun TransitionBuilder.toNotificationsShadeTransition(
+    durationScale: Double = 1.0,
+    revealHaptics: ContainerRevealHaptics,
+) {
     spec = tween(durationMillis = (DefaultDuration * durationScale).inWholeMilliseconds.toInt())
 
     // Ensure the clock isn't clipped by the shade outline during the transition from lockscreen.
@@ -34,14 +36,10 @@
         ClockElementKeys.smallClockElementKey,
         elevateInContent = Overlays.NotificationsShade,
     )
-    scaleSize(OverlayShade.Elements.Panel, height = 0f)
-    // Avoid translating the status bar with the shade panel.
-    translate(NotificationsShade.Elements.StatusBar)
-    // Slide in the shade panel from the top edge.
-    translate(OverlayShade.Elements.Panel, Edge.Top)
 
-    fractionRange(end = .5f) { fade(OverlayShade.Elements.Scrim) }
-    fractionRange(start = .5f) { fade(Notifications.Elements.NotificationScrim) }
+    verticalContainerReveal(NotificationsShade.Elements.Panel, revealHaptics)
+
+    fade(NotificationsShade.Elements.StatusBar)
 }
 
 private val DefaultDuration = 300.milliseconds
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 43aa358..522b2d4 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
@@ -17,16 +17,21 @@
 package com.android.systemui.scene.ui.composable.transitions
 
 import androidx.compose.animation.core.tween
-import com.android.compose.animation.scene.Edge
 import com.android.compose.animation.scene.TransitionBuilder
-import com.android.systemui.shade.ui.composable.OverlayShade
+import com.android.compose.animation.scene.reveal.ContainerRevealHaptics
+import com.android.compose.animation.scene.reveal.verticalContainerReveal
+import com.android.systemui.qs.ui.composable.QuickSettingsShade
 import kotlin.time.Duration.Companion.milliseconds
 
-fun TransitionBuilder.toQuickSettingsShadeTransition(durationScale: Double = 1.0) {
+fun TransitionBuilder.toQuickSettingsShadeTransition(
+    durationScale: Double = 1.0,
+    revealHaptics: ContainerRevealHaptics,
+) {
     spec = tween(durationMillis = (DefaultDuration * durationScale).inWholeMilliseconds.toInt())
 
-    translate(OverlayShade.Elements.Panel, Edge.Top)
-    fractionRange(end = .5f) { fade(OverlayShade.Elements.Scrim) }
+    verticalContainerReveal(QuickSettingsShade.Elements.Panel, revealHaptics)
+
+    fade(QuickSettingsShade.Elements.StatusBar)
 }
 
 private val DefaultDuration = 300.milliseconds
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 fc59d40..b53cc89 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
@@ -58,29 +58,32 @@
 /** Renders a lightweight shade UI container, as an overlay. */
 @Composable
 fun ContentScope.OverlayShade(
-    isShadeLayoutWide: Boolean,
+    panelElement: ElementKey,
     panelAlignment: Alignment,
     onScrimClicked: () -> Unit,
     modifier: Modifier = Modifier,
     header: @Composable () -> Unit,
     content: @Composable () -> Unit,
 ) {
+    val isFullWidth = isFullWidthShade()
     Box(modifier) {
         Scrim(onClicked = onScrimClicked)
 
-        Box(modifier = Modifier.fillMaxSize().panelPadding(), contentAlignment = panelAlignment) {
+        Box(
+            modifier = Modifier.fillMaxSize().panelContainerPadding(isFullWidth),
+            contentAlignment = panelAlignment,
+        ) {
             Panel(
-                isShadeLayoutWide = isShadeLayoutWide,
                 modifier =
                     Modifier.overscroll(verticalOverscrollEffect)
-                        .element(OverlayShade.Elements.Panel)
-                        .panelSize(),
-                header = header,
+                        .element(panelElement)
+                        .panelWidth(isFullWidth),
+                header = header.takeIf { isFullWidth },
                 content = content,
             )
         }
 
-        if (isShadeLayoutWide) {
+        if (!isFullWidth) {
             header()
         }
     }
@@ -100,9 +103,8 @@
 
 @Composable
 private fun ContentScope.Panel(
-    isShadeLayoutWide: Boolean,
     modifier: Modifier = Modifier,
-    header: @Composable () -> Unit,
+    header: (@Composable () -> Unit)?,
     content: @Composable () -> Unit,
 ) {
     Box(modifier = modifier.clip(OverlayShade.Shapes.RoundedCornerPanel)) {
@@ -117,9 +119,7 @@
         )
 
         Column {
-            if (!isShadeLayoutWide) {
-                header()
-            }
+            header?.invoke()
 
             // This content is intentionally rendered as a separate element from the background in
             // order to allow for more flexibility when defining transitions.
@@ -129,14 +129,12 @@
 }
 
 @Composable
-private fun Modifier.panelSize(): Modifier {
-    return this.then(
-        if (isFullWidthShade()) {
-            Modifier.fillMaxWidth()
-        } else {
-            Modifier.width(dimensionResource(id = R.dimen.shade_panel_width))
-        }
-    )
+private fun Modifier.panelWidth(isFullWidthPanel: Boolean): Modifier {
+    return if (isFullWidthPanel) {
+        fillMaxWidth()
+    } else {
+        width(dimensionResource(id = R.dimen.shade_panel_width))
+    }
 }
 
 @Composable
@@ -146,27 +144,23 @@
 }
 
 @Composable
-private fun Modifier.panelPadding(): Modifier {
-    val widthSizeClass = LocalWindowSizeClass.current.widthSizeClass
+private fun Modifier.panelContainerPadding(isFullWidthPanel: Boolean): Modifier {
+    if (isFullWidthPanel) {
+        return this
+    }
     val systemBars = WindowInsets.systemBarsIgnoringVisibility
     val displayCutout = WindowInsets.displayCutout
     val waterfall = WindowInsets.waterfall
     val horizontalPadding =
         PaddingValues(horizontal = dimensionResource(id = R.dimen.shade_panel_margin_horizontal))
-
-    val combinedPadding =
+    return padding(
         combinePaddings(
             systemBars.asPaddingValues(),
             displayCutout.asPaddingValues(),
             waterfall.asPaddingValues(),
             horizontalPadding,
         )
-
-    return if (widthSizeClass == WindowWidthSizeClass.Compact) {
-        padding(bottom = combinedPadding.calculateBottomPadding())
-    } else {
-        padding(combinedPadding)
-    }
+    )
 }
 
 /** Creates a union of [paddingValues] by using the max padding of each edge. */
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt
index c5d28ad..02de78b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt
@@ -74,23 +74,20 @@
 import com.android.systemui.common.ui.compose.windowinsets.LocalDisplayCutout
 import com.android.systemui.common.ui.compose.windowinsets.LocalScreenCornerRadius
 import com.android.systemui.compose.modifiers.sysuiResTag
-import com.android.systemui.lifecycle.rememberViewModel
 import com.android.systemui.privacy.OngoingPrivacyChip
 import com.android.systemui.res.R
 import com.android.systemui.scene.shared.model.Scenes
-import com.android.systemui.shade.shared.flag.DualShade
 import com.android.systemui.shade.ui.composable.ShadeHeader.Colors.chipBackground
 import com.android.systemui.shade.ui.composable.ShadeHeader.Colors.chipHighlighted
 import com.android.systemui.shade.ui.composable.ShadeHeader.Colors.onScrimDim
 import com.android.systemui.shade.ui.composable.ShadeHeader.Dimensions.CollapsedHeight
 import com.android.systemui.shade.ui.composable.ShadeHeader.Values.ClockScale
 import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel
+import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel.HeaderChipHighlight
 import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerStatusBarViewBinder
 import com.android.systemui.statusbar.phone.NotificationIconContainer
 import com.android.systemui.statusbar.phone.StatusBarLocation
 import com.android.systemui.statusbar.phone.StatusIconContainer
-import com.android.systemui.statusbar.phone.ui.StatusBarIconController
-import com.android.systemui.statusbar.phone.ui.TintedIconManager
 import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernShadeCarrierGroupMobileView
 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.ShadeCarrierGroupMobileIconViewModel
 import com.android.systemui.statusbar.policy.Clock
@@ -137,14 +134,9 @@
 /** The status bar that appears above the Shade scene on small screens */
 @Composable
 fun ContentScope.CollapsedShadeHeader(
-    viewModelFactory: ShadeHeaderViewModel.Factory,
-    createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
-    createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
-    statusBarIconController: StatusBarIconController,
+    viewModel: ShadeHeaderViewModel,
     modifier: Modifier = Modifier,
 ) {
-    val viewModel = rememberViewModel("CollapsedShadeHeader") { viewModelFactory.create() }
-
     val cutoutLocation = LocalDisplayCutout.current.location
     val horizontalPadding =
         max(LocalScreenCornerRadius.current / 2f, Shade.Dimensions.HorizontalPadding)
@@ -157,12 +149,14 @@
             }
         }
 
+    val longerDateText by viewModel.longerDateText.collectAsStateWithLifecycle()
+    val shorterDateText by viewModel.shorterDateText.collectAsStateWithLifecycle()
+
     val isShadeLayoutWide = viewModel.isShadeLayoutWide
 
     val isPrivacyChipVisible by viewModel.isPrivacyChipVisible.collectAsStateWithLifecycle()
 
-    // This layout assumes it is globally positioned at (0, 0) and is the
-    // same size as the screen.
+    // This layout assumes it is globally positioned at (0, 0) and is the same size as the screen.
     CutoutAwareShadeHeader(
         modifier = modifier.sysuiResTag(ShadeHeader.TestTags.Root),
         startContent = {
@@ -171,9 +165,11 @@
                 horizontalArrangement = Arrangement.spacedBy(5.dp),
                 modifier = Modifier.padding(horizontal = horizontalPadding),
             ) {
-                Clock(scale = 1f, viewModel = viewModel)
+                Clock(scale = 1f, onClick = viewModel::onClockClicked)
                 VariableDayDate(
-                    viewModel = viewModel,
+                    longerDateText = longerDateText,
+                    shorterDateText = shorterDateText,
+                    chipHighlight = viewModel.notificationsChipHighlight,
                     modifier = Modifier.element(ShadeHeader.Elements.CollapsedContentStart),
                 )
             }
@@ -202,17 +198,17 @@
                     if (isShadeLayoutWide) {
                         ShadeCarrierGroup(viewModel = viewModel)
                     }
-                    SystemIconChip(viewModel = viewModel, isClickable = isShadeLayoutWide) {
+                    SystemIconChip(
+                        onClick = viewModel::onSystemIconChipClicked.takeIf { isShadeLayoutWide }
+                    ) {
                         StatusIcons(
                             viewModel = viewModel,
-                            createTintedIconManager = createTintedIconManager,
-                            statusBarIconController = statusBarIconController,
                             useExpandedFormat = useExpandedTextFormat,
                             modifier = Modifier.padding(end = 6.dp).weight(1f, fill = false),
                         )
                         BatteryIcon(
-                            viewModel = viewModel,
-                            createBatteryMeterViewController = createBatteryMeterViewController,
+                            createBatteryMeterViewController =
+                                viewModel.createBatteryMeterViewController,
                             useExpandedFormat = useExpandedTextFormat,
                             modifier = Modifier.padding(vertical = 8.dp),
                         )
@@ -226,18 +222,15 @@
 /** The status bar that appears above the Quick Settings scene on small screens */
 @Composable
 fun ContentScope.ExpandedShadeHeader(
-    viewModelFactory: ShadeHeaderViewModel.Factory,
-    createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
-    createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
-    statusBarIconController: StatusBarIconController,
+    viewModel: ShadeHeaderViewModel,
     modifier: Modifier = Modifier,
 ) {
-    val viewModel = rememberViewModel("ExpandedShadeHeader") { viewModelFactory.create() }
-
     val useExpandedFormat by remember {
         derivedStateOf { shouldUseExpandedFormat(layoutState.transitionState) }
     }
 
+    val longerDateText by viewModel.longerDateText.collectAsStateWithLifecycle()
+    val shorterDateText by viewModel.shorterDateText.collectAsStateWithLifecycle()
     val isPrivacyChipVisible by viewModel.isPrivacyChipVisible.collectAsStateWithLifecycle()
 
     Box(modifier = modifier.sysuiResTag(ShadeHeader.TestTags.Root)) {
@@ -256,7 +249,7 @@
                 Box {
                     Clock(
                         scale = 2.57f,
-                        viewModel = viewModel,
+                        onClick = viewModel::onClockClicked,
                         modifier = Modifier.align(Alignment.CenterStart),
                     )
                 }
@@ -275,20 +268,23 @@
                 verticalAlignment = Alignment.CenterVertically,
                 modifier = Modifier.element(ShadeHeader.Elements.ExpandedContent),
             ) {
-                VariableDayDate(viewModel = viewModel, modifier = Modifier.widthIn(max = 90.dp))
+                VariableDayDate(
+                    longerDateText = longerDateText,
+                    shorterDateText = shorterDateText,
+                    chipHighlight = viewModel.notificationsChipHighlight,
+                    modifier = Modifier.widthIn(max = 90.dp),
+                )
                 Spacer(modifier = Modifier.weight(1f))
-                SystemIconChip(viewModel = viewModel) {
+                SystemIconChip {
                     StatusIcons(
                         viewModel = viewModel,
-                        createTintedIconManager = createTintedIconManager,
-                        statusBarIconController = statusBarIconController,
                         useExpandedFormat = useExpandedFormat,
                         modifier = Modifier.padding(end = 6.dp).weight(1f, fill = false),
                     )
                     BatteryIcon(
-                        viewModel = viewModel,
                         useExpandedFormat = useExpandedFormat,
-                        createBatteryMeterViewController = createBatteryMeterViewController,
+                        createBatteryMeterViewController =
+                            viewModel.createBatteryMeterViewController,
                     )
                 }
             }
@@ -302,15 +298,9 @@
  */
 @Composable
 fun ContentScope.OverlayShadeHeader(
-    viewModelFactory: ShadeHeaderViewModel.Factory,
-    createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
-    createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
-    statusBarIconController: StatusBarIconController,
-    notificationIconContainerStatusBarViewBinder: NotificationIconContainerStatusBarViewBinder,
+    viewModel: ShadeHeaderViewModel,
     modifier: Modifier = Modifier,
 ) {
-    val viewModel = rememberViewModel("OverlayShadeHeader") { viewModelFactory.create() }
-
     val horizontalPadding =
         max(LocalScreenCornerRadius.current / 2f, Shade.Dimensions.HorizontalPadding)
 
@@ -318,8 +308,7 @@
 
     val isPrivacyChipVisible by viewModel.isPrivacyChipVisible.collectAsStateWithLifecycle()
 
-    // This layout assumes it is globally positioned at (0, 0) and is the
-    // same size as the screen.
+    // This layout assumes it is globally positioned at (0, 0) and is the same size as the screen.
     CutoutAwareShadeHeader(
         modifier = modifier.sysuiResTag(ShadeHeader.TestTags.Root),
         startContent = {
@@ -330,21 +319,32 @@
                 if (isShadeLayoutWide) {
                     Clock(
                         scale = 1f,
-                        viewModel = viewModel,
+                        onClick = viewModel::onClockClicked,
                         modifier = Modifier.padding(horizontal = 4.dp),
                     )
                     Spacer(modifier = Modifier.width(5.dp))
                 }
-                NotificationIconChip(viewModel = viewModel) {
+                val chipHighlight = viewModel.notificationsChipHighlight
+                NotificationIconChip(
+                    chipHighlight = chipHighlight,
+                    onClick = viewModel::onNotificationIconChipClicked,
+                ) {
                     if (isShadeLayoutWide) {
                         NotificationIcons(
-                            viewModel = viewModel,
+                            chipHighlight = chipHighlight,
                             notificationIconContainerStatusBarViewBinder =
-                                notificationIconContainerStatusBarViewBinder,
+                                viewModel.notificationIconContainerStatusBarViewBinder,
                             modifier = Modifier.width(IntrinsicSize.Min).height(20.dp),
                         )
                     } else {
-                        VariableDayDate(viewModel = viewModel)
+                        val longerDateText by viewModel.longerDateText.collectAsStateWithLifecycle()
+                        val shorterDateText by
+                            viewModel.shorterDateText.collectAsStateWithLifecycle()
+                        VariableDayDate(
+                            longerDateText = longerDateText,
+                            shorterDateText = shorterDateText,
+                            chipHighlight = viewModel.notificationsChipHighlight,
+                        )
                     }
                 }
             }
@@ -355,20 +355,22 @@
                 verticalAlignment = Alignment.CenterVertically,
                 modifier = Modifier.padding(horizontal = horizontalPadding),
             ) {
-                SystemIconChip(viewModel = viewModel, isClickable = true, showBackground = true) {
+                val chipHighlight = viewModel.quickSettingsChipHighlight
+                SystemIconChip(
+                    chipHighlight = chipHighlight,
+                    onClick = viewModel::onSystemIconChipClicked,
+                ) {
                     StatusIcons(
                         viewModel = viewModel,
-                        createTintedIconManager = createTintedIconManager,
-                        statusBarIconController = statusBarIconController,
                         useExpandedFormat = false,
-                        highlightable = true,
                         modifier = Modifier.padding(end = 6.dp).weight(1f, fill = false),
+                        chipHighlight = chipHighlight,
                     )
                     BatteryIcon(
-                        viewModel = viewModel,
-                        createBatteryMeterViewController = createBatteryMeterViewController,
+                        createBatteryMeterViewController =
+                            viewModel.createBatteryMeterViewController,
                         useExpandedFormat = false,
-                        highlightable = true,
+                        chipHighlight = chipHighlight,
                     )
                 }
                 if (isPrivacyChipVisible) {
@@ -391,13 +393,7 @@
 
 /** The header that appears at the top of the Quick Settings shade overlay. */
 @Composable
-fun ContentScope.QuickSettingsOverlayHeader(
-    viewModelFactory: ShadeHeaderViewModel.Factory,
-    createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
-    modifier: Modifier = Modifier,
-) {
-    val viewModel = rememberViewModel("QuickSettingsOverlayHeader") { viewModelFactory.create() }
-
+fun QuickSettingsOverlayHeader(viewModel: ShadeHeaderViewModel, modifier: Modifier = Modifier) {
     Row(
         horizontalArrangement = Arrangement.SpaceBetween,
         verticalAlignment = Alignment.CenterVertically,
@@ -405,8 +401,7 @@
     ) {
         ShadeCarrierGroup(viewModel = viewModel)
         BatteryIcon(
-            viewModel = viewModel,
-            createBatteryMeterViewController = createBatteryMeterViewController,
+            createBatteryMeterViewController = viewModel.createBatteryMeterViewController,
             useExpandedFormat = true,
         )
     }
@@ -468,11 +463,7 @@
 }
 
 @Composable
-private fun ContentScope.Clock(
-    scale: Float,
-    viewModel: ShadeHeaderViewModel,
-    modifier: Modifier = Modifier,
-) {
+private fun ContentScope.Clock(scale: Float, onClick: () -> Unit, modifier: Modifier = Modifier) {
     val layoutDirection = LocalLayoutDirection.current
 
     Element(key = ShadeHeader.Elements.Clock, modifier = modifier) {
@@ -500,18 +491,17 @@
                                 0.5f,
                             )
                     }
-                    .clickable { viewModel.onClockClicked() },
+                    .clickable { onClick() },
         )
     }
 }
 
 @Composable
 private fun BatteryIcon(
-    viewModel: ShadeHeaderViewModel,
     createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
     useExpandedFormat: Boolean,
-    highlightable: Boolean = false,
     modifier: Modifier = Modifier,
+    chipHighlight: HeaderChipHighlight = HeaderChipHighlight.None,
 ) {
     val localContext = LocalContext.current
     val themedContext =
@@ -521,8 +511,6 @@
     val inverseColor =
         Utils.getColorAttrDefaultColor(themedContext, android.R.attr.textColorPrimaryInverse)
 
-    val isHighlighted = viewModel.highlightQuickSettingsIcons
-
     AndroidView(
         factory = { context ->
             val batteryIcon = BatteryMeterView(context, null)
@@ -544,18 +532,12 @@
             // TODO(b/298525212): use MODE_ESTIMATE in collapsed view when the screen
             //  has no center cutout. See [QsBatteryModeController.getBatteryMode]
             batteryIcon.setPercentShowMode(
-                if (useExpandedFormat) {
-                    BatteryMeterView.MODE_ESTIMATE
-                } else {
-                    BatteryMeterView.MODE_ON
-                }
+                if (useExpandedFormat) BatteryMeterView.MODE_ESTIMATE else BatteryMeterView.MODE_ON
             )
-            if (highlightable) {
-                if (isHighlighted) {
-                    batteryIcon.updateColors(primaryColor, inverseColor, inverseColor)
-                } else {
-                    batteryIcon.updateColors(primaryColor, inverseColor, primaryColor)
-                }
+            if (chipHighlight is HeaderChipHighlight.Strong) {
+                batteryIcon.updateColors(primaryColor, inverseColor, inverseColor)
+            } else if (chipHighlight is HeaderChipHighlight.Weak) {
+                batteryIcon.updateColors(primaryColor, inverseColor, primaryColor)
             }
         },
         modifier = modifier,
@@ -590,14 +572,12 @@
 
 @Composable
 private fun NotificationIcons(
-    viewModel: ShadeHeaderViewModel,
+    chipHighlight: HeaderChipHighlight,
     notificationIconContainerStatusBarViewBinder: NotificationIconContainerStatusBarViewBinder,
     modifier: Modifier = Modifier,
 ) {
     val scope = rememberCoroutineScope()
 
-    val isHighlighted = viewModel.highlightNotificationIcons
-
     AndroidView(
         factory = { context ->
             NotificationIconContainer(context, null).also { view ->
@@ -610,7 +590,7 @@
                 }
             }
         },
-        update = { it.setUseInverseOverrideIconColor(isHighlighted) },
+        update = { it.setUseInverseOverrideIconColor(chipHighlight is HeaderChipHighlight.Strong) },
         modifier = modifier,
     )
 }
@@ -618,11 +598,9 @@
 @Composable
 private fun ContentScope.StatusIcons(
     viewModel: ShadeHeaderViewModel,
-    createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
-    statusBarIconController: StatusBarIconController,
     useExpandedFormat: Boolean,
-    highlightable: Boolean = false,
     modifier: Modifier = Modifier,
+    chipHighlight: HeaderChipHighlight = HeaderChipHighlight.None,
 ) {
     val localContext = LocalContext.current
     val themedContext =
@@ -632,8 +610,6 @@
     val inverseColor =
         Utils.getColorAttrDefaultColor(themedContext, android.R.attr.textColorPrimaryInverse)
 
-    val isHighlighted = viewModel.highlightQuickSettingsIcons
-
     val carrierIconSlots =
         listOf(stringResource(id = com.android.internal.R.string.status_bar_mobile))
     val cameraSlot = stringResource(id = com.android.internal.R.string.status_bar_camera)
@@ -648,12 +624,14 @@
         viewModel.isLocationIndicationEnabled.collectAsStateWithLifecycle()
 
     val iconContainer = remember { StatusIconContainer(themedContext, null) }
-    val iconManager = remember { createTintedIconManager(iconContainer, StatusBarLocation.QS) }
+    val iconManager = remember {
+        viewModel.createTintedIconManager(iconContainer, StatusBarLocation.QS)
+    }
 
     AndroidView(
         factory = { context ->
             iconManager.setTint(primaryColor, inverseColor)
-            statusBarIconController.addIconGroup(iconManager)
+            viewModel.statusBarIconController.addIconGroup(iconManager)
 
             iconContainer
         },
@@ -686,12 +664,10 @@
                 iconContainer.removeIgnoredSlot(locationSlot)
             }
 
-            if (highlightable) {
-                if (isHighlighted) {
-                    iconManager.setTint(inverseColor, primaryColor)
-                } else {
-                    iconManager.setTint(primaryColor, inverseColor)
-                }
+            if (chipHighlight is HeaderChipHighlight.Strong) {
+                iconManager.setTint(inverseColor, primaryColor)
+            } else if (chipHighlight is HeaderChipHighlight.Weak) {
+                iconManager.setTint(primaryColor, inverseColor)
             }
         },
         modifier = modifier,
@@ -700,15 +676,12 @@
 
 @Composable
 private fun NotificationIconChip(
-    viewModel: ShadeHeaderViewModel,
+    chipHighlight: HeaderChipHighlight,
+    onClick: () -> Unit,
     modifier: Modifier = Modifier,
     content: @Composable RowScope.() -> Unit,
 ) {
     val interactionSource = remember { MutableInteractionSource() }
-    val backgroundColor =
-        if (viewModel.highlightNotificationIcons) MaterialTheme.colorScheme.chipHighlighted
-        else MaterialTheme.colorScheme.chipBackground
-
     Box(modifier = modifier) {
         Row(
             modifier =
@@ -716,16 +689,15 @@
                     .clickable(
                         interactionSource = interactionSource,
                         indication = null,
-                        onClick = { viewModel.onNotificationIconChipClicked() },
+                        onClick = { onClick() },
                     )
-                    .thenIf(DualShade.isEnabled) {
-                        Modifier.graphicsLayer {
-                                shape = RoundedCornerShape(25.dp)
-                                clip = true
-                            }
-                            .background(backgroundColor)
-                            .padding(horizontal = 8.dp, vertical = 4.dp)
-                    }
+                    .clip(RoundedCornerShape(25.dp))
+                    .background(
+                        if (chipHighlight is HeaderChipHighlight.Strong)
+                            MaterialTheme.colorScheme.chipHighlighted
+                        else MaterialTheme.colorScheme.chipBackground
+                    )
+                    .padding(horizontal = 8.dp, vertical = 4.dp)
         ) {
             content()
         }
@@ -734,10 +706,9 @@
 
 @Composable
 private fun SystemIconChip(
-    viewModel: ShadeHeaderViewModel,
-    isClickable: Boolean = false,
-    showBackground: Boolean = false,
     modifier: Modifier = Modifier,
+    chipHighlight: HeaderChipHighlight = HeaderChipHighlight.None,
+    onClick: (() -> Unit)? = null,
     content: @Composable RowScope.() -> Unit,
 ) {
     val interactionSource = remember { MutableInteractionSource() }
@@ -746,14 +717,14 @@
         Modifier.clip(RoundedCornerShape(CollapsedHeight / 4))
             .background(MaterialTheme.colorScheme.onScrimDim)
     val backgroundColor =
-        if (viewModel.highlightQuickSettingsIcons) MaterialTheme.colorScheme.chipHighlighted
+        if (chipHighlight is HeaderChipHighlight.Strong) MaterialTheme.colorScheme.chipHighlighted
         else MaterialTheme.colorScheme.chipBackground
 
     Row(
         verticalAlignment = Alignment.CenterVertically,
         modifier =
             modifier
-                .thenIf(showBackground) {
+                .thenIf(chipHighlight !is HeaderChipHighlight.None) {
                     Modifier.graphicsLayer {
                             shape = RoundedCornerShape(25.dp)
                             clip = true
@@ -761,11 +732,11 @@
                         .background(backgroundColor)
                         .padding(horizontal = 8.dp, vertical = 4.dp)
                 }
-                .thenIf(isClickable) {
+                .thenIf(onClick != null) {
                     Modifier.clickable(
                         interactionSource = interactionSource,
                         indication = null,
-                        onClick = { viewModel.onSystemIconChipClicked() },
+                        onClick = { onClick?.invoke() },
                     )
                 }
                 .thenIf(isHovered) { hoverModifier },
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 f829a0d..5040490 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
@@ -101,6 +101,7 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.composable.Scene
 import com.android.systemui.shade.shared.model.ShadeMode
+import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel
 import com.android.systemui.shade.ui.viewmodel.ShadeSceneContentViewModel
 import com.android.systemui.shade.ui.viewmodel.ShadeUserActionsViewModel
 import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
@@ -124,8 +125,6 @@
 
     object Dimensions {
         val HorizontalPadding = 16.dp
-        val ScrimOverscrollLimit = 32.dp
-        const val ScrimVisibilityThreshold = 5f
     }
 }
 
@@ -160,15 +159,22 @@
     override val userActions: Flow<Map<UserAction, UserActionResult>> = actionsViewModel.actions
 
     @Composable
-    override fun ContentScope.Content(modifier: Modifier) =
+    override fun ContentScope.Content(modifier: Modifier) {
+        val viewModel =
+            rememberViewModel("ShadeScene-viewModel") { contentViewModelFactory.create() }
+        val headerViewModel =
+            rememberViewModel("ShadeScene-headerViewModel") {
+                viewModel.shadeHeaderViewModelFactory.create()
+            }
+        val notificationsPlaceholderViewModel =
+            rememberViewModel("ShadeScene-notifPlaceholderViewModel") {
+                notificationsPlaceholderViewModelFactory.create()
+            }
         ShadeScene(
             notificationStackScrollView.get(),
-            viewModel =
-                rememberViewModel("ShadeScene-viewModel") { contentViewModelFactory.create() },
-            notificationsPlaceholderViewModel =
-                rememberViewModel("ShadeScene-notifPlaceholderViewModel") {
-                    notificationsPlaceholderViewModelFactory.create()
-                },
+            viewModel = viewModel,
+            headerViewModel = headerViewModel,
+            notificationsPlaceholderViewModel = notificationsPlaceholderViewModel,
             createTintedIconManager = tintedIconManagerFactory::create,
             createBatteryMeterViewController = batteryMeterViewControllerFactory::create,
             statusBarIconController = statusBarIconController,
@@ -180,6 +186,7 @@
             usingCollapsedLandscapeMedia =
                 Utils.useCollapsedMediaInLandscape(LocalContext.current.resources),
         )
+    }
 
     init {
         qqsMediaHost.expansion = EXPANDED
@@ -196,6 +203,7 @@
 private fun ContentScope.ShadeScene(
     notificationStackScrollView: NotificationScrollView,
     viewModel: ShadeSceneContentViewModel,
+    headerViewModel: ShadeHeaderViewModel,
     notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel,
     createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
     createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
@@ -207,13 +215,13 @@
     shadeSession: SaveableSession,
     usingCollapsedLandscapeMedia: Boolean,
 ) {
-
     val shadeMode by viewModel.shadeMode.collectAsStateWithLifecycle()
     when (shadeMode) {
         is ShadeMode.Single ->
             SingleShade(
                 notificationStackScrollView = notificationStackScrollView,
                 viewModel = viewModel,
+                headerViewModel = headerViewModel,
                 notificationsPlaceholderViewModel = notificationsPlaceholderViewModel,
                 createTintedIconManager = createTintedIconManager,
                 createBatteryMeterViewController = createBatteryMeterViewController,
@@ -228,10 +236,8 @@
             SplitShade(
                 notificationStackScrollView = notificationStackScrollView,
                 viewModel = viewModel,
+                headerViewModel = headerViewModel,
                 notificationsPlaceholderViewModel = notificationsPlaceholderViewModel,
-                createTintedIconManager = createTintedIconManager,
-                createBatteryMeterViewController = createBatteryMeterViewController,
-                statusBarIconController = statusBarIconController,
                 mediaCarouselController = mediaCarouselController,
                 mediaHost = qsMediaHost,
                 modifier = modifier,
@@ -245,6 +251,7 @@
 private fun ContentScope.SingleShade(
     notificationStackScrollView: NotificationScrollView,
     viewModel: ShadeSceneContentViewModel,
+    headerViewModel: ShadeHeaderViewModel,
     notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel,
     createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
     createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
@@ -332,10 +339,7 @@
                 },
             content = {
                 CollapsedShadeHeader(
-                    viewModelFactory = viewModel.shadeHeaderViewModelFactory,
-                    createTintedIconManager = createTintedIconManager,
-                    createBatteryMeterViewController = createBatteryMeterViewController,
-                    statusBarIconController = statusBarIconController,
+                    viewModel = headerViewModel,
                     modifier = Modifier.layoutId(SingleShadeMeasurePolicy.LayoutId.ShadeHeader),
                 )
 
@@ -413,10 +417,8 @@
 private fun ContentScope.SplitShade(
     notificationStackScrollView: NotificationScrollView,
     viewModel: ShadeSceneContentViewModel,
+    headerViewModel: ShadeHeaderViewModel,
     notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel,
-    createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
-    createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
-    statusBarIconController: StatusBarIconController,
     mediaCarouselController: MediaCarouselController,
     mediaHost: MediaHost,
     modifier: Modifier = Modifier,
@@ -509,10 +511,7 @@
 
         Column(modifier = Modifier.fillMaxSize()) {
             CollapsedShadeHeader(
-                viewModelFactory = viewModel.shadeHeaderViewModelFactory,
-                createTintedIconManager = createTintedIconManager,
-                createBatteryMeterViewController = createBatteryMeterViewController,
-                statusBarIconController = statusBarIconController,
+                viewModel = headerViewModel,
                 modifier =
                     Modifier.then(brightnessMirrorShowingModifier)
                         .padding(horizontal = { unfoldTranslationXForStartSide.roundToInt() }),
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/VariableDayDate.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/VariableDayDate.kt
index 93eca86..64aada5 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/VariableDayDate.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/VariableDayDate.kt
@@ -5,17 +5,19 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.layout.Layout
-import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.compose.theme.colorAttr
-import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel
+import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel.HeaderChipHighlight
 
 @Composable
-fun VariableDayDate(viewModel: ShadeHeaderViewModel, modifier: Modifier = Modifier) {
-    val longerText = viewModel.longerDateText.collectAsStateWithLifecycle()
-    val shorterText = viewModel.shorterDateText.collectAsStateWithLifecycle()
-
+fun VariableDayDate(
+    longerDateText: String,
+    shorterDateText: String,
+    chipHighlight: HeaderChipHighlight,
+    modifier: Modifier = Modifier,
+) {
     val textColor =
-        if (viewModel.highlightNotificationIcons) colorAttr(android.R.attr.textColorPrimaryInverse)
+        if (chipHighlight is HeaderChipHighlight.Strong)
+            colorAttr(android.R.attr.textColorPrimaryInverse)
         else colorAttr(android.R.attr.textColorPrimary)
 
     Layout(
@@ -23,7 +25,7 @@
             listOf(
                 {
                     Text(
-                        text = longerText.value,
+                        text = longerDateText,
                         style = MaterialTheme.typography.bodyMedium,
                         color = textColor,
                         maxLines = 1,
@@ -31,7 +33,7 @@
                 },
                 {
                     Text(
-                        text = shorterText.value,
+                        text = shorterDateText,
                         style = MaterialTheme.typography.bodyMedium,
                         color = textColor,
                         maxLines = 1,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModule.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModule.kt
index c73656e..f1cc71b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModule.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModule.kt
@@ -16,9 +16,9 @@
 
 package com.android.systemui.volume.panel.component.mediaoutput
 
-import com.android.systemui.volume.panel.component.mediaoutput.domain.MediaOutputAvailabilityCriteria
 import com.android.systemui.volume.panel.component.mediaoutput.ui.composable.MediaOutputComponent
 import com.android.systemui.volume.panel.component.shared.model.VolumePanelComponents
+import com.android.systemui.volume.panel.domain.AlwaysAvailableCriteria
 import com.android.systemui.volume.panel.domain.ComponentAvailabilityCriteria
 import com.android.systemui.volume.panel.shared.model.VolumePanelUiComponent
 import dagger.Binds
@@ -39,6 +39,6 @@
     @IntoMap
     @StringKey(VolumePanelComponents.MEDIA_OUTPUT)
     fun bindComponentAvailabilityCriteria(
-        criteria: MediaOutputAvailabilityCriteria
+        criteria: AlwaysAvailableCriteria
     ): ComponentAvailabilityCriteria
 }
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 a5dba0f..907b5bc 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
@@ -285,7 +285,9 @@
             val elementState = Element.State(contents)
             element.stateByContent[content.key] = elementState
 
-            layoutImpl.ancestors.fastForEach { element.stateByContent[it.inContent] = elementState }
+            layoutImpl.ancestors.fastForEach {
+                element.stateByContent.putIfAbsent(it.inContent, elementState)
+            }
         }
     }
 
@@ -402,6 +404,7 @@
                 doNotPlace(measurable, constraints)
             }
         }
+        syncAncestorElementState()
 
         val transition = elementState as? TransitionState.Transition
 
@@ -539,6 +542,75 @@
     }
 
     /**
+     * This method makes sure that the ancestor element state is *roughly* in sync. Assume we have
+     * the following nested scenes:
+     * ```
+     *       /   \
+     *     P1     P2
+     *   /   \
+     *  C1   C2
+     * ```
+     *
+     * We write the state of the shared element into its parent P1 even though P1 does not contain
+     * the element directly but it's part of its NestedSTL instead. This value is used to
+     * interpolate transitions on higher levels, e.g. between P1 and P2. Technically the best
+     * solution would be to always write the fully interpolated state into P1 but because this
+     * interferes with `computeValue` computations of other transitions this solution requires more
+     * sophistication and additional invocations of `computeValue`. We might want to aim for such a
+     * solution in the future when we allocate resources to that feature. For now, we only roughly
+     * set the state of P1 to either C1 or C2 based on heuristics.
+     *
+     * If we assign the P1 state just on attach/detach of a scene like we do for C1 and C2, this
+     * leads to problems where P1 can either become stale or is erased. This leads to situations
+     * where a shared element is not animated anymore.
+     *
+     * With this solution we track the transition state of the local transition at all times and set
+     * P1 based on the currentScene or overlay. In certain sequences of transition this may create
+     * jump cuts of a shared element mainly because of two reasons:
+     *
+     * a) P1 state is modified during a transition of P1 and X. Due to the new value it may jump cut
+     * when the interruption system is not triggered correctly. b) A dominant parent transition ends
+     * (P1 - X) but a local transition is still running, resulting in a different state of the
+     * element.
+     *
+     * Both issues can be addressed by interpolating P1 in the future.
+     */
+    private fun syncAncestorElementState() {
+        // every nested STL syncs only the level above it
+        layoutImpl.ancestors.lastOrNull()?.also { ancestor ->
+            val localTransition =
+                localElementState(
+                    currentTransitionStates.last(),
+                    isInContent = { it in element.stateByContent },
+                )
+            when (localTransition) {
+                is TransitionState.Idle ->
+                    assignState(ancestor.inContent, localTransition.currentScene)
+                is TransitionState.Transition.ChangeScene ->
+                    assignState(ancestor.inContent, localTransition.currentScene)
+                is TransitionState.Transition.ReplaceOverlay ->
+                    assignState(ancestor.inContent, localTransition.effectivelyShownOverlay)
+                is TransitionState.Transition.ShowOrHideOverlay ->
+                    if (localTransition.isEffectivelyShown) {
+                        assignState(ancestor.inContent, localTransition.overlay)
+                    } else {
+                        assignState(ancestor.inContent, localTransition.fromOrToScene)
+                    }
+                null -> {}
+            }
+        }
+    }
+
+    private fun assignState(toContent: ContentKey, fromContent: ContentKey) {
+        val fromState = element.stateByContent[fromContent]
+        if (fromState != null) {
+            element.stateByContent[toContent] = fromState
+        } else {
+            element.stateByContent.remove(toContent)
+        }
+    }
+
+    /**
      * Recursively clear the last placement values on this node and all descendants ElementNodes.
      * This should be called when this node is not placed anymore, so that we correctly clear values
      * for the descendants for which approachMeasure() won't be called.
@@ -661,22 +733,31 @@
                 }
             }
         } else {
-            // the last state of the list, is the state of the local STL
-            val lastState = states.last()
-            if (lastState is TransitionState.Idle) {
-                check(states.size == 1)
-                return lastState
-            }
-
-            // Find the last transition with a content that contains the element.
-            states.fastForEachReversed { state ->
-                val transition = state as TransitionState.Transition
-                if (isInContent(transition.fromContent) || isInContent(transition.toContent)) {
-                    return transition
-                }
-            }
+            return localElementState(states, isInContent)
         }
     }
+    return null
+}
+
+private inline fun localElementState(
+    states: List<TransitionState>,
+    isInContent: (ContentKey) -> Boolean,
+): TransitionState? {
+    // the last state of the list is the state of the local STL
+    val lastState = states.last()
+    if (lastState is TransitionState.Idle) {
+        check(states.size == 1)
+        return lastState
+    }
+
+    // Find the last transition with a content that contains the element.
+    states.fastForEachReversed { state ->
+        val transition = state as TransitionState.Transition
+        if (isInContent(transition.fromContent) || isInContent(transition.toContent)) {
+            return transition
+        }
+    }
+
     // We are running a transition where both from and to don't contain the element. The element
     // may still be rendered as e.g. it can be part of a idle scene where two overlays are currently
     // transitioning above it.
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
index 12b20a5..b59b4ab 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
@@ -145,7 +145,6 @@
                 var isCurrentClock = false
                 var isClockListChanged = false
                 for (metadata in knownClocks) {
-                    isCurrentClock = isCurrentClock || currentClockId == metadata.clockId
                     val id = metadata.clockId
                     val info =
                         availableClocks.concurrentGetOrPut(id, ClockInfo(metadata, null, manager)) {
@@ -156,15 +155,17 @@
                     if (manager != info.manager) {
                         logger.e({
                             "Clock Id conflict on attach: " +
-                                "$str1 is double registered by $str2 and $str3"
+                                "$str1 is double registered by $str2 and $str3. " +
+                                "Using $str2 since it was attached first."
                         }) {
                             str1 = id
-                            str2 = info.manager.toString()
+                            str2 = info.manager?.toString() ?: info.provider?.toString()
                             str3 = manager.toString()
                         }
                         continue
                     }
 
+                    isCurrentClock = isCurrentClock || currentClockId == metadata.clockId
                     info.provider = null
                 }
 
@@ -197,10 +198,11 @@
                     if (manager != info.manager) {
                         logger.e({
                             "Clock Id conflict on load: " +
-                                "$str1 is double registered by $str2 and $str3"
+                                "$str1 is double registered by $str2 and $str3. " +
+                                "Using $str2 since it was attached first."
                         }) {
                             str1 = id
-                            str2 = info.manager.toString()
+                            str2 = info.manager?.toString() ?: info.provider?.toString()
                             str3 = manager.toString()
                         }
                         manager.unloadPlugin()
@@ -227,10 +229,11 @@
                     if (info?.manager != manager) {
                         logger.e({
                             "Clock Id conflict on unload: " +
-                                "$str1 is double registered by $str2 and $str3"
+                                "$str1 is double registered by $str2 and $str3. " +
+                                "Using $str2 since it was attached first."
                         }) {
                             str1 = id
-                            str2 = info?.manager.toString()
+                            str2 = info?.manager?.toString() ?: info?.provider?.toString()
                             str3 = manager.toString()
                         }
                         continue
@@ -299,8 +302,7 @@
                             Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE,
                         )
                     }
-
-                ClockSettings.fromJson(JSONObject(json))
+                json?.let { ClockSettings.fromJson(JSONObject(it)) }
             } catch (ex: Exception) {
                 logger.e("Failed to parse clock settings", ex)
                 null
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt
index 9fb60c7..98cf684 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt
@@ -47,7 +47,7 @@
 
     init {
         fun createController(cfg: LayerConfig) {
-            val controller = SimpleDigitalHandLayerController(clockCtx, cfg)
+            val controller = SimpleDigitalHandLayerController(clockCtx, cfg, isLargeClock = true)
             view.addView(controller.view)
             layerControllers.add(controller)
         }
@@ -55,31 +55,20 @@
         val layerCfg =
             LayerConfig(
                 style = FontTextStyle(lineHeight = 147.25f),
+                timespec = DigitalTimespec.DIGIT_PAIR,
+                alignment = DigitalAlignment(HorizontalAlignment.CENTER, VerticalAlignment.CENTER),
                 aodStyle =
                     FontTextStyle(
                         transitionInterpolator = Interpolators.EMPHASIZED,
                         transitionDuration = 750,
                     ),
-                alignment =
-                    DigitalAlignment(HorizontalAlignment.CENTER, VerticalAlignment.BASELINE),
 
-                // Placeholders
-                timespec = DigitalTimespec.TIME_FULL_FORMAT,
+                // Placeholder
                 dateTimeFormat = "hh:mm",
             )
 
-        createController(
-            layerCfg.copy(timespec = DigitalTimespec.FIRST_DIGIT, dateTimeFormat = "hh")
-        )
-        createController(
-            layerCfg.copy(timespec = DigitalTimespec.SECOND_DIGIT, dateTimeFormat = "hh")
-        )
-        createController(
-            layerCfg.copy(timespec = DigitalTimespec.FIRST_DIGIT, dateTimeFormat = "mm")
-        )
-        createController(
-            layerCfg.copy(timespec = DigitalTimespec.SECOND_DIGIT, dateTimeFormat = "mm")
-        )
+        createController(layerCfg.copy(dateTimeFormat = "hh"))
+        createController(layerCfg.copy(dateTimeFormat = "mm"))
     }
 
     private fun refreshTime() {
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 6cc281a..af9f2ce 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
@@ -17,21 +17,21 @@
 import android.content.res.Resources
 import android.graphics.Typeface
 import android.view.LayoutInflater
-import com.android.systemui.animation.GSFAxes
 import com.android.systemui.customization.R
 import com.android.systemui.log.core.MessageBuffer
 import com.android.systemui.plugins.clocks.ClockController
-import com.android.systemui.plugins.clocks.ClockFontAxis
-import com.android.systemui.plugins.clocks.ClockFontAxisSetting
+import com.android.systemui.plugins.clocks.ClockFontAxis.Companion.merge
 import com.android.systemui.plugins.clocks.ClockLogger
 import com.android.systemui.plugins.clocks.ClockMessageBuffers
 import com.android.systemui.plugins.clocks.ClockMetadata
 import com.android.systemui.plugins.clocks.ClockPickerConfig
 import com.android.systemui.plugins.clocks.ClockProvider
 import com.android.systemui.plugins.clocks.ClockSettings
+import com.android.systemui.shared.clocks.FlexClockController.Companion.getDefaultAxes
 
 private val TAG = DefaultClockProvider::class.simpleName
 const val DEFAULT_CLOCK_ID = "DEFAULT"
+const val FLEX_CLOCK_ID = "DIGITAL_CLOCK_FLEX"
 
 data class ClockContext(
     val context: Context,
@@ -55,16 +55,20 @@
         messageBuffers = buffers
     }
 
-    override fun getClocks(): List<ClockMetadata> = listOf(ClockMetadata(DEFAULT_CLOCK_ID))
+    override fun getClocks(): List<ClockMetadata> {
+        var clocks = listOf(ClockMetadata(DEFAULT_CLOCK_ID))
+        if (isClockReactiveVariantsEnabled) clocks += ClockMetadata(FLEX_CLOCK_ID)
+        return clocks
+    }
 
     override fun createClock(settings: ClockSettings): ClockController {
-        if (settings.clockId != DEFAULT_CLOCK_ID) {
+        if (getClocks().all { it.clockId != settings.clockId }) {
             throw IllegalArgumentException("${settings.clockId} is unsupported by $TAG")
         }
 
         return if (isClockReactiveVariantsEnabled) {
             val buffers = messageBuffers ?: ClockMessageBuffers(ClockLogger.DEFAULT_MESSAGE_BUFFER)
-            val fontAxes = ClockFontAxis.merge(FlexClockController.FONT_AXES, settings.axes)
+            val fontAxes = getDefaultAxes(settings).merge(settings.axes)
             val clockSettings = settings.copy(axes = fontAxes.map { it.toSetting() })
             val typefaceCache =
                 TypefaceCache(buffers.infraMessageBuffer, NUM_CLOCK_FONT_ANIMATION_STEPS) {
@@ -86,15 +90,15 @@
     }
 
     override fun getClockPickerConfig(settings: ClockSettings): ClockPickerConfig {
-        if (settings.clockId != DEFAULT_CLOCK_ID) {
+        if (getClocks().all { it.clockId != settings.clockId }) {
             throw IllegalArgumentException("${settings.clockId} is unsupported by $TAG")
         }
 
         val fontAxes =
             if (!isClockReactiveVariantsEnabled) listOf()
-            else ClockFontAxis.merge(FlexClockController.FONT_AXES, settings.axes)
+            else getDefaultAxes(settings).merge(settings.axes)
         return ClockPickerConfig(
-            DEFAULT_CLOCK_ID,
+            settings.clockId ?: DEFAULT_CLOCK_ID,
             resources.getString(R.string.clock_default_name),
             resources.getString(R.string.clock_default_description),
             resources.getDrawable(R.drawable.clock_default_thumbnail, null),
@@ -106,23 +110,6 @@
     companion object {
         const val NUM_CLOCK_FONT_ANIMATION_STEPS = 30
 
-        // TODO(b/364681643): Variations for retargetted DIGITAL_CLOCK_FLEX
-        val LEGACY_FLEX_LS_VARIATION =
-            listOf(
-                ClockFontAxisSetting(GSFAxes.WEIGHT, 600f),
-                ClockFontAxisSetting(GSFAxes.WIDTH, 100f),
-                ClockFontAxisSetting(GSFAxes.ROUND, 100f),
-                ClockFontAxisSetting(GSFAxes.SLANT, 0f),
-            )
-
-        val LEGACY_FLEX_AOD_VARIATION =
-            listOf(
-                ClockFontAxisSetting(GSFAxes.WEIGHT, 74f),
-                ClockFontAxisSetting(GSFAxes.WIDTH, 43f),
-                ClockFontAxisSetting(GSFAxes.ROUND, 100f),
-                ClockFontAxisSetting(GSFAxes.SLANT, 0f),
-            )
-
         val FLEX_TYPEFACE by lazy {
             // TODO(b/364680873): Move constant to config_clockFontFamily when shipping
             Typeface.create("google-sans-flex-clock", Typeface.NORMAL)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt
index cc3769e..004d1aa 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt
@@ -24,7 +24,9 @@
 import com.android.systemui.plugins.clocks.ClockController
 import com.android.systemui.plugins.clocks.ClockEvents
 import com.android.systemui.plugins.clocks.ClockFontAxis
+import com.android.systemui.plugins.clocks.ClockFontAxis.Companion.merge
 import com.android.systemui.plugins.clocks.ClockFontAxisSetting
+import com.android.systemui.plugins.clocks.ClockSettings
 import com.android.systemui.plugins.clocks.WeatherData
 import com.android.systemui.plugins.clocks.ZenData
 import com.android.systemui.shared.clocks.view.FlexClockView
@@ -94,7 +96,7 @@
             }
 
             override fun onFontAxesChanged(axes: List<ClockFontAxisSetting>) {
-                val fontAxes = ClockFontAxis.merge(FONT_AXES, axes).map { it.toSetting() }
+                val fontAxes = getDefaultAxes(clockCtx.settings).merge(axes).map { it.toSetting() }
                 smallClock.events.onFontAxesChanged(fontAxes)
                 largeClock.events.onFontAxesChanged(fontAxes)
             }
@@ -120,7 +122,13 @@
     override fun dump(pw: PrintWriter) {}
 
     companion object {
-        val FONT_AXES =
+        fun getDefaultAxes(settings: ClockSettings): List<ClockFontAxis> {
+            return if (settings.clockId == FLEX_CLOCK_ID) {
+                FONT_AXES.merge(LEGACY_FLEX_SETTINGS)
+            } else FONT_AXES
+        }
+
+        private val FONT_AXES =
             listOf(
                 ClockFontAxis(
                     key = GSFAxes.WEIGHT,
@@ -135,7 +143,7 @@
                     key = GSFAxes.WIDTH,
                     type = AxisType.Float,
                     minValue = 25f,
-                    currentValue = 100f,
+                    currentValue = 85f,
                     maxValue = 151f,
                     name = "Width",
                     description = "Glyph Width",
@@ -159,5 +167,13 @@
                     description = "Glyph Slant",
                 ),
             )
+
+        private val LEGACY_FLEX_SETTINGS =
+            listOf(
+                ClockFontAxisSetting(GSFAxes.WEIGHT, 600f),
+                ClockFontAxisSetting(GSFAxes.WIDTH, 100f),
+                ClockFontAxisSetting(GSFAxes.ROUND, 100f),
+                ClockFontAxisSetting(GSFAxes.SLANT, 0f),
+            )
     }
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt
index e2bbe0f..cfcf201 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt
@@ -37,6 +37,7 @@
 import com.android.systemui.plugins.clocks.ZenData
 import com.android.systemui.shared.clocks.view.FlexClockView
 import com.android.systemui.shared.clocks.view.HorizontalAlignment
+import com.android.systemui.shared.clocks.view.VerticalAlignment
 import java.util.Locale
 import java.util.TimeZone
 import kotlin.math.max
@@ -59,7 +60,7 @@
     init {
         layerController =
             if (isLargeClock) ComposedDigitalLayerController(clockCtx)
-            else SimpleDigitalHandLayerController(clockCtx, SMALL_LAYER_CONFIG)
+            else SimpleDigitalHandLayerController(clockCtx, SMALL_LAYER_CONFIG, isLargeClock)
 
         layerController.view.layoutParams =
             FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT).apply { gravity = Gravity.CENTER }
@@ -147,21 +148,6 @@
          * keyguard_large_clock_top_margin from default clock
          */
         override fun onTargetRegionChanged(targetRegion: Rect?) {
-            // When a clock needs to be aligned with screen, like weather clock
-            // it needs to offset back the translation of keyguard_large_clock_top_margin
-            if (isLargeClock && (view as FlexClockView).isAlignedWithScreen()) {
-                val topMargin = keyguardLargeClockTopMargin
-                targetRegion?.let {
-                    val (_, yDiff) = computeLayoutDiff(view, it, isLargeClock)
-                    // In LS, we use yDiff to counter translate
-                    // the translation of KeyguardLargeClockTopMargin
-                    // With the targetRegion passed from picker,
-                    // we will have yDiff = 0, no translation is needed for weather clock
-                    if (yDiff.toInt() != 0) view.translationY = yDiff - topMargin / 2
-                }
-                return
-            }
-
             var maxWidth = 0f
             var maxHeight = 0f
 
@@ -230,7 +216,7 @@
             }
 
             override fun onPickerCarouselSwiping(swipingFraction: Float) {
-                if (isLargeClock && !(view as FlexClockView).isAlignedWithScreen()) {
+                if (isLargeClock) {
                     view.translationY = keyguardLargeClockTopMargin / 2F * swipingFraction
                 }
                 layerController.animations.onPickerCarouselSwiping(swipingFraction)
@@ -250,12 +236,13 @@
 
     companion object {
         val SMALL_CLOCK_MAX_WDTH = 120f
+
         val SMALL_LAYER_CONFIG =
             LayerConfig(
                 timespec = DigitalTimespec.TIME_FULL_FORMAT,
                 style = FontTextStyle(fontSizeScale = 0.98f),
                 aodStyle = FontTextStyle(),
-                alignment = DigitalAlignment(HorizontalAlignment.LEFT, null),
+                alignment = DigitalAlignment(HorizontalAlignment.LEFT, VerticalAlignment.CENTER),
                 dateTimeFormat = "h:mm",
             )
     }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt
index 82fc3501..1659814 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt
@@ -71,6 +71,7 @@
 
 enum class DigitalTimespec {
     TIME_FULL_FORMAT,
+    DIGIT_PAIR,
     FIRST_DIGIT,
     SECOND_DIGIT,
 }
@@ -78,8 +79,9 @@
 open class SimpleDigitalHandLayerController(
     private val clockCtx: ClockContext,
     private val layerCfg: LayerConfig,
+    isLargeClock: Boolean,
 ) : SimpleClockLayerController {
-    override val view = SimpleDigitalClockTextView(clockCtx)
+    override val view = SimpleDigitalClockTextView(clockCtx, isLargeClock)
     private val logger = Logger(clockCtx.messageBuffer, TAG)
     val timespec = DigitalTimespecHandler(layerCfg.timespec, layerCfg.dateTimeFormat)
 
@@ -120,6 +122,28 @@
         }
     }
 
+    private fun applyLayout() {
+        // TODO: Remove NO-OP
+        if (view.layoutParams is RelativeLayout.LayoutParams) {
+            val lp = view.layoutParams as RelativeLayout.LayoutParams
+            lp.addRule(RelativeLayout.TEXT_ALIGNMENT_CENTER)
+            when (view.id) {
+                R.id.HOUR_DIGIT_PAIR -> {
+                    lp.addRule(RelativeLayout.CENTER_VERTICAL)
+                    lp.addRule(RelativeLayout.ALIGN_PARENT_START)
+                }
+                R.id.MINUTE_DIGIT_PAIR -> {
+                    lp.addRule(RelativeLayout.CENTER_VERTICAL)
+                    lp.addRule(RelativeLayout.END_OF, R.id.HOUR_DIGIT_PAIR)
+                }
+                else -> {
+                    throw Exception("cannot apply two pairs layout to view ${view.id}")
+                }
+            }
+            view.layoutParams = lp
+        }
+    }
+
     override val events =
         object : ClockEvents {
             override var isReactiveTouchInteractionEnabled = false
@@ -154,6 +178,7 @@
     override val animations =
         object : ClockAnimations {
             override fun enter() {
+                applyLayout()
                 refreshTime()
             }
 
@@ -169,6 +194,7 @@
             }
 
             override fun fold(fraction: Float) {
+                applyLayout()
                 refreshTime()
             }
 
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/TimespecHandler.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/TimespecHandler.kt
index 37db783..8b3b929 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/TimespecHandler.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/TimespecHandler.kt
@@ -106,19 +106,16 @@
         )
     }
 
-    private fun getSingleDigit(): String {
-        val isFirstDigit = timespec == DigitalTimespec.FIRST_DIGIT
+    private fun getSingleDigit(offset: Int): String {
         val text = dateFormat.format(cal.time).toString()
-        return text.substring(
-            if (isFirstDigit) 0 else text.length - 1,
-            if (isFirstDigit) text.length - 1 else text.length,
-        )
+        return text.substring(offset, offset + 1)
     }
 
     fun getDigitString(): String {
         return when (timespec) {
-            DigitalTimespec.FIRST_DIGIT,
-            DigitalTimespec.SECOND_DIGIT -> getSingleDigit()
+            DigitalTimespec.FIRST_DIGIT -> getSingleDigit(0)
+            DigitalTimespec.SECOND_DIGIT -> getSingleDigit(1)
+            DigitalTimespec.DIGIT_PAIR -> dateFormat.format(cal.time).toString()
             DigitalTimespec.TIME_FULL_FORMAT -> dateFormat.format(cal.time).toString()
         }
     }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt
index 55750b5..f0f344a 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt
@@ -87,7 +87,7 @@
 
     protected fun calculateSize(widthMeasureSpec: Int, heightMeasureSpec: Int): Point? {
         maxSingleDigitSize = Point(-1, -1)
-        val bottomLocation: (textView: SimpleDigitalClockTextView) -> Int = { textView ->
+        val viewHeight: (textView: SimpleDigitalClockTextView) -> Int = { textView ->
             if (isMonoVerticalNumericLineSpacing) {
                 maxSingleDigitSize.y
             } else {
@@ -98,9 +98,15 @@
         digitalClockTextViewMap.forEach { (_, textView) ->
             textView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
             maxSingleDigitSize.x = max(maxSingleDigitSize.x, textView.measuredWidth)
-            maxSingleDigitSize.y = max(bottomLocation(textView), textView.measuredHeight)
+            maxSingleDigitSize.y = max(viewHeight(textView), textView.measuredHeight)
         }
         aodTranslate = Point(0, 0)
+        // TODO(b/364680879): Cleanup
+        /*
+        aodTranslate = Point(
+            (maxSingleDigitSize.x * AOD_HORIZONTAL_TRANSLATE_RATIO).toInt(),
+            (maxSingleDigitSize.y * AOD_VERTICAL_TRANSLATE_RATIO).toInt())
+        */
         return Point(
             ((maxSingleDigitSize.x + abs(aodTranslate.x)) * 2),
             ((maxSingleDigitSize.y + abs(aodTranslate.y)) * 2),
@@ -112,6 +118,10 @@
         digitLeftTopMap[R.id.HOUR_SECOND_DIGIT] = Point(maxSingleDigitSize.x, 0)
         digitLeftTopMap[R.id.MINUTE_FIRST_DIGIT] = Point(0, maxSingleDigitSize.y)
         digitLeftTopMap[R.id.MINUTE_SECOND_DIGIT] = Point(maxSingleDigitSize)
+        digitLeftTopMap[R.id.HOUR_DIGIT_PAIR] = Point(maxSingleDigitSize.x / 2, 0)
+        // Add a small vertical buffer for the second digit pair
+        digitLeftTopMap[R.id.MINUTE_DIGIT_PAIR] =
+            Point(maxSingleDigitSize.x / 2, (maxSingleDigitSize.y * 1.05f).toInt())
         digitLeftTopMap.forEach { (_, point) ->
             point.x += abs(aodTranslate.x)
             point.y += abs(aodTranslate.y)
@@ -179,9 +189,9 @@
             // save canvas location in anticipation of restoration later
             canvas.save()
             val xTranslateAmount =
-                digitOffsets.getOrDefault(id, 0f) + digitLeftTopMap[id]!!.x.toFloat()
+                digitOffsets.getOrDefault(id, 0f) + (digitLeftTopMap[id]?.x?.toFloat() ?: 0f)
             // move canvas to location that the textView would like
-            canvas.translate(xTranslateAmount, digitLeftTopMap[id]!!.y.toFloat())
+            canvas.translate(xTranslateAmount, digitLeftTopMap[id]?.y?.toFloat() ?: 0f)
             // draw the textView at the location of the canvas above
             textView.draw(canvas)
             // reset the canvas location back to 0 without drawing
@@ -189,8 +199,6 @@
         }
     }
 
-    fun isAlignedWithScreen(): Boolean = false
-
     fun onLocaleChanged(locale: Locale) {
         updateLocale(locale)
         requestLayout()
@@ -302,23 +310,17 @@
         clockMoveDirection: Int,
         moveFraction: Float,
     ) {
+        // TODO(b/393577936): The step animation isn't correct with the two pairs approach
         val isMovingToCenter = if (isLayoutRtl) clockMoveDirection < 0 else clockMoveDirection > 0
         // The sign of moveAmountDeltaForDigit is already set here
         // we can interpret (left - clockStartLeft) as (destinationPosition - originPosition)
         // so we no longer need to multiply direct sign to moveAmountDeltaForDigit
         val currentMoveAmount = left - clockStartLeft
-        for (i in 0 until NUM_DIGITS) {
-            val mapIndexToId =
-                when (i) {
-                    0 -> R.id.HOUR_FIRST_DIGIT
-                    1 -> R.id.HOUR_SECOND_DIGIT
-                    2 -> R.id.MINUTE_FIRST_DIGIT
-                    3 -> R.id.MINUTE_SECOND_DIGIT
-                    else -> -1
-                }
+        var index = 0
+        digitalClockTextViewMap.forEach { id, _ ->
             val digitFraction =
                 getDigitFraction(
-                    digit = i,
+                    digit = index++,
                     isMovingToCenter = isMovingToCenter,
                     fraction = moveFraction,
                 )
@@ -326,7 +328,7 @@
             val moveAmountForDigit = currentMoveAmount * digitFraction
             var moveAmountDeltaForDigit = moveAmountForDigit - currentMoveAmount
             if (isMovingToCenter && moveAmountForDigit < 0) moveAmountDeltaForDigit *= -1
-            digitOffsets[mapIndexToId] = moveAmountDeltaForDigit
+            digitOffsets[id] = moveAmountDeltaForDigit
             invalidate()
         }
     }
@@ -347,7 +349,8 @@
                 /* rangeMin= */ 0.0f,
                 /* rangeMax= */ 1.0f,
                 /* valueMin= */ digitInitialDelay,
-                /* valueMax= */ digitInitialDelay + AVAILABLE_ANIMATION_TIME,
+                /* valueMax= */ digitInitialDelay +
+                    availableAnimationTime(digitalClockTextViewMap.size),
                 /* value= */ fraction,
             )
         )
@@ -357,12 +360,8 @@
         val AOD_TRANSITION_DURATION = 750L
         val CHARGING_TRANSITION_DURATION = 300L
 
-        // Calculate the positions of all of the digits...
-        // Offset each digit by, say, 0.1
-        // This means that each digit needs to move over a slice of "fractions", i.e. digit 0 should
-        // move from 0.0 - 0.7, digit 1 from 0.1 - 0.8, digit 2 from 0.2 - 0.9, and digit 3
-        // from 0.3 - 1.0.
-        private const val NUM_DIGITS = 4
+        val AOD_HORIZONTAL_TRANSLATE_RATIO = -0.15F
+        val AOD_VERTICAL_TRANSLATE_RATIO = 0.075F
 
         // Delays. Each digit's animation should have a slight delay, so we get a nice
         // "stepping" effect. When moving right, the second digit of the hour should move first.
@@ -387,7 +386,9 @@
 
         // Total available transition time for each digit, taking into account the step. If step is
         // 0.1, then digit 0 would animate over 0.0 - 0.7, making availableTime 0.7.
-        private const val AVAILABLE_ANIMATION_TIME = 1.0f - MOVE_DIGIT_STEP * (NUM_DIGITS - 1)
+        private fun availableAnimationTime(numDigits: Int): Float {
+            return 1.0f - MOVE_DIGIT_STEP * (numDigits.toFloat() - 1)
+        }
 
         // Add language tags below that do not have vertically mono spaced numerals
         private val NON_MONO_VERTICAL_NUMERIC_LINE_SPACING_LANGUAGES =
@@ -415,6 +416,14 @@
                     outPoint.x *= 1
                     outPoint.y *= 1
                 }
+                R.id.HOUR_DIGIT_PAIR -> {
+                    outPoint.x *= -1
+                    outPoint.y *= -1
+                }
+                R.id.MINUTE_DIGIT_PAIR -> {
+                    outPoint.x *= -1
+                    outPoint.y *= 1
+                }
             }
             return outPoint
         }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
index db39162..13f5633 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
@@ -38,10 +38,13 @@
 import com.android.systemui.animation.TextAnimator
 import com.android.systemui.customization.R
 import com.android.systemui.plugins.clocks.ClockFontAxisSetting
+import com.android.systemui.plugins.clocks.ClockFontAxisSetting.Companion.replace
+import com.android.systemui.plugins.clocks.ClockFontAxisSetting.Companion.toFVar
 import com.android.systemui.plugins.clocks.ClockLogger
 import com.android.systemui.shared.clocks.ClockContext
 import com.android.systemui.shared.clocks.DigitTranslateAnimator
 import com.android.systemui.shared.clocks.DimensionParser
+import com.android.systemui.shared.clocks.FLEX_CLOCK_ID
 import com.android.systemui.shared.clocks.FontTextStyle
 import java.lang.Thread
 import kotlin.math.max
@@ -63,14 +66,32 @@
 }
 
 @SuppressLint("AppCompatCustomView")
-open class SimpleDigitalClockTextView(clockCtx: ClockContext, attrs: AttributeSet? = null) :
-    TextView(clockCtx.context, attrs) {
+open class SimpleDigitalClockTextView(
+    clockCtx: ClockContext,
+    isLargeClock: Boolean,
+    attrs: AttributeSet? = null,
+) : TextView(clockCtx.context, attrs) {
     val lockScreenPaint = TextPaint()
     lateinit var textStyle: FontTextStyle
     lateinit var aodStyle: FontTextStyle
 
-    private var lsFontVariation = ClockFontAxisSetting.toFVar(DEFAULT_LS_VARIATION)
-    private var aodFontVariation = ClockFontAxisSetting.toFVar(DEFAULT_AOD_VARIATION)
+    private val isLegacyFlex = clockCtx.settings.clockId == FLEX_CLOCK_ID
+    private val fixedAodAxes =
+        when {
+            !isLegacyFlex -> listOf(AOD_WEIGHT_AXIS, WIDTH_AXIS)
+            isLargeClock -> listOf(FLEX_AOD_LARGE_WEIGHT_AXIS, FLEX_AOD_WIDTH_AXIS)
+            else -> listOf(FLEX_AOD_SMALL_WEIGHT_AXIS, FLEX_AOD_WIDTH_AXIS)
+        }
+
+    private var lsFontVariation =
+        if (!isLegacyFlex) listOf(LS_WEIGHT_AXIS, WIDTH_AXIS, ROUND_AXIS, SLANT_AXIS).toFVar()
+        else listOf(FLEX_LS_WEIGHT_AXIS, FLEX_LS_WIDTH_AXIS, FLEX_ROUND_AXIS, SLANT_AXIS).toFVar()
+
+    private var aodFontVariation = run {
+        val roundAxis = if (!isLegacyFlex) ROUND_AXIS else FLEX_ROUND_AXIS
+        (fixedAodAxes + listOf(roundAxis, SLANT_AXIS)).toFVar()
+    }
+
     private val parser = DimensionParser(clockCtx.context)
     var maxSingleDigitHeight = -1
     var maxSingleDigitWidth = -1
@@ -129,8 +150,14 @@
         invalidate()
     }
 
-    fun updateAxes(axes: List<ClockFontAxisSetting>) {
-        lsFontVariation = ClockFontAxisSetting.toFVar(axes + OPTICAL_SIZE_AXIS)
+    fun updateAxes(lsAxes: List<ClockFontAxisSetting>) {
+        lsFontVariation = lsAxes.toFVar()
+        aodFontVariation = lsAxes.replace(fixedAodAxes).toFVar()
+        logger.i({ "updateAxes(LS = $str1, AOD = $str2)" }) {
+            str1 = lsFontVariation
+            str2 = aodFontVariation
+        }
+
         lockScreenPaint.typeface = typefaceCache.getTypefaceForVariant(lsFontVariation)
         typeface = lockScreenPaint.typeface
 
@@ -287,6 +314,7 @@
                 targetTextBounds,
             )
         }
+
         if (layout == null) {
             requestLayout()
         } else {
@@ -501,22 +529,18 @@
             Paint().also { it.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OUT) }
 
         val AOD_COLOR = Color.WHITE
-        val OPTICAL_SIZE_AXIS = ClockFontAxisSetting(GSFAxes.OPTICAL_SIZE, 144f)
-        val DEFAULT_LS_VARIATION =
-            listOf(
-                OPTICAL_SIZE_AXIS,
-                ClockFontAxisSetting(GSFAxes.WEIGHT, 400f),
-                ClockFontAxisSetting(GSFAxes.WIDTH, 100f),
-                ClockFontAxisSetting(GSFAxes.ROUND, 0f),
-                ClockFontAxisSetting(GSFAxes.SLANT, 0f),
-            )
-        val DEFAULT_AOD_VARIATION =
-            listOf(
-                OPTICAL_SIZE_AXIS,
-                ClockFontAxisSetting(GSFAxes.WEIGHT, 200f),
-                ClockFontAxisSetting(GSFAxes.WIDTH, 100f),
-                ClockFontAxisSetting(GSFAxes.ROUND, 0f),
-                ClockFontAxisSetting(GSFAxes.SLANT, 0f),
-            )
+        val LS_WEIGHT_AXIS = ClockFontAxisSetting(GSFAxes.WEIGHT, 400f)
+        val AOD_WEIGHT_AXIS = ClockFontAxisSetting(GSFAxes.WEIGHT, 200f)
+        val WIDTH_AXIS = ClockFontAxisSetting(GSFAxes.WIDTH, 85f)
+        val ROUND_AXIS = ClockFontAxisSetting(GSFAxes.ROUND, 0f)
+        val SLANT_AXIS = ClockFontAxisSetting(GSFAxes.SLANT, 0f)
+
+        // Axes for Legacy version of the Flex Clock
+        val FLEX_LS_WEIGHT_AXIS = ClockFontAxisSetting(GSFAxes.WEIGHT, 600f)
+        val FLEX_AOD_LARGE_WEIGHT_AXIS = ClockFontAxisSetting(GSFAxes.WEIGHT, 74f)
+        val FLEX_AOD_SMALL_WEIGHT_AXIS = ClockFontAxisSetting(GSFAxes.WEIGHT, 133f)
+        val FLEX_LS_WIDTH_AXIS = ClockFontAxisSetting(GSFAxes.WIDTH, 100f)
+        val FLEX_AOD_WIDTH_AXIS = ClockFontAxisSetting(GSFAxes.WIDTH, 43f)
+        val FLEX_ROUND_AXIS = ClockFontAxisSetting(GSFAxes.ROUND, 100f)
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardDisplayManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardDisplayManagerTest.kt
index cea1e96..3be9228 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardDisplayManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardDisplayManagerTest.kt
@@ -31,7 +31,6 @@
 import com.android.systemui.shade.data.repository.FakeShadeDisplayRepository
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import java.util.concurrent.Executor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.advanceUntilIdle
@@ -52,7 +51,6 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper
-@OptIn(ExperimentalCoroutinesApi::class)
 class KeyguardDisplayManagerTest : SysuiTestCase() {
     @Mock private val navigationBarController = mock(NavigationBarController::class.java)
     @Mock
diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
index d2b61c0..fe665e6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
@@ -13,8 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.keyguard
 
 import android.app.admin.DevicePolicyManager
@@ -88,7 +86,6 @@
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth
 import junit.framework.Assert
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runCurrent
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/AccessibilityRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/AccessibilityRepositoryTest.kt
index c4a92bf..84cbef8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/AccessibilityRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/AccessibilityRepositoryTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.accessibility.data.repository
 
 import android.view.accessibility.AccessibilityManager
@@ -26,7 +24,6 @@
 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.Rule
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/CaptioningRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/CaptioningRepositoryTest.kt
index fc57757..2cacea4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/CaptioningRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/CaptioningRepositoryTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.user.data.repository.userRepository
 import com.android.systemui.user.utils.FakeUserScopedService
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -41,7 +40,6 @@
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class CaptioningRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/ColorCorrectionRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/ColorCorrectionRepositoryImplTest.kt
index 801d359..e5be344 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/ColorCorrectionRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/ColorCorrectionRepositoryImplTest.kt
@@ -28,14 +28,12 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.settings.fakeSettings
 import com.google.common.truth.Truth
-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 ColorCorrectionRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/ColorInversionRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/ColorInversionRepositoryImplTest.kt
index 2f457be..0ed3dbc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/ColorInversionRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/ColorInversionRepositoryImplTest.kt
@@ -28,14 +28,12 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.settings.fakeSettings
 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 ColorInversionRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/NightDisplayRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/NightDisplayRepositoryTest.kt
index 54dbed8..e1db4c9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/NightDisplayRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/NightDisplayRepositoryTest.kt
@@ -39,7 +39,6 @@
 import com.android.systemui.utils.leaks.FakeLocationController
 import com.google.common.truth.Truth.assertThat
 import java.time.LocalTime
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
@@ -47,7 +46,6 @@
 import org.mockito.ArgumentMatchers
 import org.mockito.Mockito.verify
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class NightDisplayRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/OneHandedModeRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/OneHandedModeRepositoryImplTest.kt
index 729d356..b66b64a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/OneHandedModeRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/data/repository/OneHandedModeRepositoryImplTest.kt
@@ -27,13 +27,11 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.settings.fakeSettings
 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)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class OneHandedModeRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegateTest.kt
index b80836d..cde42bd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegateTest.kt
@@ -31,7 +31,6 @@
 import com.android.systemui.res.R
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.phone.SystemUIDialog
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -51,7 +50,6 @@
 import org.mockito.kotlin.verify
 
 /** Tests for [ExtraDimDialogDelegate]. */
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/assist/data/repository/AssistRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/assist/data/repository/AssistRepositoryTest.kt
index 80077a21..2abc44c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/assist/data/repository/AssistRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/assist/data/repository/AssistRepositoryTest.kt
@@ -23,13 +23,11 @@
 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.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AssistRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/assist/domain/interactor/AssistInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/assist/domain/interactor/AssistInteractorTest.kt
index c12f1ac..6c00ed8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/assist/domain/interactor/AssistInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/assist/domain/interactor/AssistInteractorTest.kt
@@ -25,13 +25,11 @@
 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.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class AssistInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
index f82c8b0..75ca375 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.authentication.data.repository
 
 import android.app.admin.DevicePolicyManager
@@ -40,7 +38,6 @@
 import com.google.common.truth.Truth.assertThat
 import java.util.function.Function
 import kotlin.time.Duration.Companion.seconds
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
index 080b48a..ae771cc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
@@ -36,7 +36,6 @@
 import com.android.systemui.user.data.repository.fakeUserRepository
 import com.google.common.truth.Truth.assertThat
 import kotlin.time.Duration.Companion.seconds
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.currentTime
 import kotlinx.coroutines.test.runCurrent
@@ -44,7 +43,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AuthenticationInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt
index cbb6f81..4d238ac 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt
@@ -61,7 +61,6 @@
 import com.google.common.truth.Truth.assertThat
 import junit.framework.Assert.assertFalse
 import junit.framework.Assert.assertTrue
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import org.junit.Before
 import org.junit.Rule
@@ -76,7 +75,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class BackActionInteractorTest : SysuiTestCase() {
     private val kosmos = Kosmos()
     private val testScope = kosmos.testScope
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index b8d4bb4..50762ed 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -16,7 +16,6 @@
 package com.android.systemui.biometrics
 
 import android.app.ActivityTaskManager
-import android.app.admin.DevicePolicyManager
 import android.content.pm.PackageManager
 import android.content.res.Configuration
 import android.hardware.biometrics.BiometricAuthenticator
@@ -43,6 +42,8 @@
 import com.android.app.viewcapture.ViewCapture
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.widget.LockPatternUtils
+import com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN
+import com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN
 import com.android.launcher3.icons.IconProvider
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.data.repository.FakeBiometricStatusRepository
@@ -432,8 +433,7 @@
                 .setMoreOptionsButtonListener(fakeExecutor) { _, _ -> isButtonClicked = true }
                 .build()
 
-        val container =
-            initializeFingerprintContainer(contentViewWithMoreOptionsButton = contentView)
+        val container = initializeFingerprintContainer()
 
         waitForIdleSync()
 
@@ -488,8 +488,7 @@
                 .build()
         val container =
             initializeFingerprintContainer(
-                authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL,
-                contentViewWithMoreOptionsButton = contentView,
+                authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
             )
         waitForIdleSync()
 
@@ -500,8 +499,8 @@
     @Test
     fun testCredentialViewUsesEffectiveUserId() {
         whenever(userManager.getCredentialOwnerProfile(anyInt())).thenReturn(200)
-        whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(eq(200)))
-            .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)
+        whenever(lockPatternUtils.getCredentialTypeForUser(eq(200)))
+            .thenReturn(CREDENTIAL_TYPE_PATTERN)
 
         val container =
             initializeFingerprintContainer(
@@ -578,8 +577,7 @@
         addToView: Boolean = true
     ): TestAuthContainerView {
         whenever(userManager.getCredentialOwnerProfile(anyInt())).thenReturn(20)
-        whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(eq(20)))
-            .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)
+        whenever(lockPatternUtils.getCredentialTypeForUser(eq(20))).thenReturn(CREDENTIAL_TYPE_PIN)
 
         // 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
@@ -599,7 +597,6 @@
         authenticators: Int = BiometricManager.Authenticators.BIOMETRIC_WEAK,
         addToView: Boolean = true,
         verticalListContentView: PromptVerticalListContentView? = null,
-        contentViewWithMoreOptionsButton: PromptContentViewWithMoreOptionsButton? = null,
     ) =
         initializeContainer(
             TestAuthContainerView(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
index 194b41f..002ed17 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
@@ -35,7 +35,6 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.res.R
 import com.android.systemui.util.mockito.whenever
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 
@@ -157,7 +156,6 @@
     return info
 }
 
-@OptIn(ExperimentalCoroutinesApi::class)
 internal fun TestScope.updateSfpsIndicatorRequests(
     kosmos: Kosmos,
     mContext: SysuiTestableContext,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/BiometricStatusRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/BiometricStatusRepositoryTest.kt
index d215047..881ee10 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/BiometricStatusRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/BiometricStatusRepositoryTest.kt
@@ -40,7 +40,6 @@
 import com.android.systemui.testKosmos
 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
@@ -52,7 +51,6 @@
 import org.mockito.junit.MockitoJUnit
 import org.mockito.junit.MockitoRule
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class BiometricStatusRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/DisplayStateRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/DisplayStateRepositoryTest.kt
index d9b7161..7a9f3ec 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/DisplayStateRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/DisplayStateRepositoryTest.kt
@@ -35,7 +35,6 @@
 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.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -45,7 +44,6 @@
 import org.junit.runner.RunWith
 import org.mockito.Mockito.spy
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DisplayStateRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt
index 9c11405..05312e9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt
@@ -37,7 +37,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import java.util.concurrent.Executor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -55,7 +54,6 @@
 import org.mockito.junit.MockitoJUnit
 import org.mockito.junit.MockitoRule
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FacePropertyRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/FaceSettingsRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/FaceSettingsRepositoryImplTest.kt
index 0209ab8..756442b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/FaceSettingsRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/FaceSettingsRepositoryImplTest.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.util.mockito.withArgCaptor
 import com.android.systemui.util.settings.SecureSettings
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -45,7 +44,6 @@
 
 private const val USER_ID = 8
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FaceSettingsRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/FingerprintRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/FingerprintRepositoryImplTest.kt
index ff5a419f..ffabc83 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/FingerprintRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/FingerprintRepositoryImplTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.biometrics.shared.model.SensorStrength
 import com.android.systemui.coroutines.collectLastValue
 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
@@ -45,7 +44,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FingerprintRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt
index 22971bc..1260771 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.util.mockito.withArgCaptor
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.toList
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.TestScope
@@ -49,7 +48,6 @@
 private const val CHALLENGE = 90L
 private const val OP_PACKAGE_NAME = "biometric.testapp"
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PromptRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/BiometricStatusInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/BiometricStatusInteractorImplTest.kt
index 5d2d20c..4622cbe 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/BiometricStatusInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/BiometricStatusInteractorImplTest.kt
@@ -32,7 +32,6 @@
 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.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -41,7 +40,6 @@
 import org.mockito.Mockito
 import org.mockito.Mockito.`when`
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class BiometricStatusInteractorImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractorImplTest.kt
index 58fe2c9..15816fd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractorImplTest.kt
@@ -21,7 +21,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.toList
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -40,7 +39,6 @@
 private const val OPERATION_ID = 100L
 private const val MAX_ATTEMPTS = 5
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class CredentialInteractorImplTest : SysuiTestCase() {
@@ -135,9 +133,9 @@
     private fun pinCredential(result: VerifyCredentialResponse, credentialOwner: Int = USER_ID) =
         runTest {
             val usedAttempts = 1
-            whenever(lockPatternUtils.getCurrentFailedPasswordAttempts(eq(USER_ID)))
+            whenever(lockPatternUtils.getCurrentFailedPasswordAttempts(eq(credentialOwner)))
                 .thenReturn(usedAttempts)
-            whenever(lockPatternUtils.verifyCredential(any(), eq(USER_ID), anyInt()))
+            whenever(lockPatternUtils.verifyCredential(any(), eq(credentialOwner), anyInt()))
                 .thenReturn(result)
             whenever(lockPatternUtils.verifyTiedProfileChallenge(any(), eq(USER_ID), anyInt()))
                 .thenReturn(result)
@@ -170,7 +168,7 @@
                 assertThat(successfulResult).isNotNull()
                 assertThat(successfulResult!!.hat).isEqualTo(result.gatekeeperHAT)
 
-                verify(lockPatternUtils).userPresent(eq(USER_ID))
+                verify(lockPatternUtils).userPresent(eq(credentialOwner))
                 verify(lockPatternUtils)
                     .removeGatekeeperPasswordHandle(eq(result.gatekeeperPasswordHandle))
             } else {
@@ -190,13 +188,13 @@
                         .hasSize(statusList.size)
 
                     verify(lockPatternUtils)
-                        .setLockoutAttemptDeadline(eq(USER_ID), eq(result.timeout))
+                        .setLockoutAttemptDeadline(eq(credentialOwner), eq(result.timeout))
                 } else { // failed
                     assertThat(failedResult.error)
                         .matches(Regex("(.*)try again(.*)", RegexOption.IGNORE_CASE).toPattern())
                     assertThat(statusList).isEmpty()
 
-                    verify(lockPatternUtils).reportFailedPasswordAttempt(eq(USER_ID))
+                    verify(lockPatternUtils).reportFailedPasswordAttempt(eq(credentialOwner))
                 }
             }
         }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt
index f40b6b0..f3d5dfb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt
@@ -14,7 +14,6 @@
 import com.android.systemui.util.mockito.withArgCaptor
 import com.android.systemui.util.time.FakeSystemClock
 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
@@ -27,7 +26,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DisplayStateInteractorImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorTest.kt
index 970ce1f..353d2b1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorTest.kt
@@ -29,13 +29,11 @@
 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.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FingerprintPropertyInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
index 30207bb..40928fa 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
@@ -41,7 +41,6 @@
 import com.android.systemui.scene.shared.model.Scenes
 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.Before
@@ -50,7 +49,6 @@
 import org.junit.runner.RunWith
 import org.mockito.junit.MockitoJUnit
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class LogContextInteractorImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt
index 5a36376..136dfef 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt
@@ -16,7 +16,6 @@
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.flowOf
@@ -37,7 +36,6 @@
 private const val OPERATION_ID = 100L
 private const val OP_PACKAGE_NAME = "biometric.testapp"
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PromptCredentialInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
index b39a888..97d5944 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
@@ -41,7 +41,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -51,7 +50,6 @@
 import org.mockito.Mock
 import org.mockito.junit.MockitoJUnit
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PromptSelectorInteractorImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/SideFpsSensorInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/SideFpsSensorInteractorTest.kt
index a862112..4d967d6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/SideFpsSensorInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/SideFpsSensorInteractorTest.kt
@@ -55,7 +55,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import java.util.Optional
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -69,7 +68,6 @@
 import org.mockito.Mockito.spy
 import org.mockito.junit.MockitoJUnit
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class SideFpsSensorInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
index 297aee5c..63b9d4f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.res.R
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -50,7 +49,6 @@
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.junit.MockitoJUnit
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class UdfpsOverlayInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
index 57df662..4d02708 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
@@ -37,7 +37,6 @@
 import com.android.systemui.res.R
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.eq
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -59,7 +58,6 @@
 import org.mockito.junit.MockitoRule
 import org.mockito.kotlin.firstValue
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt
index e4c5cd4..3e10507 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt
@@ -10,7 +10,6 @@
 import com.android.systemui.biometrics.promptInfo
 import com.android.systemui.biometrics.shared.model.PromptKind
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.toList
 import kotlinx.coroutines.launch
@@ -25,7 +24,6 @@
 private const val REQUEST_ID = 9L
 private const val OPERATION_ID = 10L
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class CredentialViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/DefaultUdfpsTouchOverlayViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/DefaultUdfpsTouchOverlayViewModelTest.kt
index 0d01472..a194c8e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/DefaultUdfpsTouchOverlayViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/DefaultUdfpsTouchOverlayViewModelTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.statusbar.phone.systemUIDialogManager
 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.Before
@@ -46,7 +45,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class DefaultUdfpsTouchOverlayViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelTest.kt
index 77ddd31..ce43c5f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelTest.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.statusbar.phone.systemUIDialogManager
 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.Before
@@ -40,7 +39,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceEntryUdfpsTouchOverlayViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
index 66f44ba..b6c6347 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
@@ -77,7 +77,6 @@
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.android.msdl.data.model.MSDLToken
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.TestScope
@@ -107,7 +106,6 @@
 private const val OP_PACKAGE_NAME_NO_LOGO_INFO = "biometric.testapp.nologoinfo"
 private const val OP_PACKAGE_NAME_CAN_NOT_BE_FOUND = "can.not.be.found"
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
index 831012c..9f90fb8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
@@ -48,7 +48,6 @@
 import com.android.systemui.unfold.compat.ScreenSizeFoldProvider
 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.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -63,7 +62,6 @@
 import org.mockito.junit.MockitoJUnit
 import org.mockito.junit.MockitoRule
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class SideFpsOverlayViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegateTest.kt
index 9f0c7e1..b4200b6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegateTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runCurrent
@@ -45,7 +44,6 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-@OptIn(ExperimentalCoroutinesApi::class)
 class AudioSharingDialogDelegateTest : SysuiTestCase() {
     @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
     private val kosmos = testKosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModelTest.kt
index 32606e0..3bb023f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModelTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.res.R
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
@@ -50,7 +49,6 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-@OptIn(ExperimentalCoroutinesApi::class)
 class AudioSharingDialogViewModelTest : SysuiTestCase() {
     @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
     private val kosmos = testKosmos().apply { testDispatcher = UnconfinedTestDispatcher() }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt
index cebd05d..682ad0c5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt
@@ -27,7 +27,6 @@
 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.launch
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -48,7 +47,6 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-@OptIn(ExperimentalCoroutinesApi::class)
 class AudioSharingInteractorTest : SysuiTestCase() {
     @get:Rule val mockito: MockitoRule = MockitoJUnit.rule()
     private val kosmos = testKosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepositoryTest.kt
index f074606..587f3cc8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepositoryTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
 import com.android.systemui.volume.data.repository.audioSharingRepository
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -44,7 +43,6 @@
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorTest.kt
index cee17c3..5b108c8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorTest.kt
@@ -31,7 +31,6 @@
 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.flow.MutableSharedFlow
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runCurrent
@@ -52,7 +51,6 @@
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorTest.kt
index ad0337e..9803bb9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorTest.kt
@@ -24,7 +24,6 @@
 import com.android.systemui.statusbar.phone.SystemUIDialog
 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
@@ -40,7 +39,6 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-@OptIn(ExperimentalCoroutinesApi::class)
 class DeviceItemActionInteractorTest : SysuiTestCase() {
     @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
     private val kosmos = testKosmos().apply { testDispatcher = UnconfinedTestDispatcher() }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/data/repository/EmergencyServicesRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/data/repository/EmergencyServicesRepositoryImplTest.kt
index d317aeb..1aa9c19 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/data/repository/EmergencyServicesRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/data/repository/EmergencyServicesRepositoryImplTest.kt
@@ -26,7 +26,6 @@
 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.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -34,7 +33,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @android.platform.test.annotations.EnabledOnRavenwood
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt
index b391b5a..3fbb022 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -176,7 +175,6 @@
         }
 
     /** Emits a new sim card state and collects the last value of the flow argument. */
-    @OptIn(ExperimentalCoroutinesApi::class)
     private fun <T> TestScope.emitSubscriptionIdAndCollectLastValue(
         flow: Flow<T>,
         subId: Int = 1,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt
index 10bf523..f376e93 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerActionButtonInteractorTest.kt
@@ -43,7 +43,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.telecom.telecomManager
 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
@@ -55,7 +54,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableSceneContainer
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
index 521b346..dd4af7b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
@@ -46,7 +46,6 @@
 import com.android.systemui.util.settings.fakeGlobalSettings
 import com.google.common.truth.Truth.assertThat
 import kotlin.time.Duration.Companion.seconds
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -55,7 +54,6 @@
 import org.junit.runner.RunWith
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableSceneContainer
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt
index 65c9b72..d098f28 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt
@@ -53,7 +53,6 @@
 import com.android.systemui.util.mockito.KotlinArgumentCaptor
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -67,7 +66,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt
index bd1403a..3b50e4b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt
@@ -35,7 +35,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -52,7 +51,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class SimBouncerInteractorTest : SysuiTestCase() {
     @Mock lateinit var telephonyManager: TelephonyManager
     @Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt
index a6ed37e..d8a9719 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt
@@ -63,12 +63,12 @@
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.domain.startable.sceneContainerStartable
 import com.android.systemui.scene.sceneContainerViewModelFactory
+import com.android.systemui.scene.sceneTransitionsBuilder
 import com.android.systemui.scene.shared.model.SceneContainerConfig
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.sceneDataSourceDelegator
 import com.android.systemui.scene.ui.composable.Scene
 import com.android.systemui.scene.ui.composable.SceneContainer
-import com.android.systemui.scene.ui.composable.SceneContainerTransitions
 import com.android.systemui.scene.ui.view.sceneJankMonitorFactory
 import com.android.systemui.testKosmos
 import kotlin.time.Duration.Companion.seconds
@@ -96,6 +96,7 @@
 import platform.test.motion.golden.UnknownTypeException
 import platform.test.screenshot.DeviceEmulationSpec
 import platform.test.screenshot.Displays.Phone
+import kotlin.test.Ignore
 
 /** MotionTest for the Bouncer Predictive Back animation */
 @LargeTest
@@ -120,9 +121,9 @@
         SceneContainerConfig(
             sceneKeys,
             initialSceneKey,
-            SceneContainerTransitions,
             emptyList(),
             navigationDistances,
+            sceneTransitionsBuilder,
         )
     }
     private val view = mock<View>()
@@ -172,6 +173,7 @@
     }
 
     @Test
+    @Ignore("b/394049206: Update the goldens and re-enable this test.")
     fun bouncerPredictiveBackMotion() =
         motionTestRule.runTest(timeout = 30.seconds) {
             val motion =
@@ -190,7 +192,7 @@
                                         Scenes.Bouncer to bouncerScene,
                                     ),
                                 initialSceneKey = Scenes.Bouncer,
-                                sceneTransitions = SceneContainerTransitions,
+                                transitionsBuilder = kosmos.sceneTransitionsBuilder,
                                 overlayByKey = emptyMap(),
                                 dataSourceDelegator = kosmos.sceneDataSourceDelegator,
                                 qsSceneAdapter = { kosmos.fakeQsSceneAdapter },
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
index 9552564..edd115f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.testKosmos
 import com.google.android.msdl.data.model.MSDLToken
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -90,7 +89,6 @@
             assertThat(animateFailure).isFalse()
         }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     @EnableFlags(Flags.FLAG_MSDL_FEEDBACK)
     fun onAuthenticationResult_playUnlockTokenIfSuccessful() =
@@ -109,7 +107,6 @@
             assertThat(msdlPlayer.latestPropertiesPlayed).isEqualTo(authInteractionProperties)
         }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     @EnableFlags(Flags.FLAG_MSDL_FEEDBACK)
     fun onAuthenticationResult_playFailureTokenIfFailure() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt
index 8c8faee..482a067 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt
@@ -59,7 +59,6 @@
 import com.android.systemui.user.data.repository.fakeUserRepository
 import com.google.common.truth.Truth.assertThat
 import kotlin.time.Duration.Companion.seconds
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.currentTime
@@ -69,7 +68,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableFlags(Flags.FLAG_COMPOSE_BOUNCER)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModelTest.kt
index 94f6769..eef8d9f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModelTest.kt
@@ -46,7 +46,6 @@
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.launchIn
@@ -59,7 +58,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableSceneContainer
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt
index d371592..e12fabf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerUserActionsViewModelTest.kt
@@ -32,14 +32,12 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.truth.containsEntriesExactly
 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)
 @EnableSceneContainer
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt
index 1a43501..61c74cc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt
@@ -51,7 +51,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 class KeyguardBouncerViewModelTest : SysuiTestCase() {
 
     @Mock lateinit var bouncerView: BouncerView
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
index 29ee874..b2d2458 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
@@ -47,7 +47,6 @@
 import com.google.common.truth.Truth.assertThat
 import java.util.UUID
 import kotlin.time.Duration.Companion.seconds
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
@@ -57,7 +56,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PasswordBouncerViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
index 0490a26..ec7d1c3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
@@ -41,7 +41,6 @@
 import com.google.android.msdl.data.model.MSDLToken
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.test.TestScope
@@ -51,7 +50,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PatternBouncerViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
index af5f2ac..705e834 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
@@ -49,7 +49,6 @@
 import kotlin.random.Random
 import kotlin.random.nextInt
 import kotlin.test.assertTrue
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.test.TestScope
@@ -59,7 +58,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PinBouncerViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/ScreenBrightnessDisplayManagerRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/ScreenBrightnessDisplayManagerRepositoryTest.kt
index 2e8efdb..8c748f0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/ScreenBrightnessDisplayManagerRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/ScreenBrightnessDisplayManagerRepositoryTest.kt
@@ -38,7 +38,6 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
 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
@@ -53,7 +52,6 @@
 import org.mockito.junit.MockitoJUnit
 import org.mockito.junit.MockitoRule
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ScreenBrightnessDisplayManagerRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractorTest.kt
index 18e7a7e..39146d2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractorTest.kt
@@ -30,13 +30,11 @@
 import com.android.systemui.log.table.logcatTableLogBuffer
 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)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ScreenBrightnessInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt
index 2d093bf..6deb525 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt
@@ -26,10 +26,8 @@
 import com.android.systemui.brightness.shared.model.GammaBrightness
 import com.android.systemui.brightness.shared.model.LinearBrightness
 import com.android.systemui.classifier.domain.interactor.falsingInteractor
-import com.android.systemui.common.shared.model.ContentDescription
-import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.common.shared.model.Text
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.graphics.imageLoader
 import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.lifecycle.activateIn
@@ -38,14 +36,12 @@
 import com.android.systemui.settings.brightness.ui.brightnessWarningToast
 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.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class BrightnessSliderViewModelTest : SysuiTestCase() {
@@ -65,6 +61,7 @@
                 falsingInteractor,
                 supportsMirroring = true,
                 brightnessWarningToast,
+                imageLoader,
             )
         }
     }
@@ -162,20 +159,21 @@
         }
 
     @Test
-    fun label() {
-        assertThat(underTest.label)
-            .isEqualTo(Text.Resource(R.string.quick_settings_brightness_dialog_title))
-    }
-
-    @Test
     fun icon() {
-        assertThat(underTest.icon)
-            .isEqualTo(
-                Icon.Resource(
-                    R.drawable.ic_brightness_full,
-                    ContentDescription.Resource(underTest.label.res),
-                )
-            )
+        assertThat(BrightnessSliderViewModel.getIconForPercentage(0f))
+            .isEqualTo(R.drawable.ic_brightness_low)
+        assertThat(BrightnessSliderViewModel.getIconForPercentage(20f))
+            .isEqualTo(R.drawable.ic_brightness_low)
+        assertThat(BrightnessSliderViewModel.getIconForPercentage(20.1f))
+            .isEqualTo(R.drawable.ic_brightness_medium)
+        assertThat(BrightnessSliderViewModel.getIconForPercentage(50f))
+            .isEqualTo(R.drawable.ic_brightness_medium)
+        assertThat(BrightnessSliderViewModel.getIconForPercentage(79.9f))
+            .isEqualTo(R.drawable.ic_brightness_medium)
+        assertThat(BrightnessSliderViewModel.getIconForPercentage(80f))
+            .isEqualTo(R.drawable.ic_brightness_full)
+        assertThat(BrightnessSliderViewModel.getIconForPercentage(100f))
+            .isEqualTo(R.drawable.ic_brightness_full)
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt
index 667d364..648d74d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt
@@ -26,13 +26,11 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.util.settings.fakeSettings
 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)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class CameraAutoRotateRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt
index 29de58e..b73a212 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.util.mockito.mock
 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
@@ -35,7 +34,6 @@
 import org.mockito.ArgumentMatchers
 import org.mockito.Mockito
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @android.platform.test.annotations.EnabledOnRavenwood
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt
index f75e036..6c8097e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt
@@ -23,13 +23,11 @@
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.kosmos.Kosmos
 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)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @android.platform.test.annotations.EnabledOnRavenwood
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt
index 7fa1be3..7161c2c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt
@@ -23,13 +23,11 @@
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.kosmos.Kosmos
 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)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @android.platform.test.annotations.EnabledOnRavenwood
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/coroutine/CoroutineResultTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/coroutine/CoroutineResultTest.kt
index de07cda..5128650 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/coroutine/CoroutineResultTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/coroutine/CoroutineResultTest.kt
@@ -19,14 +19,12 @@
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
 /** atest SystemUITests:CoroutineResultTest */
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class CoroutineResultTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/data/repository/PackageInstallerMonitorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/data/repository/PackageInstallerMonitorTest.kt
index 4c908dd..781e416 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/data/repository/PackageInstallerMonitorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/data/repository/PackageInstallerMonitorTest.kt
@@ -36,7 +36,6 @@
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Correspondence
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -48,7 +47,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PackageInstallerMonitorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/data/repository/PackageUpdateMonitorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/data/repository/PackageUpdateMonitorTest.kt
index 35d9d3f..3e0c19e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/data/repository/PackageUpdateMonitorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/data/repository/PackageUpdateMonitorTest.kt
@@ -34,7 +34,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.fakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.launchIn
@@ -47,7 +46,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PackageUpdateMonitorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/domain/interactor/PackageChangeInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/domain/interactor/PackageChangeInteractorTest.kt
index a164e7c..19bc04bf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/domain/interactor/PackageChangeInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/domain/interactor/PackageChangeInteractorTest.kt
@@ -31,7 +31,6 @@
 import com.android.systemui.user.data.repository.fakeUserRepository
 import com.android.systemui.user.domain.interactor.selectedUserInteractor
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -39,7 +38,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PackageChangeInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/ui/data/repository/ConfigurationRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/ui/data/repository/ConfigurationRepositoryImplTest.kt
index 205f944..a2c647d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/ui/data/repository/ConfigurationRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/ui/data/repository/ConfigurationRepositoryImplTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.util.mockito.withArgCaptor
 import com.android.systemui.util.wrapper.DisplayUtilsWrapper
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -42,7 +41,6 @@
 import org.mockito.MockitoAnnotations
 import org.mockito.kotlin.clearInvocations
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ConfigurationRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractorTest.kt
index 5994afa..4a960fe 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractorTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -38,7 +37,6 @@
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.whenever
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ConfigurationInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/ui/view/LongPressHandlingViewInteractionHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/ui/view/LongPressHandlingViewInteractionHandlerTest.kt
index f06cd6a..262c590 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/common/ui/view/LongPressHandlingViewInteractionHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/common/ui/view/LongPressHandlingViewInteractionHandlerTest.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.DisposableHandle
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -39,7 +38,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class LongPressHandlingViewInteractionHandlerTest : SysuiTestCase() {
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 00d5afe..ad7df9e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt
@@ -42,7 +42,6 @@
 import com.android.systemui.power.shared.model.ScreenPowerState
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.whenever
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -54,7 +53,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
 @RunWith(ParameterizedAndroidJunit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalOngoingContentStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalOngoingContentStartableTest.kt
index 9113617..e53155d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalOngoingContentStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalOngoingContentStartableTest.kt
@@ -32,14 +32,12 @@
 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.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnableFlags(FLAG_COMMUNAL_HUB)
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
index 68f4acd..6f2082b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalSceneStartableTest.kt
@@ -58,7 +58,6 @@
 import com.android.systemui.util.settings.fakeSettings
 import com.google.common.truth.Truth.assertThat
 import kotlin.time.Duration.Companion.milliseconds
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
@@ -72,7 +71,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 @EnableFlags(FLAG_COMMUNAL_HUB)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/db/DefaultWidgetPopulationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/db/DefaultWidgetPopulationTest.kt
index f1c58a2..3eb0800 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/db/DefaultWidgetPopulationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/db/DefaultWidgetPopulationTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.log.logcatLogBuffer
 import com.android.systemui.testKosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -45,7 +44,6 @@
 import org.mockito.kotlin.verify
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class DefaultWidgetPopulationTest : SysuiTestCase() {
     private val kosmos = testKosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalMediaRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalMediaRepositoryImplTest.kt
index 2b0928f..c6196d4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalMediaRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalMediaRepositoryImplTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.whenever
 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
@@ -37,7 +36,6 @@
 import org.mockito.kotlin.argumentCaptor
 import org.mockito.kotlin.mock
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @android.platform.test.annotations.EnabledOnRavenwood
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 b6359c7..3682dce 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
@@ -34,7 +34,6 @@
 import com.android.systemui.settings.fakeUserFileManager
 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
@@ -44,7 +43,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.kotlin.spy
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class CommunalPrefsRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSceneRepositoryImplTest.kt
similarity index 60%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalRepositoryImplTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSceneRepositoryImplTest.kt
index fd0bf4d..293d324 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSceneRepositoryImplTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,34 +21,44 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.communal.shared.model.CommunalScenes
-import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.scene.shared.model.sceneDataSource
+import com.android.systemui.kosmos.backgroundScope
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.scene.shared.model.SceneDataSource
+import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.flowOf
-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
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-class CommunalRepositoryImplTest : SysuiTestCase() {
+class CommunalSceneRepositoryImplTest : SysuiTestCase() {
+    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
 
-    private val kosmos = testKosmos()
-    private val testScope = kosmos.testScope
-    private val underTest by lazy {
-        CommunalSceneRepositoryImpl(
-            kosmos.applicationCoroutineScope,
-            kosmos.applicationCoroutineScope,
-            kosmos.sceneDataSource,
-        )
-    }
+    private val delegator = mock<SceneDataSourceDelegator> {}
+
+    private val Kosmos.underTest by
+        Kosmos.Fixture {
+            CommunalSceneRepositoryImpl(
+                applicationScope = applicationCoroutineScope,
+                backgroundScope = backgroundScope,
+                sceneDataSource = delegator,
+                delegator = delegator,
+            )
+        }
 
     @Test
     fun transitionState_idleByDefault() =
-        testScope.runTest {
+        kosmos.runTest {
             val transitionState by collectLastValue(underTest.transitionState)
             assertThat(transitionState)
                 .isEqualTo(ObservableTransitionState.Idle(CommunalScenes.Default))
@@ -56,7 +66,7 @@
 
     @Test
     fun transitionState_setTransitionState_returnsNewValue() =
-        testScope.runTest {
+        kosmos.runTest {
             val expectedSceneKey = CommunalScenes.Communal
             underTest.setTransitionState(flowOf(ObservableTransitionState.Idle(expectedSceneKey)))
 
@@ -66,7 +76,7 @@
 
     @Test
     fun transitionState_setNullTransitionState_returnsDefaultValue() =
-        testScope.runTest {
+        kosmos.runTest {
             // Set a value for the transition state flow.
             underTest.setTransitionState(
                 flowOf(ObservableTransitionState.Idle(CommunalScenes.Communal))
@@ -80,4 +90,18 @@
             assertThat(transitionState)
                 .isEqualTo(ObservableTransitionState.Idle(CommunalScenes.Default))
         }
+
+    @Test
+    fun showHubFromPowerButton() =
+        kosmos.runTest {
+            fakeKeyguardRepository.setKeyguardShowing(false)
+
+            underTest.showHubFromPowerButton()
+
+            argumentCaptor<SceneDataSource>().apply {
+                verify(delegator).setDelegate(capture())
+
+                assertThat(firstValue.currentScene.value).isEqualTo(CommunalScenes.Communal)
+            }
+        }
 }
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 eb1f1d9..5c98365 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
@@ -51,6 +51,7 @@
 import com.android.systemui.util.settings.fakeSettings
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
+import org.junit.After
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -78,6 +79,32 @@
         setKeyguardFeaturesDisabled(PRIMARY_USER, KEYGUARD_DISABLE_FEATURES_NONE)
         setKeyguardFeaturesDisabled(SECONDARY_USER, KEYGUARD_DISABLE_FEATURES_NONE)
         setKeyguardFeaturesDisabled(WORK_PROFILE, KEYGUARD_DISABLE_FEATURES_NONE)
+
+        mContext.orCreateTestableResources.addOverride(
+            com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault,
+            false,
+        )
+        mContext.orCreateTestableResources.addOverride(
+            com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault,
+            false,
+        )
+        mContext.orCreateTestableResources.addOverride(
+            com.android.internal.R.bool.config_dreamsActivatedOnPosturedByDefault,
+            false,
+        )
+    }
+
+    @After
+    fun tearDown() {
+        mContext.orCreateTestableResources.removeOverride(
+            com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault
+        )
+        mContext.orCreateTestableResources.removeOverride(
+            com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault
+        )
+        mContext.orCreateTestableResources.removeOverride(
+            com.android.internal.R.bool.config_dreamsActivatedOnPosturedByDefault
+        )
     }
 
     @EnableFlags(FLAG_COMMUNAL_HUB)
@@ -334,6 +361,18 @@
         }
 
     @Test
+    fun whenToDream_charging_defaultValue() =
+        kosmos.runTest {
+            mContext.orCreateTestableResources.addOverride(
+                com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault,
+                true,
+            )
+
+            val whenToDreamState by collectLastValue(underTest.getWhenToDreamState(PRIMARY_USER))
+            assertThat(whenToDreamState).isEqualTo(WhenToDream.WHILE_CHARGING)
+        }
+
+    @Test
     fun whenToDream_docked() =
         kosmos.runTest {
             val whenToDreamState by collectLastValue(underTest.getWhenToDreamState(PRIMARY_USER))
@@ -348,6 +387,18 @@
         }
 
     @Test
+    fun whenToDream_docked_defaultValue() =
+        kosmos.runTest {
+            mContext.orCreateTestableResources.addOverride(
+                com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault,
+                true,
+            )
+
+            val whenToDreamState by collectLastValue(underTest.getWhenToDreamState(PRIMARY_USER))
+            assertThat(whenToDreamState).isEqualTo(WhenToDream.WHILE_DOCKED)
+        }
+
+    @Test
     fun whenToDream_postured() =
         kosmos.runTest {
             val whenToDreamState by collectLastValue(underTest.getWhenToDreamState(PRIMARY_USER))
@@ -362,6 +413,18 @@
         }
 
     @Test
+    fun whenToDream_postured_defaultValue() =
+        kosmos.runTest {
+            mContext.orCreateTestableResources.addOverride(
+                com.android.internal.R.bool.config_dreamsActivatedOnPosturedByDefault,
+                true,
+            )
+
+            val whenToDreamState by collectLastValue(underTest.getWhenToDreamState(PRIMARY_USER))
+            assertThat(whenToDreamState).isEqualTo(WhenToDream.WHILE_POSTURED)
+        }
+
+    @Test
     fun whenToDream_default() =
         kosmos.runTest {
             val whenToDreamState by collectLastValue(underTest.getWhenToDreamState(PRIMARY_USER))
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepositoryImplTest.kt
index 1a426d6..4e12a16 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSmartspaceRepositoryImplTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.time.fakeSystemClock
 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
@@ -47,7 +46,6 @@
 import org.mockito.kotlin.verify
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class CommunalSmartspaceRepositoryImplTest : SysuiTestCase() {
     private val kosmos = testKosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalBackActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalBackActionInteractorTest.kt
index c365f1c..70f38f7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalBackActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalBackActionInteractorTest.kt
@@ -29,12 +29,10 @@
 import com.android.systemui.kosmos.runTest
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class CommunalBackActionInteractorTest : SysuiTestCase() {
     private val kosmos = testKosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorCommunalDisabledTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorCommunalDisabledTest.kt
index cebcbc9..beec184 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorCommunalDisabledTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorCommunalDisabledTest.kt
@@ -31,7 +31,6 @@
 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.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -42,7 +41,6 @@
  * This class is a variation of the [CommunalInteractorTest] for cases where communal is disabled.
  */
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class CommunalInteractorCommunalDisabledTest : SysuiTestCase() {
     private val kosmos = testKosmos()
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 c9e7a5d..c3cc3e6 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
@@ -21,6 +21,7 @@
 import android.app.admin.devicePolicyManager
 import android.content.Intent
 import android.content.pm.UserInfo
+import android.content.res.mainResources
 import android.os.UserHandle
 import android.os.UserManager
 import android.os.userManager
@@ -85,6 +86,7 @@
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.advanceTimeBy
+import org.junit.After
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -106,7 +108,10 @@
         UserInfo(/* id= */ 0, /* name= */ "primary user", /* flags= */ UserInfo.FLAG_MAIN)
     private val secondaryUser = UserInfo(/* id= */ 1, /* name= */ "secondary user", /* flags= */ 0)
 
-    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+    private val kosmos =
+        testKosmos()
+            .apply { mainResources = mContext.orCreateTestableResources.resources }
+            .useUnconfinedTestDispatcher()
 
     private val Kosmos.underTest by Kosmos.Fixture { communalInteractor }
 
@@ -122,6 +127,32 @@
 
         kosmos.fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, true)
         mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB)
+
+        mContext.orCreateTestableResources.addOverride(
+            com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault,
+            false,
+        )
+        mContext.orCreateTestableResources.addOverride(
+            com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault,
+            false,
+        )
+        mContext.orCreateTestableResources.addOverride(
+            com.android.internal.R.bool.config_dreamsActivatedOnPosturedByDefault,
+            false,
+        )
+    }
+
+    @After
+    fun tearDown() {
+        mContext.orCreateTestableResources.removeOverride(
+            com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault
+        )
+        mContext.orCreateTestableResources.removeOverride(
+            com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault
+        )
+        mContext.orCreateTestableResources.removeOverride(
+            com.android.internal.R.bool.config_dreamsActivatedOnPosturedByDefault
+        )
     }
 
     @Test
@@ -398,6 +429,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
     fun ctaTile_showsByDefault() =
         kosmos.runTest {
             fakeCommunalTutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED)
@@ -412,6 +444,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
     fun ctaTile_afterDismiss_doesNotShow() =
         kosmos.runTest {
             // Set to main user, so we can dismiss the tile for the main user.
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 6a9b9be..77d7091 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
@@ -35,7 +35,6 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
 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.advanceTimeBy
@@ -126,7 +125,6 @@
             assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
         }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @DisableFlags(FLAG_SCENE_CONTAINER)
     @Test
     fun snapToSceneWithDelay() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractorTest.kt
index d5020a5..ff722bf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractorTest.kt
@@ -51,7 +51,6 @@
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.time.Duration.Companion.seconds
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.flowOf
@@ -63,7 +62,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableFlags(FLAG_COMMUNAL_HUB, FLAG_COMMUNAL_SCENE_KTF_REFACTOR)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractorTest.kt
index 8a9c42d..feee9e3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalTutorialInteractorTest.kt
@@ -36,7 +36,6 @@
 import com.android.systemui.user.data.repository.FakeUserRepository
 import com.android.systemui.user.data.repository.fakeUserRepository
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -44,7 +43,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class CommunalTutorialInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/WidgetTrampolineInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/WidgetTrampolineInteractorTest.kt
index d6734e8..d15ec2f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/WidgetTrampolineInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/WidgetTrampolineInteractorTest.kt
@@ -38,7 +38,6 @@
 import kotlin.time.Duration
 import kotlin.time.Duration.Companion.milliseconds
 import kotlin.time.Duration.Companion.seconds
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
@@ -56,7 +55,6 @@
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class WidgetTrampolineInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/log/CommunalLoggerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/log/CommunalLoggerStartableTest.kt
index 28ad269..358cae7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/log/CommunalLoggerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/log/CommunalLoggerStartableTest.kt
@@ -31,7 +31,6 @@
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.flow.flowOf
@@ -48,7 +47,6 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class CommunalLoggerStartableTest : SysuiTestCase() {
     @Mock private lateinit var uiEventLogger: UiEventLogger
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelTest.kt
index 0084e18..1a3606e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelTest.kt
@@ -35,7 +35,6 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -45,7 +44,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class CommunalTransitionViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModelTest.kt
index 5510710..c158baf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModelTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.communal.ui.viewmodel
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -46,7 +44,6 @@
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModelTest.kt
index bea1010..3ad7981 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModelTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.lifecycle.activateIn
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -34,7 +33,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ResizeableItemFrameViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/widgets/CommunalAppWidgetHostTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/widgets/CommunalAppWidgetHostTest.kt
index 18513fc..30c41c8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/widgets/CommunalAppWidgetHostTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/widgets/CommunalAppWidgetHostTest.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
 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
@@ -42,7 +41,6 @@
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWithLooper(setAsMainLooper = true)
 @RunWith(AndroidJUnit4::class)
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 b70f46c..dbdd7fb 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
@@ -29,6 +29,7 @@
 import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
 import com.android.systemui.Flags.FLAG_COMMUNAL_RESPONSIVE_GRID
 import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_DIRECT_EDIT_MODE
+import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
 import com.android.systemui.communal.data.model.CommunalSmartspaceTimer
@@ -94,7 +95,6 @@
 import com.android.systemui.user.data.repository.FakeUserRepository
 import com.android.systemui.user.data.repository.fakeUserRepository
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
@@ -116,7 +116,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
@@ -219,6 +218,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
     fun ordering_smartspaceBeforeUmoBeforeWidgetsBeforeCtaTile() =
         testScope.runTest {
             tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
@@ -258,7 +258,7 @@
 
     /** TODO(b/378171351): Handle ongoing content in responsive grid. */
     @Test
-    @DisableFlags(FLAG_COMMUNAL_RESPONSIVE_GRID)
+    @DisableFlags(FLAG_COMMUNAL_RESPONSIVE_GRID, FLAG_GLANCEABLE_HUB_V2)
     fun ongoingContent_umoAndOneTimer_sizedAppropriately() =
         testScope.runTest {
             // Widgets available.
@@ -296,7 +296,7 @@
 
     /** TODO(b/378171351): Handle ongoing content in responsive grid. */
     @Test
-    @DisableFlags(FLAG_COMMUNAL_RESPONSIVE_GRID)
+    @DisableFlags(FLAG_COMMUNAL_RESPONSIVE_GRID, FLAG_GLANCEABLE_HUB_V2)
     fun ongoingContent_umoAndTwoTimers_sizedAppropriately() =
         testScope.runTest {
             // Widgets available.
@@ -342,6 +342,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
     fun communalContent_mediaHostVisible_umoIncluded() =
         testScope.runTest {
             // Media playing.
@@ -353,6 +354,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
     fun communalContent_mediaHostVisible_umoExcluded() =
         testScope.runTest {
             whenever(mediaHost.visible).thenReturn(false)
@@ -408,6 +410,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
     fun dismissCta_hidesCtaTileAndShowsPopup_thenHidesPopupAfterTimeout() =
         testScope.runTest {
             setIsMainUser(true)
@@ -734,6 +737,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
     fun communalContent_emitsFrozenContent_whenFrozen() =
         testScope.runTest {
             val communalContent by collectLastValue(underTest.communalContent)
@@ -790,6 +794,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
     fun communalContent_emitsLatestContent_whenNotFrozen() =
         testScope.runTest {
             val communalContent by collectLastValue(underTest.communalContent)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt
index 9ef2b19..9568194 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt
@@ -41,7 +41,6 @@
 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.MutableSharedFlow
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -53,7 +52,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class CommunalAppWidgetHostStartableTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalTransitionAnimatorControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalTransitionAnimatorControllerTest.kt
index a052b07..a4261b0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalTransitionAnimatorControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalTransitionAnimatorControllerTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runTest
 import org.junit.Assert.assertFalse
@@ -37,7 +36,6 @@
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.verify
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class CommunalTransitionAnimatorControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/EditWidgetsActivityControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/EditWidgetsActivityControllerTest.kt
index 3ba8625..9525496 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/EditWidgetsActivityControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/EditWidgetsActivityControllerTest.kt
@@ -22,7 +22,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.argumentCaptor
@@ -32,7 +31,6 @@
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class EditWidgetsActivityControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/EditWidgetsActivityStarterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/EditWidgetsActivityStarterTest.kt
index 48b42d5..807023c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/EditWidgetsActivityStarterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/EditWidgetsActivityStarterTest.kt
@@ -25,7 +25,6 @@
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -37,7 +36,6 @@
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class EditWidgetsActivityStarterTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/GlanceableHubWidgetManagerServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/GlanceableHubWidgetManagerServiceTest.kt
index c3c958c..a2f702c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/GlanceableHubWidgetManagerServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/GlanceableHubWidgetManagerServiceTest.kt
@@ -39,7 +39,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -54,7 +53,6 @@
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetConfigurationControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetConfigurationControllerTest.kt
index e1bdf1c..8ad9048 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetConfigurationControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetConfigurationControllerTest.kt
@@ -31,7 +31,6 @@
 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.async
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -47,7 +46,6 @@
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class WidgetConfigurationControllerTest : SysuiTestCase() {
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 9c308a60..ed4e73a 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
@@ -36,7 +36,6 @@
 import com.android.systemui.log.logcatLogBuffer
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.testKosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Assert.assertFalse
@@ -52,7 +51,6 @@
 import org.mockito.kotlin.refEq
 import org.mockito.kotlin.verify
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class WidgetInteractionHandlerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/DreamClockTimeComplicationTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/DreamClockTimeComplicationTest.java
index 22ab499..92ccf12 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/DreamClockTimeComplicationTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/DreamClockTimeComplicationTest.java
@@ -23,7 +23,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
-import android.view.View;
+import android.widget.TextClock;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
@@ -41,6 +41,8 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.Locale;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class DreamClockTimeComplicationTest extends SysuiTestCase {
@@ -68,7 +70,7 @@
     private ComplicationViewModel mComplicationViewModel;
 
     @Mock
-    private View mView;
+    private TextClock mView;
 
     @Mock
     private ComplicationLayoutParams mLayoutParams;
@@ -86,6 +88,7 @@
         MockitoAnnotations.initMocks(this);
         when(mComponentFactory.create()).thenReturn(mComponent);
         when(mComponent.getViewHolder()).thenReturn(mDreamClockTimeViewHolder);
+        when(mView.getTextLocale()).thenReturn(Locale.US);
         mMonitor = SelfExecutingMonitor.createInstance();
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/controls/panels/SelectedComponentRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/controls/panels/SelectedComponentRepositoryTest.kt
index 86e3481..0545665 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/controls/panels/SelectedComponentRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/controls/panels/SelectedComponentRepositoryTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import java.io.File
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -42,7 +41,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@ExperimentalCoroutinesApi
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class SelectedComponentRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/controls/settings/ControlsSettingsRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/controls/settings/ControlsSettingsRepositoryImplTest.kt
index 3bdd5cf..43945fa 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/controls/settings/ControlsSettingsRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/controls/settings/ControlsSettingsRepositoryImplTest.kt
@@ -25,7 +25,6 @@
 import com.android.systemui.user.data.repository.FakeUserRepository
 import com.android.systemui.util.settings.FakeSettings
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.toList
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.TestScope
@@ -37,7 +36,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class ControlsSettingsRepositoryImplTest : SysuiTestCase() {
 
     companion object {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/controls/start/ControlsStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/controls/start/ControlsStartableTest.kt
index 0d8312e..11c6fed 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/controls/start/ControlsStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/controls/start/ControlsStartableTest.kt
@@ -57,7 +57,6 @@
 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.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -73,7 +72,6 @@
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ControlsStartableTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/coroutines/FlowTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/coroutines/FlowTest.kt
index 23da3f1..7a77f0d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/coroutines/FlowTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/coroutines/FlowTest.kt
@@ -4,13 +4,11 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FlowTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/demomode/DemoModeControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/demomode/DemoModeControllerTest.kt
index 4793a52f3..014a418 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/demomode/DemoModeControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/demomode/DemoModeControllerTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.util.settings.FakeGlobalSettings
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
@@ -39,7 +38,6 @@
 import org.mockito.MockitoAnnotations
 
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 @SmallTest
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
index 79115ae..844c9bf 100644
--- 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
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.deviceconfig.data.repository
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -27,7 +25,6 @@
 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
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index 71abed7..f6016c6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -93,7 +93,6 @@
 import com.google.common.truth.Truth.assertThat
 import java.io.PrintWriter
 import java.io.StringWriter
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.TestScope
@@ -116,7 +115,6 @@
 import org.mockito.Mockito.verifyNoMoreInteractions
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt
index 73373d55..89ad668 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt
@@ -13,7 +13,6 @@
 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.runBlocking
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -24,7 +23,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @android.platform.test.annotations.EnabledOnRavenwood
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/AuthRippleInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/AuthRippleInteractorTest.kt
index 3005d0b..5e2e07c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/AuthRippleInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/AuthRippleInteractorTest.kt
@@ -27,13 +27,11 @@
 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.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AuthRippleInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt
index 6fd8660..f44b9fe 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt
@@ -45,14 +45,12 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.whenever
 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
 import org.mockito.ArgumentMatchers.anyInt
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class BiometricMessageInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricSettingsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricSettingsInteractorTest.kt
index 4a7757b..2d69227 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricSettingsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricSettingsInteractorTest.kt
@@ -24,12 +24,10 @@
 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.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceEntryBiometricSettingsInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricsAllowedInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricsAllowedInteractorTest.kt
index 295a626..46b2986c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricsAllowedInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricsAllowedInteractorTest.kt
@@ -30,12 +30,10 @@
 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.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceEntryBiometricsAllowedInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
index a0c56b4..329627a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
@@ -61,7 +61,6 @@
 import com.android.systemui.user.data.repository.fakeUserRepository
 import com.android.systemui.util.mockito.eq
 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.TestScope
@@ -74,7 +73,6 @@
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorTest.kt
index 6022d9c..886351c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthStatusInteractorTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.res.R
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -42,7 +41,6 @@
 import org.junit.runner.RunWith
 import org.mockito.Mockito.mock
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceEntryFaceAuthStatusInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorTest.kt
index 5fd480f..e051500 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorTest.kt
@@ -56,7 +56,6 @@
 import com.android.systemui.statusbar.phone.screenOffAnimationController
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
@@ -68,7 +67,6 @@
 import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
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 1bb5c9a..84f08f1 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
@@ -49,7 +49,6 @@
 import com.android.systemui.statusbar.sysuiStatusBarStateController
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -58,7 +57,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableSceneContainer
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractorTest.kt
index b3c891d..a5c0da5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntrySourceInteractorTest.kt
@@ -52,7 +52,6 @@
 import com.android.systemui.statusbar.policy.devicePostureController
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -62,7 +61,6 @@
 import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceEntrySourceInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorTest.kt
index d5839b5..db594a5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractorTest.kt
@@ -31,13 +31,11 @@
 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.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceEntryUdfpsInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt
index 0302336..1ce2bc9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt
@@ -49,7 +49,6 @@
 import com.android.systemui.user.domain.interactor.selectedUserInteractor
 import com.android.systemui.util.settings.fakeSettings
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
@@ -59,7 +58,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceUnlockedInteractorTest : SysuiTestCase() {
@@ -570,7 +568,7 @@
             unlockDevice()
             assertThat(isUnlocked).isTrue()
 
-            underTest.lockNow()
+            underTest.lockNow("test")
             runCurrent()
 
             assertThat(isUnlocked).isFalse()
@@ -597,6 +595,62 @@
             assertThat(deviceUnlockStatus?.isUnlocked).isFalse()
         }
 
+    @Test
+    fun deviceUnlockStatus_staysUnlocked_whenDeviceGoesToSleep_whileIsTrusted() =
+        testScope.runTest {
+            setLockAfterScreenTimeout(5000)
+            kosmos.fakeAuthenticationRepository.powerButtonInstantlyLocks = false
+            val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
+
+            kosmos.fakeTrustRepository.setCurrentUserTrusted(true)
+
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+            runCurrent()
+            assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
+
+            kosmos.powerInteractor.setAsleepForTest(
+                sleepReason = PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON
+            )
+            runCurrent()
+
+            assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
+        }
+
+    @Test
+    fun deviceUnlockStatus_staysUnlocked_whileIsTrusted() =
+        testScope.runTest {
+            val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
+            kosmos.fakeTrustRepository.setCurrentUserTrusted(true)
+            unlockDevice()
+
+            kosmos.powerInteractor.setAsleepForTest(
+                sleepReason = PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON
+            )
+            runCurrent()
+
+            assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
+        }
+
+    @Test
+    fun deviceUnlockStatus_becomesLocked_whenNoLongerTrusted_whileAsleep() =
+        testScope.runTest {
+            val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
+            kosmos.fakeTrustRepository.setCurrentUserTrusted(true)
+            unlockDevice()
+            kosmos.powerInteractor.setAsleepForTest(
+                sleepReason = PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON
+            )
+            runCurrent()
+            assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
+
+            kosmos.fakeTrustRepository.setCurrentUserTrusted(false)
+            runCurrent()
+
+            assertThat(deviceUnlockStatus?.isUnlocked).isFalse()
+        }
+
     private fun TestScope.unlockDevice() {
         val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt
index a981e20..f14ab53 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt
@@ -47,7 +47,6 @@
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -61,7 +60,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.kotlin.mock
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/ui/binder/LiftToRunFaceAuthBinderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/ui/binder/LiftToRunFaceAuthBinderTest.kt
index 11cade2..6b3136f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/ui/binder/LiftToRunFaceAuthBinderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/ui/binder/LiftToRunFaceAuthBinderTest.kt
@@ -35,7 +35,6 @@
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.sensors.asyncSensorManager
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -49,7 +48,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/ui/viewmodel/UdfpsAccessibilityOverlayViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/ui/viewmodel/UdfpsAccessibilityOverlayViewModelTest.kt
index 2d54337..9050083 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/ui/viewmodel/UdfpsAccessibilityOverlayViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/ui/viewmodel/UdfpsAccessibilityOverlayViewModelTest.kt
@@ -41,7 +41,6 @@
 import com.android.systemui.testKosmos
 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.junit.After
@@ -50,7 +49,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class UdfpsAccessibilityOverlayViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DeviceStateRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DeviceStateRepositoryTest.kt
index bec8a30..6457184 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DeviceStateRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DeviceStateRepositoryTest.kt
@@ -40,7 +40,6 @@
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
@@ -53,7 +52,6 @@
 
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 class DeviceStateRepositoryTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayMetricsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayMetricsRepositoryTest.kt
index d79db5c..c3759ca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayMetricsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayMetricsRepositoryTest.kt
@@ -27,7 +27,6 @@
 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.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -37,7 +36,6 @@
 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/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
index c585d5c..dfea784 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
@@ -34,7 +34,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.utils.os.FakeHandler
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
@@ -50,7 +49,6 @@
 
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 class DisplayRepositoryTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt
index a2b50fd..92ea01e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt
@@ -39,7 +39,6 @@
 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.launchIn
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.test.TestScope
@@ -53,7 +52,6 @@
 
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 class ConnectedDisplayInteractorTest : SysuiTestCase() {
 
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 0df584f..526510a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
@@ -83,7 +83,6 @@
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -107,7 +106,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @RunWith(ParameterizedAndroidJunit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsComponentInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsComponentInteractorTest.kt
index c950523..f347668 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsComponentInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsComponentInteractorTest.kt
@@ -39,7 +39,6 @@
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Truth.assertThat
 import java.util.Optional
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -48,7 +47,6 @@
 import org.junit.runner.RunWith
 import org.mockito.Mockito.verify
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class HomeControlsComponentInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsDreamServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsDreamServiceTest.kt
index 4317b9f..e56bd0a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsDreamServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsDreamServiceTest.kt
@@ -40,7 +40,6 @@
 import com.android.systemui.util.wakelock.WakeLockFake
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.resetMain
 import kotlinx.coroutines.test.runCurrent
@@ -60,7 +59,6 @@
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class HomeControlsDreamServiceTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsDreamStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsDreamStartableTest.kt
index ef02817..0b6b976 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsDreamStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/HomeControlsDreamStartableTest.kt
@@ -44,7 +44,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.user.data.repository.fakeUserRepository
 import java.util.Optional
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -59,7 +58,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class HomeControlsDreamStartableTest(flags: FlagsParameterization) : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/service/HomeControlsRemoteProxyTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/service/HomeControlsRemoteProxyTest.kt
index e57776f..38f1902 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/service/HomeControlsRemoteProxyTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/service/HomeControlsRemoteProxyTest.kt
@@ -25,14 +25,12 @@
 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.launch
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class HomeControlsRemoteProxyTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/service/RemoteHomeControlsDataSourceDelegatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/service/RemoteHomeControlsDataSourceDelegatorTest.kt
index 4002175..2b86f6b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/service/RemoteHomeControlsDataSourceDelegatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/service/RemoteHomeControlsDataSourceDelegatorTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.util.service.ObservableServiceConnection
 import com.android.systemui.util.service.PersistentConnectionManager
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -44,7 +43,6 @@
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class RemoteHomeControlsDataSourceDelegatorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/system/HomeControlsRemoteServiceBinderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/system/HomeControlsRemoteServiceBinderTest.kt
index b343def..a2ff5b4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/system/HomeControlsRemoteServiceBinderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/homecontrols/system/HomeControlsRemoteServiceBinderTest.kt
@@ -46,7 +46,6 @@
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Truth.assertThat
 import java.util.Optional
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -56,7 +55,6 @@
 import org.mockito.Mockito
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class HomeControlsRemoteServiceBinderTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt
index e567062..1c93b3c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.dreams.ui.viewmodel
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -46,7 +44,6 @@
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dump/DumpHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dump/DumpHandlerTest.kt
index 5976292..09c4231 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dump/DumpHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dump/DumpHandlerTest.kt
@@ -275,7 +275,9 @@
 
     @Test
     fun testDumpAllProtoDumpables() {
+        @Suppress("DEPRECATION")
         dumpManager.registerDumpable("protoDumpable1", protoDumpable1)
+        @Suppress("DEPRECATION")
         dumpManager.registerDumpable("protoDumpable2", protoDumpable2)
 
         val args = arrayOf(DumpHandler.PROTO)
@@ -287,7 +289,9 @@
 
     @Test
     fun testDumpSingleProtoDumpable() {
+        @Suppress("DEPRECATION")
         dumpManager.registerDumpable("protoDumpable1", protoDumpable1)
+        @Suppress("DEPRECATION")
         dumpManager.registerDumpable("protoDumpable2", protoDumpable2)
 
         val args = arrayOf(DumpHandler.PROTO, "protoDumpable1")
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorParameterizedTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorParameterizedTest.kt
index 6899d23..e126b4d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorParameterizedTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorParameterizedTest.kt
@@ -57,7 +57,6 @@
 
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 class KeyboardTouchpadEduInteractorParameterizedTest(private val gestureType: GestureType) :
     SysuiTestCase() {
     private val kosmos = testKosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
index dc393c0..adcd849 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
@@ -50,7 +50,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 class KeyboardTouchpadEduInteractorTest : SysuiTestCase() {
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/ui/view/ContextualEduUiCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/ui/view/ContextualEduUiCoordinatorTest.kt
index 248b922..6cb6fed 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/ui/view/ContextualEduUiCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/ui/view/ContextualEduUiCoordinatorTest.kt
@@ -63,7 +63,6 @@
 
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
-@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
 class ContextualEduUiCoordinatorTest(private val gestureType: GestureType) : SysuiTestCase() {
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/flags/NotOccludedConditionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/flags/NotOccludedConditionTest.kt
index 46b4c4b..ae2c483 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/flags/NotOccludedConditionTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/flags/NotOccludedConditionTest.kt
@@ -22,7 +22,6 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestDispatcher
@@ -39,7 +38,6 @@
 /**
  * Be careful with the {FeatureFlagsReleaseRestarter} in this test. It has a call to System.exit()!
  */
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class NotOccludedConditionTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/globalactions/data/repository/GlobalActionsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/globalactions/data/repository/GlobalActionsRepositoryTest.kt
index e437c10..e46bfb7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/globalactions/data/repository/GlobalActionsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/globalactions/data/repository/GlobalActionsRepositoryTest.kt
@@ -23,14 +23,12 @@
 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.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 GlobalActionsRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/globalactions/domain/interactor/GlobalActionsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/globalactions/domain/interactor/GlobalActionsInteractorTest.kt
index 92755120..afb9bd3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/globalactions/domain/interactor/GlobalActionsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/globalactions/domain/interactor/GlobalActionsInteractorTest.kt
@@ -23,14 +23,12 @@
 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.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 GlobalActionsInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/msdl/qs/TileHapticsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/msdl/qs/TileHapticsViewModelTest.kt
index f6a6e54..891d6f9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/msdl/qs/TileHapticsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/msdl/qs/TileHapticsViewModelTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.testKosmos
 import com.google.android.msdl.data.model.MSDLToken
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -39,7 +38,6 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class TileHapticsViewModelTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/HapticSliderPluginTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/HapticSliderPluginTest.kt
index 0881010..5030d1e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/HapticSliderPluginTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/HapticSliderPluginTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.util.time.fakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.advanceTimeBy
@@ -44,7 +43,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class HapticSliderPluginTest : SysuiTestCase() {
 
     private val kosmos = Kosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/SliderStateTrackerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/SliderStateTrackerTest.kt
index 2e9d993..8060f7b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/SliderStateTrackerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/SliderStateTrackerTest.kt
@@ -21,7 +21,6 @@
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runTest
@@ -35,7 +34,6 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class SliderStateTrackerTest : SysuiTestCase() {
 
@@ -102,7 +100,6 @@
 
     // Tests on the WAIT state
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun waitCompletes_onWait_movesToHandleAcquired() = runTest {
         val config = SeekableSliderTrackerConfig()
@@ -716,7 +713,6 @@
         assertThat(mSliderStateTracker.currentState).isEqualTo(SliderState.IDLE)
     }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     private fun initTracker(
         scope: CoroutineScope,
         config: SeekableSliderTrackerConfig = SeekableSliderTrackerConfig(),
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/compose/ui/SliderHapticsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/compose/ui/SliderHapticsViewModelTest.kt
index 8693f6b..895ef9cd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/compose/ui/SliderHapticsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/compose/ui/SliderHapticsViewModelTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.lifecycle.activateIn
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.test.runCurrent
@@ -39,7 +38,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class SliderHapticsViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepositoryTest.kt
index f2e43fc..798c5ab 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepositoryTest.kt
@@ -38,7 +38,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
 class UserInputDeviceRepositoryTest : SysuiTestCase() {
 
     private lateinit var underTest: UserInputDeviceRepository
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialNotificationCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialNotificationCoordinatorTest.kt
index 886aa51..e0082da 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialNotificationCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialNotificationCoordinatorTest.kt
@@ -35,7 +35,6 @@
 import com.android.systemui.touchpad.data.repository.FakeTouchpadRepository
 import com.google.common.truth.Truth.assertThat
 import kotlin.time.Duration.Companion.hours
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -51,7 +50,6 @@
 import org.mockito.kotlin.never
 import org.mockito.kotlin.verify
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class TutorialNotificationCoordinatorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt
index 722451e..e87aca4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.touchpad.data.repository.FakeTouchpadRepository
 import com.google.common.truth.Truth.assertThat
 import kotlin.time.Duration.Companion.hours
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.advanceTimeBy
@@ -39,7 +38,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class TutorialSchedulerInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt
index 1de38ee..57bcc14 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt
@@ -44,7 +44,6 @@
 import com.android.systemui.util.coroutines.MainDispatcherRule
 import com.google.common.truth.Truth.assertThat
 import java.util.Optional
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.TestScope
@@ -55,7 +54,6 @@
 import org.junit.runner.RunWith
 import org.mockito.kotlin.mock
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyboardTouchpadTutorialViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/backlight/domain/interactor/KeyboardBacklightInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/backlight/domain/interactor/KeyboardBacklightInteractorTest.kt
index 64cd091..92d3dbae 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/backlight/domain/interactor/KeyboardBacklightInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/backlight/domain/interactor/KeyboardBacklightInteractorTest.kt
@@ -24,14 +24,12 @@
 import com.android.systemui.keyboard.data.repository.FakeKeyboardRepository
 import com.android.systemui.keyboard.shared.model.BacklightModel
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.first
 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 KeyboardBacklightInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/backlight/ui/KeyboardBacklightDialogCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/backlight/ui/KeyboardBacklightDialogCoordinatorTest.kt
index 47261a9..cd5e54b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/backlight/ui/KeyboardBacklightDialogCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/backlight/ui/KeyboardBacklightDialogCoordinatorTest.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
@@ -44,7 +43,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyboardBacklightDialogCoordinatorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt
index 8b13411..4976fce 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt
@@ -36,7 +36,6 @@
 import com.android.systemui.utils.os.FakeHandler
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.test.StandardTestDispatcher
@@ -54,7 +53,6 @@
 import org.mockito.kotlin.any
 import org.mockito.kotlin.anyOrNull
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @TestableLooper.RunWithLooper
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ShortcutHelperCoreStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ShortcutHelperCoreStartableTest.kt
index b417616..25b5972 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ShortcutHelperCoreStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ShortcutHelperCoreStartableTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.plugins.activityStarter
 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
@@ -37,7 +36,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class ShortcutHelperCoreStartableTest : SysuiTestCase() {
     private val kosmos = testKosmos()
     private val repo = kosmos.shortcutHelperStateRepository
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/DefaultShortcutCategoriesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/DefaultShortcutCategoriesRepositoryTest.kt
index cd05980..e5991e8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/DefaultShortcutCategoriesRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/DefaultShortcutCategoriesRepositoryTest.kt
@@ -62,7 +62,6 @@
 import com.android.systemui.res.R
 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
@@ -72,7 +71,6 @@
 import org.mockito.Mockito.mock
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DefaultShortcutCategoriesRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
index 6149098..800886b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
@@ -51,7 +51,6 @@
 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.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -69,7 +68,6 @@
     private val systemShortcutsSource = FakeKeyboardShortcutGroupsSource()
     private val multitaskingShortcutsSource = FakeKeyboardShortcutGroupsSource()
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     private val kosmos =
         testKosmos().also {
             it.testDispatcher = UnconfinedTestDispatcher()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt
index 7a34335..1bb4805 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt
@@ -44,7 +44,6 @@
 import com.android.systemui.settings.userTracker
 import com.android.systemui.statusbar.phone.systemUIDialogFactory
 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
@@ -53,7 +52,6 @@
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ShortcutHelperDialogStarterTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
index cf38072..7667448 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
@@ -66,7 +66,6 @@
 import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SHORTCUT_HELPER_SHOWING
 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
@@ -77,7 +76,6 @@
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ShortcutHelperViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt
index 727481e..be9e93c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt
@@ -30,7 +30,6 @@
 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.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -40,7 +39,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class StickyKeysIndicatorCoordinatorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/viewmodel/StickyKeysIndicatorViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/viewmodel/StickyKeysIndicatorViewModelTest.kt
index 7ec53df..9daf0ff 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/viewmodel/StickyKeysIndicatorViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/viewmodel/StickyKeysIndicatorViewModelTest.kt
@@ -43,7 +43,6 @@
 import com.android.systemui.util.settings.data.repository.userAwareSecureSettingsRepository
 import com.android.systemui.util.settings.fakeSettings
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -54,7 +53,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class StickyKeysIndicatorViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
index 6b49d3a..32a631b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
@@ -21,7 +21,6 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
 import com.android.systemui.utils.GlobalWindowManager
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -34,7 +33,6 @@
 import org.mockito.Mockito.verifyNoMoreInteractions
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class ResourceTrimmerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt
index 56e8185..577f222 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
@@ -40,7 +39,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @android.platform.test.annotations.EnabledOnRavenwood
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 451ebf3..e999c16 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
@@ -52,7 +52,6 @@
 import com.android.systemui.util.settings.fakeSettings
 import com.google.common.truth.Truth.assertThat
 import java.time.Duration
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Assert.assertEquals
@@ -67,7 +66,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DoNotDisturbQuickAffordanceConfigTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
index 77e0f4e..1159049 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.statusbar.policy.FlashlightController
 import com.android.systemui.utils.leaks.FakeFlashlightController
 import com.android.systemui.utils.leaks.LeakCheckedTest
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.toList
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
@@ -39,7 +38,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @android.platform.test.annotations.EnabledOnRavenwood
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceHapticViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceHapticViewModelTest.kt
index 18946f9..11401af 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceHapticViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceHapticViewModelTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -37,7 +36,6 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceHapticViewModelTest : SysuiTestCase() {
 
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 8c54ca1..c787a8b 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
@@ -23,7 +23,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.kosmos.useUnconfinedTestDispatcher
@@ -37,7 +36,6 @@
 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.test.advanceUntilIdle
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -48,7 +46,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceLegacySettingSyncerTest : SysuiTestCase() {
@@ -85,7 +82,6 @@
                             .thenReturn(FakeSharedPreferences())
                     },
                 userTracker = FakeUserTracker(),
-                communalSettingsInteractor = kosmos.communalSettingsInteractor,
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
         settings.putInt(Settings.Secure.LOCKSCREEN_SHOW_CONTROLS, 0)
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 bc2c2d2..d93b77b 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
@@ -20,22 +20,17 @@
 import android.content.Intent
 import android.content.SharedPreferences
 import android.content.pm.UserInfo
-import android.platform.test.annotations.EnableFlags
 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.backup.BackupHelper
-import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
 import com.android.systemui.res.R
 import com.android.systemui.settings.FakeUserTracker
 import com.android.systemui.settings.UserFileManager
-import com.android.systemui.testKosmos
 import com.android.systemui.util.FakeSharedPreferences
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.toList
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
@@ -54,11 +49,9 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceLocalUserSelectionManagerTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
 
     @Mock private lateinit var userFileManager: UserFileManager
 
@@ -85,7 +78,6 @@
                 context = context,
                 userFileManager = userFileManager,
                 userTracker = userTracker,
-                communalSettingsInteractor = kosmos.communalSettingsInteractor,
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
     }
@@ -315,27 +307,6 @@
             )
     }
 
-    @EnableFlags(Flags.FLAG_GLANCEABLE_HUB_V2)
-    @Test
-    fun getSelections_returnsSelectionsIfHubV2Enabled() = runTest {
-        overrideResource(R.bool.custom_lockscreen_shortcuts_enabled, false)
-        overrideResource(com.android.internal.R.bool.config_glanceableHubEnabled, true)
-
-        overrideResource(R.array.config_keyguardQuickAffordanceDefaults, arrayOf<String>())
-        val affordanceIdsBySlotId = mutableListOf<Map<String, List<String>>>()
-        val job =
-            launch(UnconfinedTestDispatcher()) {
-                underTest.selections.toList(affordanceIdsBySlotId)
-            }
-        val slotId1 = "slot1"
-        val affordanceId1 = "affordance1"
-
-        underTest.setSelections(slotId = slotId1, affordanceIds = listOf(affordanceId1))
-        assertSelections(affordanceIdsBySlotId.last(), mapOf(slotId1 to listOf(affordanceId1)))
-
-        job.cancel()
-    }
-
     private fun assertSelections(
         observed: Map<String, List<String>>?,
         expected: Map<String, List<String>>,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
index a1c9f87..2e71310 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.toList
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.StandardTestDispatcher
@@ -41,7 +40,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceRemoteUserSelectionManagerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
index 173b4e5..115055d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.whenever
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -43,7 +42,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MuteQuickAffordanceConfigTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt
index 42b3463..3e67b89 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.cancelChildren
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.StandardTestDispatcher
@@ -51,7 +50,6 @@
 import org.mockito.Mockito.verifyNoMoreInteractions
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MuteQuickAffordanceCoreStartableTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
index a9b9c90..ee5188e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
@@ -30,7 +30,6 @@
 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.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
@@ -42,7 +41,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class VideoCameraQuickAffordanceConfigTest : SysuiTestCase() {
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 4e8a2a3..8e484cc 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
@@ -59,7 +59,6 @@
 import com.android.systemui.util.mockito.eq
 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.TestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -79,10 +78,10 @@
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.doAnswer
 import org.mockito.kotlin.doReturn
 import org.mockito.kotlin.stub
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @RunWith(AndroidJUnit4::class)
@@ -473,6 +472,51 @@
         }
 
     @Test
+    @EnableFlags(com.android.settings.flags.Flags.FLAG_BIOMETRICS_ONBOARDING_EDUCATION)
+    fun registerEnabledOnKeyguardCallback_multipleUsers_shouldSendAllUpdates() =
+        testScope.runTest {
+
+            // Simulate call to register callback when in multiple users setup
+            biometricManager.stub {
+                on { registerEnabledOnKeyguardCallback(any()) } doAnswer
+                        { invocation ->
+                            val callback =
+                                invocation.arguments[0] as IBiometricEnabledOnKeyguardCallback
+                            callback.onChanged(true, PRIMARY_USER_ID, TYPE_FACE)
+                            callback.onChanged(true, PRIMARY_USER_ID, TYPE_FINGERPRINT)
+                            callback.onChanged(true, ANOTHER_USER_ID, TYPE_FACE)
+                            callback.onChanged(true, ANOTHER_USER_ID, TYPE_FINGERPRINT)
+                        }
+            }
+            authController.stub {
+                on { isFingerprintEnrolled(anyInt()) } doReturn true
+                on { isFaceAuthEnrolled(anyInt()) } doReturn true
+            }
+
+            // Check primary user status
+            createBiometricSettingsRepository()
+            var fingerprintAllowed = collectLastValue(underTest.isFingerprintEnrolledAndEnabled)
+            var faceAllowed = collectLastValue(underTest.isFaceAuthEnrolledAndEnabled)
+            runCurrent()
+
+            enrollmentChange(UNDER_DISPLAY_FINGERPRINT, PRIMARY_USER_ID, true)
+            enrollmentChange(FACE, PRIMARY_USER_ID, true)
+            assertThat(fingerprintAllowed()).isTrue()
+            assertThat(faceAllowed()).isTrue()
+
+            // Check secondary user status
+            userRepository.setSelectedUserInfo(ANOTHER_USER)
+            fingerprintAllowed = collectLastValue(underTest.isFingerprintEnrolledAndEnabled)
+            faceAllowed = collectLastValue(underTest.isFaceAuthEnrolledAndEnabled)
+            runCurrent()
+
+            enrollmentChange(UNDER_DISPLAY_FINGERPRINT, ANOTHER_USER_ID, true)
+            enrollmentChange(FACE, ANOTHER_USER_ID, true)
+            assertThat(fingerprintAllowed()).isTrue()
+            assertThat(faceAllowed()).isTrue()
+        }
+
+    @Test
     fun devicePolicyControlsFaceAuthenticationEnabledState() =
         testScope.runTest {
             faceAuthIsEnrolled()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
index 9bcc19d..f3f9fa7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.filterIsInstance
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
@@ -48,7 +47,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @android.platform.test.annotations.EnabledOnRavenwood
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
index a0b8542..f40555f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
@@ -24,7 +24,6 @@
 import com.android.systemui.statusbar.policy.DevicePostureController
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
@@ -37,7 +36,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @android.platform.test.annotations.EnabledOnRavenwood
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyEventRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyEventRepositoryTest.kt
index bbe45c1..c7f1525 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyEventRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyEventRepositoryTest.kt
@@ -25,7 +25,6 @@
 import com.android.systemui.keyevent.data.repository.KeyEventRepositoryImpl
 import com.android.systemui.statusbar.CommandQueue
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -39,7 +38,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyEventRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryTest.kt
index 972ca02..13d09e8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryTest.kt
@@ -15,8 +15,6 @@
  *
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.keyguard.data.repository
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -31,7 +29,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.ThreadAssert
 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.runTest
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 a101818..b0e07be 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
@@ -22,7 +22,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceConfig
 import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceProviderClientFactory
@@ -46,7 +45,6 @@
 import com.android.systemui.util.settings.fakeSettings
 import com.google.common.truth.Truth.assertThat
 import java.util.Locale
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
 import org.junit.After
 import org.junit.Before
@@ -55,7 +53,6 @@
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.anyString
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
@@ -89,7 +86,6 @@
                             .thenReturn(FakeSharedPreferences())
                     },
                 userTracker = userTracker,
-                communalSettingsInteractor = kosmos.communalSettingsInteractor,
                 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 6805a13..ec7031a 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
@@ -45,7 +45,6 @@
 import com.android.systemui.util.mockito.withArgCaptor
 import com.android.systemui.util.time.FakeSystemClock
 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.StandardTestDispatcher
@@ -62,7 +61,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @android.platform.test.annotations.EnabledOnRavenwood
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardSurfaceBehindRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardSurfaceBehindRepositoryImplTest.kt
index bed959f..368bf9e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardSurfaceBehindRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardSurfaceBehindRepositoryImplTest.kt
@@ -21,7 +21,6 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectValues
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -29,7 +28,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardSurfaceBehindRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
index 0bfcd54..3a8603d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
@@ -36,7 +36,6 @@
 import com.android.systemui.util.mockito.mock
 import junit.framework.Assert.assertEquals
 import junit.framework.Assert.assertFalse
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -47,7 +46,6 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class LightRevealScrimRepositoryTest : SysuiTestCase() {
     private val kosmos = testKosmos()
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 2d12150..8a1afe4 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
@@ -29,7 +29,6 @@
 import com.android.systemui.user.data.repository.FakeUserRepository
 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
@@ -44,7 +43,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @android.platform.test.annotations.EnabledOnRavenwood
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt
index 0bd541c..3dd2ecd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -42,7 +41,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class BurnInInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt
index b5ea305..425079d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt
@@ -48,7 +48,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -61,7 +60,6 @@
 import org.mockito.junit.MockitoJUnit
 import org.mockito.junit.MockitoRule
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceEntrySideFpsOverlayInteractorTest : SysuiTestCase() {
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 047d8c2..2feabf8 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
@@ -51,7 +51,6 @@
 import com.android.systemui.power.shared.model.WakeSleepReason
 import com.android.systemui.power.shared.model.WakefulnessState
 import com.android.systemui.testKosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -60,7 +59,6 @@
 import org.junit.runner.RunWith
 import org.mockito.Mockito.reset
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FromAlternateBouncerTransitionInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt
index 3f2e78c..208abf3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt
@@ -63,7 +63,6 @@
 import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
 import com.android.systemui.testKosmos
 import junit.framework.Assert.assertEquals
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
@@ -73,7 +72,6 @@
 import org.junit.runner.RunWith
 import org.mockito.Mockito.reset
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FromAodTransitionInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt
index df44425..c7f9edf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorTest.kt
@@ -55,7 +55,6 @@
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth
 import junit.framework.Assert.assertEquals
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.advanceTimeBy
@@ -73,7 +72,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 @EnableFlags(FLAG_COMMUNAL_HUB)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt
index e9e3e1b..dcfa298 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt
@@ -44,7 +44,6 @@
 import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
 import com.android.systemui.testKosmos
 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
@@ -59,7 +58,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt
index 9e8713b..63960ab 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt
@@ -40,7 +40,6 @@
 import com.android.systemui.shade.data.repository.fakeShadeRepository
 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.Before
@@ -49,7 +48,6 @@
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.spy
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FromLockscreenTransitionInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorTest.kt
index 4a90722..63ed040 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorTest.kt
@@ -51,7 +51,6 @@
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.testKosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.runCurrent
@@ -61,7 +60,6 @@
 import org.junit.runner.RunWith
 import org.mockito.Mockito.reset
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FromOccludedTransitionInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt
index a7da230..63bb100 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt
@@ -37,7 +37,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.user.domain.interactor.selectedUserInteractor
 import junit.framework.Assert.assertEquals
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -45,7 +44,6 @@
 import org.junit.runner.RunWith
 import org.mockito.Mockito.reset
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FromPrimaryBouncerTransitionInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/InWindowLauncherUnlockAnimationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/InWindowLauncherUnlockAnimationInteractorTest.kt
index ea5a41f..6241865 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/InWindowLauncherUnlockAnimationInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/InWindowLauncherUnlockAnimationInteractorTest.kt
@@ -44,7 +44,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 class InWindowLauncherUnlockAnimationInteractorTest : SysuiTestCase() {
     private val kosmos = testKosmos()
     private val underTest =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt
index 84b7f5c..3acb9c6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt
@@ -39,7 +39,6 @@
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -52,7 +51,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardBlueprintInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
index dadcf71..c63f6f6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
@@ -45,7 +45,6 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
 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.TestScope
@@ -56,7 +55,6 @@
 import org.junit.runner.RunWith
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnableSceneContainer
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorTest.kt
index fabed03..4eb5ea0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorTest.kt
@@ -34,7 +34,6 @@
 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.StandardTestDispatcher
 import kotlinx.coroutines.test.TestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -45,7 +44,6 @@
 import org.junit.runner.RunWith
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardDismissInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
index c44f27e..0718d0d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
@@ -52,7 +52,6 @@
 import com.android.systemui.shade.data.repository.shadeRepository
 import com.android.systemui.testKosmos
 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.advanceTimeBy
@@ -62,7 +61,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractorTest.kt
index fbdab7d..6704d63 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractorTest.kt
@@ -36,7 +36,6 @@
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -49,7 +48,6 @@
 import org.mockito.junit.MockitoJUnit
 import org.mockito.kotlin.isNull
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardKeyEventInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractorTest.kt
index bef995f..3eacc28 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLockWhileAwakeInteractorTest.kt
@@ -39,7 +39,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 class KeyguardLockWhileAwakeInteractorTest : SysuiTestCase() {
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
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 ae2a5c5..8f60e6b 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
@@ -30,8 +30,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.keyguard.domain.interactor
 
 import android.provider.Settings
@@ -66,7 +64,6 @@
 import com.google.common.truth.Truth.assertThat
 import junit.framework.Assert.assertFalse
 import junit.framework.Assert.assertTrue
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
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 88c8b1f..868b3ce 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
@@ -28,7 +28,6 @@
 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.communal.domain.interactor.communalSettingsInteractor
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.dock.DockManager
@@ -67,7 +66,6 @@
 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
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -79,7 +77,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
@@ -150,7 +147,6 @@
                             .thenReturn(FakeSharedPreferences())
                     },
                 userTracker = userTracker,
-                communalSettingsInteractor = kosmos.communalSettingsInteractor,
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
         val remoteUserSelectionManager =
@@ -200,7 +196,6 @@
                 biometricSettingsRepository = biometricSettingsRepository,
                 backgroundDispatcher = kosmos.testDispatcher,
                 appContext = context,
-                communalSettingsInteractor = kosmos.communalSettingsInteractor,
                 accessibilityManager = accessibilityManager,
                 sceneInteractor = { kosmos.sceneInteractor },
             )
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
index c9871f1..6d53e6c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
@@ -50,7 +50,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
     private val kosmos = testKosmos()
     private lateinit var testScope: TestScope
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
index 16f02c5..e203a27 100644
--- 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
@@ -40,7 +40,6 @@
 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
@@ -53,7 +52,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardTouchHandlingInteractorTest : SysuiTestCase() {
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 635f8026..29e95cd 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
@@ -55,7 +55,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 class KeyguardTransitionInteractorTest : SysuiTestCase() {
     val kosmos = testKosmos()
     val underTest = kosmos.keyguardTransitionInteractor
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index abcbdb1..d057f7a0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -65,7 +65,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.whenever
 import kotlin.time.Duration.Companion.milliseconds
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.cancelChildren
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.flowOf
@@ -88,7 +87,6 @@
  * Class for testing user journeys through the interactors. They will all be activated during setup,
  * to ensure the expected transitions are still triggered.
  */
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class KeyguardTransitionScenariosTest(flags: FlagsParameterization?) : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt
index 98e3c68..a814953 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt
@@ -44,7 +44,6 @@
 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
@@ -58,7 +57,6 @@
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt
index e24bb04..96db014 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt
@@ -38,7 +38,6 @@
 import com.android.systemui.statusbar.LightRevealScrim
 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.Assert.assertEquals
@@ -47,7 +46,6 @@
 import org.mockito.Mockito
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class LightRevealScrimInteractorTest : SysuiTestCase() {
     val kosmos =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/SwipeToDismissInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/SwipeToDismissInteractorTest.kt
index d77519d..d36b45e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/SwipeToDismissInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/SwipeToDismissInteractorTest.kt
@@ -36,7 +36,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 class SwipeToDismissInteractorTest : SysuiTestCase() {
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/UdfpsKeyguardInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/UdfpsKeyguardInteractorTest.kt
index 309e3a8..be81f31 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/UdfpsKeyguardInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/UdfpsKeyguardInteractorTest.kt
@@ -49,7 +49,6 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
 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
@@ -62,7 +61,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class UdfpsKeyguardInteractorTest(flags: FlagsParameterization) : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
index 5f5d80c..b7c162b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
@@ -60,7 +60,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() {
     private val lockscreenSurfaceVisibilityFlow = MutableStateFlow<Boolean?>(false)
     private val primaryBouncerSurfaceVisibilityFlow = MutableStateFlow<Boolean?>(false)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/InWindowLauncherUnlockAnimationManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/InWindowLauncherUnlockAnimationManagerTest.kt
index 0cfc20d..0e9f5e7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/InWindowLauncherUnlockAnimationManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/InWindowLauncherUnlockAnimationManagerTest.kt
@@ -41,7 +41,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 class InWindowLauncherUnlockAnimationManagerTest : SysuiTestCase() {
     private val kosmos = testKosmos()
     private lateinit var underTest: InWindowLauncherUnlockAnimationManager
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt
index 4e3d18c..5131b60 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinderTest.kt
@@ -40,7 +40,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 class KeyguardClockViewBinderTest : SysuiTestCase() {
     @Mock private lateinit var rootView: ConstraintLayout
     @Mock private lateinit var burnInLayer: Layer
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt
index 9055495..7a614fd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt
@@ -43,7 +43,6 @@
 
 @SmallTest
 @RunWithLooper(setAsMainLooper = true)
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 @RunWith(AndroidJUnit4::class)
 class KeyguardSurfaceBehindParamsApplierTest : SysuiTestCase() {
     @get:Rule val animatorTestRule = AnimatorTestRule(this)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt
index bafabe0..97c746c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt
@@ -50,7 +50,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
 
     @get:Rule val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt
index 810ca49..3a016ff 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt
@@ -43,7 +43,6 @@
 import com.android.systemui.keyguard.ui.view.layout.sections.SplitShadeGuidelines
 import com.android.systemui.util.mockito.whenever
 import java.util.Optional
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -55,7 +54,6 @@
 
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
-@ExperimentalCoroutinesApi
 @SmallTest
 class DefaultKeyguardBlueprintTest : SysuiTestCase() {
     private lateinit var underTest: DefaultKeyguardBlueprint
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt
index 1cf45f8..2ef86e66 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt
@@ -47,7 +47,6 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -58,7 +57,6 @@
 import org.mockito.MockitoAnnotations
 import org.mockito.kotlin.mock
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class ClockSectionTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AccessibilityActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AccessibilityActionsViewModelTest.kt
index d0f434a..708257a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AccessibilityActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AccessibilityActionsViewModelTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.keyguard.ui.viewmodel
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -31,7 +29,6 @@
 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.runTest
 import org.junit.Before
 import org.junit.Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerMessageAreaViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerMessageAreaViewModelTest.kt
index 87d1cd5..1716fe0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerMessageAreaViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerMessageAreaViewModelTest.kt
@@ -33,7 +33,6 @@
 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.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -41,7 +40,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AlternateBouncerMessageAreaViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToAodTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToAodTransitionViewModelTest.kt
index df8afdb..9dd1429 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToAodTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToAodTransitionViewModelTest.kt
@@ -38,13 +38,11 @@
 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.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AlternateBouncerToAodTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToDozingTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToDozingTransitionViewModelTest.kt
index f8a6fc7..a75f27c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToDozingTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToDozingTransitionViewModelTest.kt
@@ -33,13 +33,11 @@
 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.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AlternateBouncerToDozingTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModelTest.kt
index 692ffee..1e91845 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModelTest.kt
@@ -33,13 +33,11 @@
 import com.android.systemui.statusbar.sysuiStatusBarStateController
 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
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AlternateBouncerToGoneTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToLockscreenTransitionViewModelTest.kt
index f74b74a..e0ba826 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToLockscreenTransitionViewModelTest.kt
@@ -30,13 +30,11 @@
 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.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AlternateBouncerToLockscreenTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToOccludedTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToOccludedTransitionViewModelTest.kt
index 288dc48..06c224f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToOccludedTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToOccludedTransitionViewModelTest.kt
@@ -30,12 +30,10 @@
 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.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AlternateBouncerToOccludedTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelTest.kt
index e93ed39..bbbdeff 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelTest.kt
@@ -36,12 +36,10 @@
 import com.android.systemui.shade.shadeTestUtil
 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
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AlternateBouncerToPrimaryBouncerTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt
index 844a166..e1323c1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt
@@ -37,14 +37,12 @@
 import com.android.systemui.util.mockito.any
 import com.google.common.collect.Range
 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.Mockito.mock
 import org.mockito.Mockito.verify
 
-@ExperimentalCoroutinesApi
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class AlternateBouncerViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt
index 5d95480..7b000df 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt
@@ -29,12 +29,10 @@
 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.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class AlternateBouncerWindowViewModelTest : SysuiTestCase() {
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 be504cc..eb8f1aa 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
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.keyguard.ui.viewmodel
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -38,7 +36,6 @@
 import com.android.systemui.testKosmos
 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.emptyFlow
 import kotlinx.coroutines.test.runCurrent
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelTest.kt
index a3371d3..0e13d01 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToGoneTransitionViewModelTest.kt
@@ -27,12 +27,10 @@
 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.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AodToGoneTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt
index 4dbe7c8..caf54f1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.shade.shadeTestUtil
 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.Before
@@ -41,7 +40,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class AodToLockscreenTransitionViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelTest.kt
index db8fbf6..e030868 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModelTest.kt
@@ -27,12 +27,10 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AodToOccludedTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModelTest.kt
index 01191cc..52f7ca7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModelTest.kt
@@ -32,13 +32,11 @@
 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.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AodToPrimaryBouncerTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt
index 22677b2..c8fade3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt
@@ -30,13 +30,11 @@
 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.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceEntryBackgroundViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModelTest.kt
index d42b538..eb4b373 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModelTest.kt
@@ -30,14 +30,12 @@
 import com.android.systemui.res.R
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
 import org.junit.After
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceEntryForegroundViewModelTest : SysuiTestCase() {
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 b49e546..5bc4d5e 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
@@ -39,7 +39,6 @@
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
@@ -48,7 +47,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceEntryIconViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModelTest.kt
index bf3231e..61a50ba 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModelTest.kt
@@ -29,13 +29,11 @@
 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.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DozingToGoneTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt
index 8e4876d..779c1cd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt
@@ -27,12 +27,10 @@
 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.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DozingToLockscreenTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelTest.kt
index 28410d9..bafd415 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelTest.kt
@@ -34,14 +34,12 @@
 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.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DozingToPrimaryBouncerTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
index e34edb4..eb5e139 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
@@ -36,13 +36,11 @@
 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.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelTest.kt
index 1dd435b..3ab920a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelTest.kt
@@ -35,13 +35,11 @@
 import com.android.systemui.testKosmos
 import com.google.common.collect.Range
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class GlanceableHubToLockscreenTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModelTest.kt
index 54d20d2..6b9e23a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModelTest.kt
@@ -29,11 +29,9 @@
 import com.android.systemui.kosmos.collectValues
 import com.android.systemui.kosmos.runTest
 import com.android.systemui.testKosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class GlanceableHubToPrimaryBouncerTransitionViewModelTest : SysuiTestCase() {
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
index bab466a..ce234ccb 100644
--- 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
@@ -34,13 +34,11 @@
 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() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDozingTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDozingTransitionViewModelTest.kt
index 80a9532..c7c0369 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDozingTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDozingTransitionViewModelTest.kt
@@ -35,13 +35,11 @@
 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.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class GoneToDozingTransitionViewModelTest : SysuiTestCase() {
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 bd892d5..9c7f0149 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
@@ -36,7 +36,6 @@
 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.flow.MutableStateFlow
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runTest
@@ -47,7 +46,6 @@
 import org.mockito.kotlin.doReturn
 import org.mockito.kotlin.mock
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 class KeyguardIndicationAreaViewModelTest() : SysuiTestCase() {
     private val kosmos = testKosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
index 789477e..83bee7c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
@@ -15,8 +15,6 @@
  *
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.keyguard.ui.viewmodel
 
 import android.platform.test.flag.junit.FlagsParameterization
@@ -57,7 +55,6 @@
 import com.android.systemui.util.ui.stopAnimating
 import com.android.systemui.util.ui.value
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.flow.flowOf
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 5436d7e..bd0fb68 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,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.keyguard.ui.viewmodel
 
 import android.platform.test.flag.junit.FlagsParameterization
@@ -27,8 +25,10 @@
 import com.android.systemui.flags.DisableSceneContainer
 import com.android.systemui.flags.andSceneContainer
 import com.android.systemui.keyguard.data.repository.fakeKeyguardClockRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository
 import com.android.systemui.keyguard.shared.model.ClockSize
+import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.lifecycle.activateIn
@@ -42,7 +42,6 @@
 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
@@ -239,6 +238,10 @@
                 val isContentVisible by collectLastValue(underTest.isContentVisible)
 
                 keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true, null)
+                fakeKeyguardTransitionRepository.transitionTo(
+                    KeyguardState.LOCKSCREEN,
+                    KeyguardState.OCCLUDED,
+                )
                 runCurrent()
                 assertThat(isContentVisible).isFalse()
             }
@@ -249,7 +252,12 @@
         with(kosmos) {
             testScope.runTest {
                 val isContentVisible by collectLastValue(underTest.isContentVisible)
+
                 keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true, null)
+                fakeKeyguardTransitionRepository.transitionTo(
+                    KeyguardState.LOCKSCREEN,
+                    KeyguardState.OCCLUDED,
+                )
                 runCurrent()
 
                 sceneInteractor.snapToScene(Scenes.Shade, "")
@@ -258,6 +266,35 @@
             }
         }
 
+    @Test
+    fun isContentVisible_whenOccluded_notVisibleInOccluded_visibleInAod() =
+        with(kosmos) {
+            testScope.runTest {
+                val isContentVisible by collectLastValue(underTest.isContentVisible)
+                keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true, null)
+                fakeKeyguardTransitionRepository.transitionTo(
+                    KeyguardState.LOCKSCREEN,
+                    KeyguardState.OCCLUDED,
+                )
+                runCurrent()
+
+                sceneInteractor.snapToScene(Scenes.Shade, "")
+                runCurrent()
+                assertThat(isContentVisible).isFalse()
+
+                fakeKeyguardTransitionRepository.transitionTo(
+                    KeyguardState.OCCLUDED,
+                    KeyguardState.AOD,
+                )
+                runCurrent()
+
+                sceneInteractor.snapToScene(Scenes.Lockscreen, "")
+                runCurrent()
+
+                assertThat(isContentVisible).isTrue()
+            }
+        }
+
     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/LockscreenToAodTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelTest.kt
index bc381f2..28f5799 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelTest.kt
@@ -37,7 +37,6 @@
 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.Before
@@ -46,7 +45,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class LockscreenToAodTransitionViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModelTest.kt
index 0a0ded7..9c42a64 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModelTest.kt
@@ -33,14 +33,12 @@
 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.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class LockscreenToDozingTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
index 9337793..4bec6bb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.keyguard.ui.viewmodel
 
 import android.platform.test.flag.junit.FlagsParameterization
@@ -40,7 +38,6 @@
 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.Before
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModelTest.kt
index b5cee80..aefa2eb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModelTest.kt
@@ -35,13 +35,11 @@
 import com.android.systemui.testKosmos
 import com.google.common.collect.Range
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class LockscreenToGlanceableHubTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelTest.kt
index 26cb485..a82d01f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelTest.kt
@@ -29,12 +29,10 @@
 import com.android.systemui.statusbar.sysuiStatusBarStateController
 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
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class LockscreenToGoneTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
index 576795d..6d90c43 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.keyguard.ui.viewmodel
 
 import android.platform.test.flag.junit.FlagsParameterization
@@ -44,7 +42,6 @@
 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.Before
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt
index aaca603..a31728c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt
@@ -44,7 +44,6 @@
 import com.android.systemui.testKosmos
 import com.google.common.collect.Range
 import com.google.common.truth.Truth
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.test.runCurrent
@@ -55,7 +54,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class LockscreenToPrimaryBouncerTransitionViewModelTest(flags: FlagsParameterization) :
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
index 97e6763..57c65b4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.keyguard.ui.viewmodel
 
 import android.platform.test.annotations.DisableFlags
@@ -50,7 +48,6 @@
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.math.pow
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runTest
 import org.junit.BeforeClass
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelTest.kt
index 1912987..123ed0b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToAodTransitionViewModelTest.kt
@@ -29,13 +29,11 @@
 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.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class OccludedToAodTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
index 4c16a33..5357c28 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
@@ -32,13 +32,11 @@
 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 OccludedToLockscreenTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModelTest.kt
index 0951df2..8533134 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModelTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -38,7 +37,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class OccludedToPrimaryBouncerTransitionViewModelTest(flags: FlagsParameterization) :
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModelTest.kt
index 0b7a38e..715bd39 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OffToLockscreenTransitionViewModelTest.kt
@@ -29,7 +29,6 @@
 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.runTest
 import org.junit.Before
 import org.junit.Test
@@ -37,7 +36,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class OffToLockscreenTransitionViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelTest.kt
index aa1e7ae..db617a7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelTest.kt
@@ -31,13 +31,11 @@
 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.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PrimaryBouncerToAodTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelTest.kt
index 766816b..90a918b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelTest.kt
@@ -34,13 +34,11 @@
 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.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PrimaryBouncerToDozingTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModelTest.kt
index e4843bd..d64ae3f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModelTest.kt
@@ -29,11 +29,9 @@
 import com.android.systemui.kosmos.collectValues
 import com.android.systemui.kosmos.runTest
 import com.android.systemui.testKosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PrimaryBouncerToGlanceableHubTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
index fd2e335..97709a7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
@@ -66,11 +66,7 @@
             runCurrent()
 
             keyguardTransitionRepository.sendTransitionSteps(
-                listOf(
-                    step(0f, TransitionState.STARTED),
-                    step(0.3f),
-                    step(0.6f),
-                ),
+                listOf(step(0f, TransitionState.STARTED), step(0.3f), step(0.6f)),
                 testScope,
             )
 
@@ -87,11 +83,7 @@
             whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(true)
 
             keyguardTransitionRepository.sendTransitionSteps(
-                listOf(
-                    step(0f, TransitionState.STARTED),
-                    step(0.3f),
-                    step(0.6f),
-                ),
+                listOf(step(0f, TransitionState.STARTED), step(0.3f), step(0.6f)),
                 testScope,
             )
 
@@ -149,7 +141,8 @@
     @Test
     fun notificationAlpha() =
         testScope.runTest {
-            val values by collectValues(underTest.notificationAlpha)
+            val values by
+                collectValues(underTest.notificationAlpha(ViewStateAccessor(alpha = { 0.5f })))
             runCurrent()
 
             keyguardTransitionRepository.sendTransitionSteps(
@@ -158,7 +151,7 @@
                 testScope,
             )
 
-            assertThat(values[0]).isEqualTo(1f)
+            assertThat(values[0]).isEqualTo(0.5f)
             assertThat(values[1]).isEqualTo(0f)
             // Should always finish with 1f to show HUNs
             assertThat(values[2]).isEqualTo(1f)
@@ -167,7 +160,7 @@
     @Test
     fun notificationAlpha_leaveShadeOpen() =
         testScope.runTest {
-            val values by collectValues(underTest.notificationAlpha)
+            val values by collectValues(underTest.notificationAlpha(ViewStateAccessor()))
             runCurrent()
 
             sysuiStatusBarStateController.setLeaveOpenOnKeyguardHide(true)
@@ -185,14 +178,14 @@
 
     private fun step(
         value: Float,
-        state: TransitionState = TransitionState.RUNNING
+        state: TransitionState = TransitionState.RUNNING,
     ): TransitionStep {
         return TransitionStep(
             from = KeyguardState.PRIMARY_BOUNCER,
             to = KeyguardState.GONE,
             value = value,
             transitionState = state,
-            ownerName = "PrimaryBouncerToGoneTransitionViewModelTest"
+            ownerName = "PrimaryBouncerToGoneTransitionViewModelTest",
         )
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt
index 8fefb8d..6fd54f4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt
@@ -36,7 +36,6 @@
 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.Before
@@ -45,7 +44,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class PrimaryBouncerToLockscreenTransitionViewModelTest(flags: FlagsParameterization) :
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModelTest.kt
index fd7fb9f..cec624d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModelTest.kt
@@ -28,12 +28,10 @@
 import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PrimaryBouncerToOccludedTransitionViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModelTest.kt
index 0588b1c..dfed1f0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModelTest.kt
@@ -53,7 +53,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.mock
 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
@@ -62,7 +61,6 @@
 import org.mockito.Mockito.spy
 import org.mockito.Mockito.verify
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @TestableLooper.RunWithLooper
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/ExclusiveActivatableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/ExclusiveActivatableTest.kt
index 81b9180..3978312 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/ExclusiveActivatableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/lifecycle/ExclusiveActivatableTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.lifecycle
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -24,7 +22,6 @@
 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.Job
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/log/echo/LogcatEchoTrackerDebugTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/log/echo/LogcatEchoTrackerDebugTest.kt
index a5f50af..f508df2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/log/echo/LogcatEchoTrackerDebugTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/log/echo/LogcatEchoTrackerDebugTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.util.settings.FakeGlobalSettings
 import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceUntilIdle
@@ -44,7 +43,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class LogcatEchoTrackerDebugTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt
index 030b172..d5d88d3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt
@@ -25,7 +25,6 @@
 import com.google.common.truth.Truth.assertThat
 import java.io.PrintWriter
 import java.io.StringWriter
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.flow
@@ -39,7 +38,6 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class LogDiffsForTableTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryTest.kt
index 466c9f9..460232c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryTest.kt
@@ -43,7 +43,6 @@
 import com.google.common.collect.ImmutableList
 import com.google.common.truth.Truth.assertThat
 import com.google.common.util.concurrent.ListenableFuture
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -63,7 +62,6 @@
 private const val CUSTOM_ACTION_NAME = "Custom Action"
 private const val CUSTOM_ACTION_COMMAND = "custom-action"
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWithLooper
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataLoaderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataLoaderTest.kt
index cf503bb..1f1a74b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataLoaderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataLoaderTest.kt
@@ -47,7 +47,6 @@
 import com.android.systemui.statusbar.SbnBuilder
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.runTest
@@ -387,7 +386,6 @@
             assertThat(result).isNotNull()
         }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun testLoadMediaDataInBg_cancelMultipleScheduledTasks() =
         testScope.runTest {
@@ -416,7 +414,6 @@
             verify(mockImageLoader, times(1)).loadBitmap(any(), anyInt(), anyInt(), anyInt())
         }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun testLoadMediaDataInBg_fromResumeToActive_doesNotCancelResumeToActiveTask() =
         testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
index 57ac906..3078a94 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
@@ -26,6 +26,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
@@ -643,6 +644,132 @@
         verify(mMediaSwitchingController).addDeviceToPlayMedia(mMediaDevice2);
     }
 
+    @DisableFlags(Flags.FLAG_DISABLE_TRANSFER_WHEN_APPS_DO_NOT_SUPPORT)
+    @Test
+    public void clickFullItemOfSelectableDevice_flagOff_hasListingPreference_verifyConnectDevice() {
+        List<MediaDevice> mediaDevices = new ArrayList<>();
+        mediaDevices.add(mMediaDevice2);
+        when(mMediaDevice2.hasRouteListingPreferenceItem()).thenReturn(true);
+        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(mediaDevices);
+        when(mMediaSwitchingController.getTransferableMediaDevices()).thenReturn(List.of());
+        when(mMediaSwitchingController.isCurrentOutputDeviceHasSessionOngoing()).thenReturn(false);
+        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
+
+        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTitleText.getText().toString()).isEqualTo(TEST_DEVICE_NAME_2);
+        assertThat(mViewHolder.mContainerLayout.isFocusable()).isTrue();
+
+        mViewHolder.mContainerLayout.performClick();
+
+        verify(mMediaSwitchingController).connectDevice(mMediaDevice2);
+    }
+
+    @EnableFlags(Flags.FLAG_DISABLE_TRANSFER_WHEN_APPS_DO_NOT_SUPPORT)
+    @Test
+    public void clickFullItemOfSelectableDevice_flagOn_hasListingPreference_verifyConnectDevice() {
+        List<MediaDevice> mediaDevices = new ArrayList<>();
+        mediaDevices.add(mMediaDevice2);
+        when(mMediaDevice2.hasRouteListingPreferenceItem()).thenReturn(true);
+        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(mediaDevices);
+        when(mMediaSwitchingController.getTransferableMediaDevices()).thenReturn(List.of());
+        when(mMediaSwitchingController.isCurrentOutputDeviceHasSessionOngoing()).thenReturn(false);
+        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
+
+        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTitleText.getText().toString()).isEqualTo(TEST_DEVICE_NAME_2);
+        assertThat(mViewHolder.mContainerLayout.isFocusable()).isTrue();
+
+        mViewHolder.mContainerLayout.performClick();
+
+        verify(mMediaSwitchingController).connectDevice(mMediaDevice2);
+    }
+
+    @DisableFlags(Flags.FLAG_DISABLE_TRANSFER_WHEN_APPS_DO_NOT_SUPPORT)
+    @Test
+    public void clickFullItemOfSelectableDevice_flagOff_isTransferable_verifyConnectDevice() {
+        List<MediaDevice> mediaDevices = new ArrayList<>();
+        mediaDevices.add(mMediaDevice2);
+        when(mMediaDevice2.hasRouteListingPreferenceItem()).thenReturn(false);
+        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(mediaDevices);
+        when(mMediaSwitchingController.getTransferableMediaDevices()).thenReturn(mediaDevices);
+        when(mMediaSwitchingController.isCurrentOutputDeviceHasSessionOngoing()).thenReturn(false);
+        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
+
+        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTitleText.getText().toString()).isEqualTo(TEST_DEVICE_NAME_2);
+        assertThat(mViewHolder.mContainerLayout.isFocusable()).isTrue();
+
+        mViewHolder.mContainerLayout.performClick();
+
+        verify(mMediaSwitchingController).connectDevice(mMediaDevice2);
+    }
+
+    @EnableFlags(Flags.FLAG_DISABLE_TRANSFER_WHEN_APPS_DO_NOT_SUPPORT)
+    @Test
+    public void clickFullItemOfSelectableDevice_flagOn_isTransferable_verifyConnectDevice() {
+        List<MediaDevice> mediaDevices = new ArrayList<>();
+        mediaDevices.add(mMediaDevice2);
+        when(mMediaDevice2.hasRouteListingPreferenceItem()).thenReturn(false);
+        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(mediaDevices);
+        when(mMediaSwitchingController.getTransferableMediaDevices()).thenReturn(mediaDevices);
+        when(mMediaSwitchingController.isCurrentOutputDeviceHasSessionOngoing()).thenReturn(false);
+        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
+
+        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTitleText.getText().toString()).isEqualTo(TEST_DEVICE_NAME_2);
+        assertThat(mViewHolder.mContainerLayout.isFocusable()).isTrue();
+
+        mViewHolder.mContainerLayout.performClick();
+
+        verify(mMediaSwitchingController).connectDevice(mMediaDevice2);
+    }
+
+    @DisableFlags(Flags.FLAG_DISABLE_TRANSFER_WHEN_APPS_DO_NOT_SUPPORT)
+    @Test
+    public void clickFullItemOfSelectableDevice_flagOff_notTransferable_verifyConnectDevice() {
+        List<MediaDevice> mediaDevices = new ArrayList<>();
+        mediaDevices.add(mMediaDevice2);
+        when(mMediaDevice2.hasRouteListingPreferenceItem()).thenReturn(false);
+        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(mediaDevices);
+        when(mMediaSwitchingController.getTransferableMediaDevices()).thenReturn(List.of());
+        when(mMediaSwitchingController.isCurrentOutputDeviceHasSessionOngoing()).thenReturn(false);
+        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
+
+        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTitleText.getText().toString()).isEqualTo(TEST_DEVICE_NAME_2);
+        assertThat(mViewHolder.mContainerLayout.isFocusable()).isTrue();
+
+        mViewHolder.mContainerLayout.performClick();
+
+        verify(mMediaSwitchingController).connectDevice(mMediaDevice2);
+    }
+
+    @EnableFlags(Flags.FLAG_DISABLE_TRANSFER_WHEN_APPS_DO_NOT_SUPPORT)
+    @Test
+    public void clickFullItemOfSelectableDevice_flagOn_notTransferable_verifyNotConnectDevice() {
+        List<MediaDevice> mediaDevices = new ArrayList<>();
+        mediaDevices.add(mMediaDevice2);
+        when(mMediaDevice2.hasRouteListingPreferenceItem()).thenReturn(false);
+        when(mMediaSwitchingController.getSelectableMediaDevice()).thenReturn(mediaDevices);
+        when(mMediaSwitchingController.getTransferableMediaDevices()).thenReturn(List.of());
+        when(mMediaSwitchingController.isCurrentOutputDeviceHasSessionOngoing()).thenReturn(false);
+        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
+
+        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTitleText.getText().toString()).isEqualTo(TEST_DEVICE_NAME_2);
+        assertThat(mViewHolder.mContainerLayout.isFocusable()).isTrue();
+
+        mViewHolder.mContainerLayout.performClick();
+
+        verify(mMediaSwitchingController, never()).connectDevice(any(MediaDevice.class));
+    }
+
     @Test
     public void onGroupActionTriggered_clickSelectedRemoteDevice_triggerUngrouping() {
         when(mMediaSwitchingController.getSelectableMediaDevice())
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/appselector/data/ActivityTaskManagerThumbnailLoaderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/appselector/data/ActivityTaskManagerThumbnailLoaderTest.kt
index 9797c8c..47ec5ec 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/appselector/data/ActivityTaskManagerThumbnailLoaderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/appselector/data/ActivityTaskManagerThumbnailLoaderTest.kt
@@ -17,7 +17,6 @@
 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.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
@@ -26,7 +25,6 @@
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 class ActivityTaskManagerThumbnailLoaderTest : SysuiTestCase() {
 
     private val dispatcher = UnconfinedTestDispatcher()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt
index 6ec38ba..6bc8000 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt
@@ -27,13 +27,11 @@
 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
 import org.junit.runner.RunWith
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class MediaRouterRepositoryTest : SysuiTestCase() {
     val kosmos = Kosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/FakeNoteTaskBubbleController.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/FakeNoteTaskBubbleController.kt
index ebc00c3..9283455 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/FakeNoteTaskBubbleController.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/FakeNoteTaskBubbleController.kt
@@ -38,7 +38,7 @@
 ) : NoteTaskBubblesController(unUsed1, unsUsed2) {
     override suspend fun areBubblesAvailable() = optionalBubbles.isPresent
 
-    override suspend fun showOrHideAppBubble(
+    override suspend fun showOrHideNoteBubble(
         intent: Intent,
         userHandle: UserHandle,
         icon: Icon,
@@ -49,12 +49,12 @@
                 if (
                     bubbleExpandBehavior == NoteTaskBubbleExpandBehavior.KEEP_IF_EXPANDED &&
                         bubbles.isBubbleExpanded(
-                            Bubble.getAppBubbleKeyForApp(intent.`package`, userHandle)
+                            Bubble.getNoteBubbleKeyForApp(intent.`package`, userHandle)
                         )
                 ) {
                     return@ifPresentOrElse
                 }
-                bubbles.showOrHideAppBubble(intent, userHandle, icon)
+                bubbles.showOrHideNoteBubble(intent, userHandle, icon)
             },
             { throw IllegalAccessException() },
         )
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt
index e55d6ad..7b9af90 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/notetask/NoteTaskBubblesServiceTest.kt
@@ -64,41 +64,41 @@
     }
 
     @Test
-    fun showOrHideAppBubble_defaultExpandBehavior_shouldCallBubblesApi() {
+    fun showOrHideNoteBubble_defaultExpandBehavior_shouldCallBubblesApi() {
         val intent = Intent()
         val user = UserHandle.SYSTEM
         val icon = Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget)
         val bubbleExpandBehavior = NoteTaskBubbleExpandBehavior.DEFAULT
         whenever(bubbles.isBubbleExpanded(any())).thenReturn(false)
 
-        createServiceBinder().showOrHideAppBubble(intent, user, icon, bubbleExpandBehavior)
+        createServiceBinder().showOrHideNoteBubble(intent, user, icon, bubbleExpandBehavior)
 
-        verify(bubbles).showOrHideAppBubble(intent, user, icon)
+        verify(bubbles).showOrHideNoteBubble(intent, user, icon)
     }
 
     @Test
-    fun showOrHideAppBubble_keepIfExpanded_bubbleShown_shouldNotCallBubblesApi() {
+    fun showOrHideNoteBubble_keepIfExpanded_bubbleShown_shouldNotCallBubblesApi() {
         val intent = Intent().apply { setPackage("test") }
         val user = UserHandle.SYSTEM
         val icon = Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget)
         val bubbleExpandBehavior = NoteTaskBubbleExpandBehavior.KEEP_IF_EXPANDED
         whenever(bubbles.isBubbleExpanded(any())).thenReturn(true)
 
-        createServiceBinder().showOrHideAppBubble(intent, user, icon, bubbleExpandBehavior)
+        createServiceBinder().showOrHideNoteBubble(intent, user, icon, bubbleExpandBehavior)
 
-        verify(bubbles, never()).showOrHideAppBubble(intent, user, icon)
+        verify(bubbles, never()).showOrHideNoteBubble(intent, user, icon)
     }
 
     @Test
-    fun showOrHideAppBubble_keepIfExpanded_bubbleNotShown_shouldCallBubblesApi() {
+    fun showOrHideNoteBubble_keepIfExpanded_bubbleNotShown_shouldCallBubblesApi() {
         val intent = Intent().apply { setPackage("test") }
         val user = UserHandle.SYSTEM
         val icon = Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget)
         val bubbleExpandBehavior = NoteTaskBubbleExpandBehavior.KEEP_IF_EXPANDED
         whenever(bubbles.isBubbleExpanded(any())).thenReturn(false)
 
-        createServiceBinder().showOrHideAppBubble(intent, user, icon, bubbleExpandBehavior)
+        createServiceBinder().showOrHideNoteBubble(intent, user, icon, bubbleExpandBehavior)
 
-        verify(bubbles).showOrHideAppBubble(intent, user, icon)
+        verify(bubbles).showOrHideNoteBubble(intent, user, icon)
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt
index 6759608..26f5d9e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt
@@ -42,7 +42,6 @@
 import com.android.systemui.statusbar.notification.data.repository.setActiveNotifs
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -50,7 +49,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
@@ -124,35 +122,35 @@
         }
 
     @Test
-    fun showHeader_showsOnNarrowScreen() =
+    fun showClock_showsOnNarrowScreen() =
         testScope.runTest {
             kosmos.shadeRepository.setShadeLayoutWide(false)
 
             // Shown when notifications are present.
             kosmos.activeNotificationListRepository.setActiveNotifs(1)
             runCurrent()
-            assertThat(underTest.showHeader).isTrue()
+            assertThat(underTest.showClock).isTrue()
 
             // Hidden when notifications are not present.
             kosmos.activeNotificationListRepository.setActiveNotifs(0)
             runCurrent()
-            assertThat(underTest.showHeader).isFalse()
+            assertThat(underTest.showClock).isFalse()
         }
 
     @Test
-    fun showHeader_hidesOnWideScreen() =
+    fun showClock_hidesOnWideScreen() =
         testScope.runTest {
             kosmos.shadeRepository.setShadeLayoutWide(true)
 
             // Hidden when notifications are present.
             kosmos.activeNotificationListRepository.setActiveNotifs(1)
             runCurrent()
-            assertThat(underTest.showHeader).isFalse()
+            assertThat(underTest.showClock).isFalse()
 
             // Hidden when notifications are not present.
             kosmos.activeNotificationListRepository.setActiveNotifs(0)
             runCurrent()
-            assertThat(underTest.showHeader).isFalse()
+            assertThat(underTest.showClock).isFalse()
         }
 
     private fun TestScope.lockDevice() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseSceneContainerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseSceneContainerTest.kt
index 07ec38e..32e5fa1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseSceneContainerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseSceneContainerTest.kt
@@ -41,7 +41,6 @@
 import com.google.common.truth.Truth.assertThat
 import javax.inject.Provider
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.test.resetMain
@@ -62,7 +61,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 @RunWithLooper
-@OptIn(ExperimentalCoroutinesApi::class)
 @EnableSceneContainer
 class QSPanelControllerBaseSceneContainerTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/UserSettingObserverTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/UserSettingObserverTest.kt
index 0c2b59f..858ed6a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/UserSettingObserverTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/UserSettingObserverTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.util.settings.fakeSettings
 import com.google.common.truth.Truth.assertThat
 import junit.framework.Assert.fail
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.After
@@ -40,7 +39,6 @@
 
 private typealias Callback = (Int, Boolean) -> Unit
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 @TestableLooper.RunWithLooper
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/AbstractQSFragmentComposeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/AbstractQSFragmentComposeViewModelTest.kt
index 87e2fef..dd5e892 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/AbstractQSFragmentComposeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/AbstractQSFragmentComposeViewModelTest.kt
@@ -31,7 +31,6 @@
 import com.android.systemui.qs.composefragment.dagger.usingMediaInComposeFragment
 import com.android.systemui.testKosmos
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestResult
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.resetMain
@@ -42,7 +41,6 @@
 import org.junit.runner.RunWith
 
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 abstract class AbstractQSFragmentComposeViewModelTest : SysuiTestCase() {
     protected val kosmos = testKosmos().apply { mediaDataManager = legacyMediaDataManagerImpl }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelForceQSTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelForceQSTest.kt
index d16da1c..428d9748 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelForceQSTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelForceQSTest.kt
@@ -23,7 +23,6 @@
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.sysuiStatusBarStateController
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -33,7 +32,6 @@
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 @RunWithLooper
-@OptIn(ExperimentalCoroutinesApi::class)
 class QSFragmentComposeViewModelForceQSTest(private val testData: TestData) :
     AbstractQSFragmentComposeViewModelTest() {
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt
index 4457d9b..e3fe24c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt
@@ -46,7 +46,6 @@
 import com.android.systemui.statusbar.sysuiStatusBarStateController
 import com.android.systemui.util.animation.DisappearParameters
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import org.junit.Test
@@ -56,7 +55,6 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper
-@OptIn(ExperimentalCoroutinesApi::class)
 class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest() {
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/DynamicIconTilesInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/DynamicIconTilesInteractorTest.kt
index 75d4b91..c683007 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/DynamicIconTilesInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/DynamicIconTilesInteractorTest.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.qs.pipeline.shared.TileSpec
 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.Before
@@ -57,7 +56,6 @@
         }
     }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun removingTile_updatesSharedPreferences() =
         with(kosmos) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractorTest.kt
index ed28dc8..79acfda 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconTilesInteractorTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.qs.pipeline.shared.TileSpec
 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
@@ -53,7 +52,6 @@
         assertThat(underTest.isIconTile(smallTile)).isTrue()
     }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun isIconTile_updatesFromSharedPreferences() =
         with(kosmos) {
@@ -76,7 +74,6 @@
             }
         }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun resize_updatesSharedPreferences() =
         with(kosmos) {
@@ -96,7 +93,6 @@
             }
         }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun resizingNonCurrentTile_doesNothing() =
         with(kosmos) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/SizedTilesResetInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/SizedTilesResetInteractorTest.kt
index ee7a15e..e6d78d9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/SizedTilesResetInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/SizedTilesResetInteractorTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.qs.pipeline.shared.TileSpec
 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
@@ -47,7 +46,6 @@
         }
     private val underTest = with(kosmos) { sizedTilesResetInteractor }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun changeTiles_resetsCorrectly() {
         with(kosmos) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt
index 98770c7..68a591d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.qs.pipeline.shared.TileSpec
 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.Before
@@ -48,7 +47,6 @@
         underTest = kosmos.detailsViewModel
     }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun changeTileDetailsViewModel() = with(kosmos) {
         testScope.runTest {
@@ -62,8 +60,8 @@
             val tiles = currentTilesInteractor.currentTiles.value
 
             assertThat(currentTilesInteractor.currentTilesSpecs.size).isEqualTo(2)
-            assertThat(tiles!![1].spec).isEqualTo(specNoDetails)
-            (tiles!![1].tile as FakeQSTile).hasDetailsViewModel = false
+            assertThat(tiles[1].spec).isEqualTo(specNoDetails)
+            (tiles[1].tile as FakeQSTile).hasDetailsViewModel = false
 
             assertThat(underTest.activeTileDetails).isNull()
 
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 bbfa7e7..50229eb 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
@@ -62,7 +62,6 @@
 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
@@ -501,7 +500,6 @@
             }
         }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun currentTiles_moveTileDown() =
         with(kosmos) {
@@ -527,7 +525,6 @@
             }
         }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun currentTiles_moveTileUp() =
         with(kosmos) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModelTest.kt
index e686d4d..fdbf42c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/MediaInRowInLandscapeViewModelTest.kt
@@ -36,7 +36,6 @@
 import com.android.systemui.testKosmos
 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.junit.Before
@@ -44,7 +43,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(ParameterizedAndroidJunit4::class)
 @SmallTest
 class MediaInRowInLandscapeViewModelTest(private val testData: TestData) : SysuiTestCase() {
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
index 3d1265a..69fc4cd 100644
--- 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
@@ -35,7 +35,6 @@
 import com.android.systemui.res.R
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -43,7 +42,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class QuickQuickSettingsViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt
index 1545e74..e1672ea 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.qs.pipeline.shared.logging.QSPipelineLogger
 import com.android.systemui.util.settings.FakeSettings
 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
@@ -37,7 +36,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt
index a0dec8c..0a8b1d1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt
@@ -43,7 +43,6 @@
 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.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -53,7 +52,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt
index 39851b6..41b00bb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt
@@ -10,7 +10,6 @@
 import com.android.systemui.qs.pipeline.shared.logging.QSPipelineLogger
 import com.android.systemui.statusbar.policy.FakeDeviceProvisionedController
 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
@@ -22,7 +21,6 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class QSSettingsRestoredBroadcastRepositoryTest : SysuiTestCase() {
     private val dispatcher = StandardTestDispatcher()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt
index 23056b2..88e3951 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.retail.data.repository.FakeRetailModeRepository
 import com.android.systemui.util.settings.FakeSettings
 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
@@ -42,7 +41,6 @@
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class TileSpecSettingsRepositoryTest : SysuiTestCase() {
 
     private lateinit var secureSettings: FakeSettings
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt
index 1ca3c06..88da9ae 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt
@@ -12,7 +12,6 @@
 import com.android.systemui.util.settings.FakeSettings
 import com.google.common.truth.Truth
 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
@@ -23,7 +22,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt
index b12fbc2..502e179 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt
@@ -11,7 +11,6 @@
 import com.android.systemui.qs.pipeline.shared.logging.QSPipelineLogger
 import com.android.systemui.util.settings.FakeSettings
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -25,7 +24,6 @@
 
 @SmallTest
 @EnabledOnRavenwood
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class UserTileSpecRepositoryTest : SysuiTestCase() {
     private val secureSettings = FakeSettings()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/restoreprocessors/WorkTileRestoreProcessorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/restoreprocessors/WorkTileRestoreProcessorTest.kt
index 57bb77f..5abcb0c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/restoreprocessors/WorkTileRestoreProcessorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/data/restoreprocessors/WorkTileRestoreProcessorTest.kt
@@ -25,7 +25,6 @@
 import com.android.systemui.qs.pipeline.data.model.RestoreData
 import com.android.systemui.qs.pipeline.shared.TileSpec
 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
@@ -34,7 +33,6 @@
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class WorkTileRestoreProcessorTest : SysuiTestCase() {
 
     private val underTest = WorkTileRestoreProcessor()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt
index 5619022..b0fd7eb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt
@@ -29,12 +29,10 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.settings.fakeSettings
 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
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AutoAddableSettingTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt
index ea8d873..3be8e3f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.statusbar.policy.CallbackController
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.channels.ProducerScope
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.runCurrent
@@ -34,7 +33,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
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 8ad647d..a262984 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
@@ -29,7 +29,6 @@
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.whenever
 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
@@ -41,7 +40,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt
index b925b27..c5788b5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.statusbar.policy.DataSaverController
 import com.android.systemui.util.mockito.capture
 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
@@ -39,7 +38,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt
index 188c6a9..ac32fa8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.statusbar.policy.DeviceControlsController
 import com.android.systemui.util.mockito.capture
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.runCurrent
@@ -42,7 +41,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt
index 02699dd..cc694d4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.statusbar.policy.HotspotController
 import com.android.systemui.util.mockito.capture
 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
@@ -39,7 +38,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt
index 20fd360..ca7fa5f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.TestResult
@@ -47,7 +46,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class NightDisplayAutoAddableTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt
index 633e494..9a3b007 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.StandardTestDispatcher
@@ -50,7 +49,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt
index c5c76eb..d3fba4d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.statusbar.policy.WalletController
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -36,7 +35,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt
index bf34d6ee..0049042 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt
@@ -37,14 +37,12 @@
 import com.android.systemui.qs.tiles.WorkModeTile
 import com.android.systemui.settings.FakeUserTracker
 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 WorkTileAutoAddableTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/AccessibilityTilesInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/AccessibilityTilesInteractorTest.kt
index 6cd627c..d9e2d82 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/AccessibilityTilesInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/AccessibilityTilesInteractorTest.kt
@@ -32,7 +32,6 @@
 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.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -45,7 +44,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class AccessibilityTilesInteractorTest : SysuiTestCase() {
     private val USER_0_INFO = UserInfo(0, "zero", "", UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt
index 167eff1..c83f2f4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.util.mockito.any
 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.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -51,7 +50,6 @@
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class AutoAddInteractorTest : SysuiTestCase() {
     private val testScope = TestScope()
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
index 090e2e9..9b50f1b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
@@ -57,7 +57,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import com.google.protobuf.nano.MessageNano
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -74,7 +73,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class CurrentTilesInteractorImplTest : SysuiTestCase() {
 
     private val tileSpecRepository: TileSpecRepository = FakeTileSpecRepository()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt
index 00c7204..3a9c3d0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt
@@ -40,7 +40,6 @@
 import com.android.systemui.settings.fakeUserTracker
 import com.android.systemui.settings.userTracker
 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
@@ -52,7 +51,6 @@
  * from a device that uses different specs for tiles, we may end up with empty (or mostly empty) QS.
  * In that case, we want to prepend the default tiles instead.
  */
-@OptIn(ExperimentalCoroutinesApi::class)
 @MediumTest
 @RunWith(AndroidJUnit4::class)
 class NoLowNumberOfTilesTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt
index 6bcaea4..9d9bfda 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt
@@ -35,7 +35,6 @@
 import com.android.systemui.settings.fakeUserTracker
 import com.android.systemui.settings.userTracker
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -51,7 +50,6 @@
  */
 @MediumTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class WorkProfileAutoAddedAfterRestoreTest : SysuiTestCase() {
 
     private val kosmos by lazy { Kosmos().apply { fakeUserTracker.set(listOf(USER_0_INFO), 0) } }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/shared/QSSettingsPackageRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/shared/QSSettingsPackageRepositoryTest.kt
index 765c02a..a727714 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/shared/QSSettingsPackageRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/shared/QSSettingsPackageRepositoryTest.kt
@@ -28,7 +28,6 @@
 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
@@ -42,7 +41,6 @@
 import org.mockito.junit.MockitoRule
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class QSSettingsPackageRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
index 4c834b3..41d7e49 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
@@ -41,7 +41,6 @@
 import com.android.systemui.qs.tiles.dialog.InternetDialogManager
 import com.android.systemui.qs.tiles.dialog.WifiStateWorker
 import com.android.systemui.res.R
-import com.android.systemui.shade.shared.flag.DualShade
 import com.android.systemui.statusbar.connectivity.AccessPointController
 import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
 import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
@@ -58,7 +57,6 @@
 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiScanEntry
 import com.android.systemui.util.mockito.mock
 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
@@ -76,7 +74,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWithLooper(setAsMainLooper = true)
 @RunWith(ParameterizedAndroidJunit4::class)
@@ -147,7 +144,7 @@
                 dialogManager,
                 wifiStateWorker,
                 accessPointController,
-                internetDetailsViewModelFactory
+                internetDetailsViewModelFactory,
             )
 
         underTest.initialize()
@@ -297,7 +294,6 @@
                 FLAG_SCENE_CONTAINER,
                 KeyguardWmStateRefactor.FLAG_NAME,
                 NotificationThrottleHun.FLAG_NAME,
-                DualShade.FLAG_NAME,
             ]
     )
     fun click_withQsDetailedViewEnabled() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt
index 7bb28db..bbc0dbc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt
@@ -28,6 +28,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.common.shared.model.asIcon
+import com.android.systemui.kosmos.mainCoroutineContext
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.ActivityStarter
@@ -55,7 +56,6 @@
 import com.android.systemui.util.settings.FakeSettings
 import com.android.systemui.util.settings.SecureSettings
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.After
@@ -66,7 +66,6 @@
 import org.mockito.MockitoAnnotations
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @EnableFlags(android.app.Flags.FLAG_MODES_UI)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
@@ -126,6 +125,7 @@
 
         userActionInteractor =
             ModesTileUserActionInteractor(
+                kosmos.mainCoroutineContext,
                 inputHandler,
                 dialogDelegate,
                 kosmos.zenModeInteractor,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt
index c47a412..fba6151 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt
@@ -37,7 +37,6 @@
 import com.google.common.truth.Truth.assertThat
 import java.io.PrintWriter
 import java.io.StringWriter
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -53,7 +52,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class QSTileViewModelImplTest : SysuiTestCase() {
 
     @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractorTest.kt
index 67e2fba..fda75ca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractorTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel
 import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.toCollection
 import kotlinx.coroutines.test.runCurrent
@@ -34,7 +33,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractorTest.kt
index 990d747..afbc3e8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractorTest.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.util.time.DateFormatUtil
 import com.android.systemui.utils.leaks.FakeNextAlarmController
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.toCollection
 import kotlinx.coroutines.test.runCurrent
@@ -41,7 +40,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AlarmTileDataInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileDataInteractorTest.kt
index c80eb13..44c175a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileDataInteractorTest.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.qs.tiles.impl.battery.domain.interactor.BatterySaverTileDataInteractor
 import com.android.systemui.utils.leaks.FakeBatteryController
 import com.google.common.truth.Truth
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.toCollection
 import kotlinx.coroutines.test.runCurrent
@@ -37,7 +36,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractorTest.kt
index abaf808..4c156b7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractorTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.toCollection
 import kotlinx.coroutines.test.runCurrent
@@ -34,7 +33,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt
index 89ba69f..10530a2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.launchIn
@@ -50,7 +49,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class CustomTileDefaultsRepositoryTest : SysuiTestCase() {
 
     @Mock private lateinit var sysuiContext: Context
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt
index 2eeb75e..835dba2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt
@@ -35,7 +35,6 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.nullable
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -50,7 +49,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @SuppressLint("UnspecifiedRegisterReceiverFlag") // Not needed in the test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt
index c9869bdb..83e61d1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt
@@ -35,7 +35,6 @@
 import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
 import com.android.systemui.qs.tiles.impl.custom.packageManagerAdapterFacade
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -44,7 +43,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class CustomTileRepositoryTest : SysuiTestCase() {
 
     private val kosmos = Kosmos().apply { customTileSpec = TileSpec.create(TEST_COMPONENT) }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt
index b5aaadc..2cc3678 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt
@@ -45,7 +45,6 @@
 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.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.test.runCurrent
@@ -55,7 +54,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class CustomTileDataInteractorTest : SysuiTestCase() {
 
     private val kosmos =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt
index 33299d9..a317dc5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt
@@ -36,7 +36,6 @@
 import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.advanceTimeBy
@@ -47,7 +46,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class CustomTileInteractorTest : SysuiTestCase() {
 
     private val kosmos = testKosmos().apply { customTileSpec = TileSpec.create(TEST_COMPONENT) }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractorTest.kt
index c5a8c70..d42eb5e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractorTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel
 import com.android.systemui.utils.leaks.FakeFlashlightController
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -36,7 +35,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractorTest.kt
index 39bc8a6..cd82504 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractorTest.kt
@@ -24,14 +24,12 @@
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
 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.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FontScalingTileDataInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractorTest.kt
index 9099d3d..4b9d11d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractorTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel
 import com.android.systemui.statusbar.policy.fakeBluetoothController
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -43,7 +42,6 @@
 import org.mockito.junit.MockitoRule
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt
index 5259aa8..63607f1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt
@@ -57,14 +57,12 @@
 import com.android.systemui.util.CarrierConfigTracker
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 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 InternetTileDataInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractorTest.kt
index 75b07ee..228e993 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractorTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.toCollection
 import kotlinx.coroutines.test.runCurrent
@@ -34,7 +33,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
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
index f3fc0ab..7562ac0 100644
--- 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
@@ -31,7 +31,6 @@
 import com.android.systemui.settings.userTracker
 import com.android.systemui.util.settings.fakeGlobalSettings
 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
@@ -64,7 +63,6 @@
         underTest = IssueRecordingDataInteractor(state, kosmos.testScope.testScheduler)
     }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun emitsEvent_whenIsRecordingStatusChanges_correctly() {
         kosmos.testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/interactor/LocationTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/interactor/LocationTileDataInteractorTest.kt
index 9adf57a..52ce95b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/interactor/LocationTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/interactor/LocationTileDataInteractorTest.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel
 import com.android.systemui.utils.leaks.FakeLocationController
 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
@@ -37,7 +36,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt
index 029a2f9..0b641ce 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt
@@ -40,7 +40,6 @@
 import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.toCollection
 import kotlinx.coroutines.test.runCurrent
@@ -49,7 +48,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ModesTileDataInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt
index 89b8e91..24e4279 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.qs.tiles.impl.modes.domain.interactor
 
 import android.graphics.drawable.TestStubDrawable
@@ -30,6 +28,7 @@
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.asIcon
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.mainCoroutineContext
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
 import com.android.systemui.qs.tiles.base.actions.qsTileIntentUserInputHandler
@@ -41,7 +40,6 @@
 import com.android.systemui.statusbar.policy.ui.dialog.modesDialogEventLogger
 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
@@ -62,6 +60,7 @@
 
     private val underTest =
         ModesTileUserActionInteractor(
+            kosmos.mainCoroutineContext,
             inputHandler,
             mockDialogDelegate,
             zenModeInteractor,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractorTest.kt
index 35d6d5a..4786fc4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractorTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.toCollection
 import kotlinx.coroutines.test.runCurrent
@@ -36,7 +35,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class NotesTileDataInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileDataInteractorTest.kt
index 0761ee7..59eb069 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileDataInteractorTest.kt
@@ -27,14 +27,12 @@
 import com.android.systemui.qs.tiles.impl.onehanded.domain.OneHandedModeTileDataInteractor
 import com.android.wm.shell.onehanded.OneHanded
 import com.google.common.truth.Truth.assertThat
-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
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class OneHandedModeTileDataInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt
index a5f98a7..dc3248d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt
@@ -28,14 +28,12 @@
 import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel
 import com.google.common.truth.Truth.assertThat
-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
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt
index 266875e..283fa60 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt
@@ -36,7 +36,6 @@
 import com.android.systemui.utils.leaks.FakeBatteryController
 import com.android.systemui.utils.leaks.FakeRotationLockController
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.toCollection
 import kotlinx.coroutines.test.runCurrent
@@ -45,7 +44,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractorTest.kt
index daee22d..c286ea7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractorTest.kt
@@ -28,14 +28,12 @@
 import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel
 import com.android.systemui.utils.leaks.FakeDataSaverController
 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.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractorTest.kt
index 28f2a43..41174e7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractorTest.kt
@@ -28,14 +28,12 @@
 import com.android.systemui.screenrecord.data.model.ScreenRecordModel
 import com.android.systemui.screenrecord.data.repository.screenRecordRepository
 import com.google.common.truth.Truth.assertThat
-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
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractorTest.kt
index d0cd56fc..6c7bb1b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractorTest.kt
@@ -32,7 +32,6 @@
 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.flowOf
 import kotlinx.coroutines.flow.toCollection
 import kotlinx.coroutines.test.runCurrent
@@ -42,7 +41,6 @@
 import org.mockito.ArgumentMatchers.eq
 import org.mockito.Mockito.verify
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class SensorPrivacyToggleTileDataInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileDataInteractorTest.kt
index 46e1609..96538b7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileDataInteractorTest.kt
@@ -39,7 +39,6 @@
 import com.android.systemui.utils.leaks.FakeLocationController
 import com.google.common.truth.Truth.assertThat
 import java.time.LocalTime
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -49,7 +48,6 @@
 import org.mockito.Mock
 import org.mockito.Mockito.verify
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class UiModeNightTileDataInteractorTest : SysuiTestCase() {
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 2edb9c6..0598a8b 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
@@ -37,7 +37,6 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -53,7 +52,6 @@
 @MediumTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class QSTileViewModelTest : SysuiTestCase() {
 
     @Mock private lateinit var qsTileLogger: QSTileLogger
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 0219a4c..ece21e1 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
@@ -37,7 +37,6 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -54,7 +53,6 @@
 /** Tests all possible [QSTileUserAction]s. If you need */
 @MediumTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class QSTileViewModelUserInputTest : SysuiTestCase() {
 
     @Mock private lateinit var qsTileLogger: QSTileLogger
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt
index 8769022..a8b005f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt
@@ -39,7 +39,7 @@
 import com.android.systemui.qs.dagger.QSSceneComponent
 import com.android.systemui.settings.brightness.MirrorController
 import com.android.systemui.shade.data.repository.fakeShadeRepository
-import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.capture
@@ -50,7 +50,6 @@
 import com.google.common.truth.Truth.assertThat
 import java.util.Locale
 import javax.inject.Provider
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
@@ -64,7 +63,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class QSSceneAdapterImplTest : SysuiTestCase() {
 
     private val kosmos = Kosmos().apply { testCase = this@QSSceneAdapterImplTest }
@@ -118,16 +116,14 @@
             }
         }
 
-    private val shadeInteractor = kosmos.shadeInteractor
-    private val displayStateInteractor = kosmos.displayStateInteractor
     private val dumpManager = mock<DumpManager>()
 
     private val underTest =
         QSSceneAdapterImpl(
             qsSceneComponentFactory,
             qsImplProvider,
-            shadeInteractor,
-            displayStateInteractor,
+            kosmos.shadeModeInteractor,
+            kosmos.displayStateInteractor,
             dumpManager,
             testDispatcher,
             testScope.backgroundScope,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelTest.kt
new file mode 100644
index 0000000..6e26fa11
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelTest.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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 android.testing.TestableLooper
+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.flags.EnableSceneContainer
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.lifecycle.activateIn
+import com.android.systemui.qs.composefragment.dagger.usingMediaInComposeFragment
+import com.android.systemui.scene.domain.startable.sceneContainerStartable
+import com.android.systemui.shade.domain.interactor.enableDualShade
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
+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)
+@TestableLooper.RunWithLooper
+@EnableSceneContainer
+class QuickSettingsContainerViewModelTest : SysuiTestCase() {
+
+    private val kosmos =
+        testKosmos().apply {
+            usingMediaInComposeFragment = false // This is not for the compose fragment
+        }
+    private val testScope = kosmos.testScope
+
+    private val shadeModeInteractor = kosmos.shadeModeInteractor
+
+    private val underTest by lazy {
+        kosmos.quickSettingsContainerViewModelFactory.create(supportsBrightnessMirroring = false)
+    }
+
+    @Before
+    fun setUp() {
+        kosmos.sceneContainerStartable.start()
+        kosmos.enableDualShade()
+        underTest.activateIn(testScope)
+    }
+
+    @Test
+    fun showHeader_showsOnNarrowScreen() =
+        testScope.runTest {
+            kosmos.enableDualShade(wideLayout = false)
+            val isShadeLayoutWide by collectLastValue(shadeModeInteractor.isShadeLayoutWide)
+            assertThat(isShadeLayoutWide).isFalse()
+
+            assertThat(underTest.showHeader).isTrue()
+        }
+
+    @Test
+    fun showHeader_hidesOnWideScreen() =
+        testScope.runTest {
+            kosmos.enableDualShade(wideLayout = true)
+            val isShadeLayoutWide by collectLastValue(shadeModeInteractor.isShadeLayoutWide)
+            assertThat(isShadeLayoutWide).isTrue()
+
+            assertThat(underTest.showHeader).isFalse()
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneContentViewModelTest.kt
index e2d33b6..b36c111 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneContentViewModelTest.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.qs.ui.viewmodel
 
-import android.platform.test.annotations.DisableFlags
 import android.testing.TestableLooper.RunWithLooper
 import androidx.lifecycle.LifecycleOwner
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -39,13 +38,15 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModelFactory
 import com.android.systemui.shade.data.repository.shadeRepository
-import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.disableDualShade
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
 import com.android.systemui.shade.ui.viewmodel.shadeHeaderViewModelFactory
 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.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -54,11 +55,11 @@
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper
 @EnableSceneContainer
-@DisableFlags(com.android.systemui.Flags.FLAG_DUAL_SHADE)
 class QuickSettingsSceneContentViewModelTest : SysuiTestCase() {
 
     private val kosmos = testKosmos()
@@ -73,7 +74,6 @@
 
     private val sceneContainerStartable = kosmos.sceneContainerStartable
     private val sceneInteractor by lazy { kosmos.sceneInteractor }
-    private val shadeInteractor by lazy { kosmos.shadeInteractor }
 
     private lateinit var underTest: QuickSettingsSceneContentViewModel
 
@@ -90,10 +90,11 @@
                 footerActionsViewModelFactory = footerActionsViewModelFactory,
                 footerActionsController = footerActionsController,
                 mediaCarouselInteractor = kosmos.mediaCarouselInteractor,
-                shadeInteractor = shadeInteractor,
+                shadeModeInteractor = kosmos.shadeModeInteractor,
                 sceneInteractor = sceneInteractor,
             )
         underTest.activateIn(testScope)
+        kosmos.disableDualShade()
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt
index 01714d7..ec05965 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt
@@ -42,7 +42,6 @@
 import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationScrollViewModel
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -50,7 +49,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
@@ -127,24 +125,6 @@
         }
 
     @Test
-    fun showHeader_showsOnNarrowScreen() =
-        testScope.runTest {
-            kosmos.enableDualShade(wideLayout = false)
-            runCurrent()
-
-            assertThat(underTest.showHeader).isTrue()
-        }
-
-    @Test
-    fun showHeader_hidesOnWideScreen() =
-        testScope.runTest {
-            kosmos.enableDualShade(wideLayout = true)
-            runCurrent()
-
-            assertThat(underTest.showHeader).isFalse()
-        }
-
-    @Test
     fun onPanelShapeChanged() =
         testScope.runTest {
             var actual: ShadeScrimShape? = null
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt
index f2e658d..7bcaeab 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt
@@ -38,6 +38,7 @@
 import com.android.traceur.TraceConfig
 import com.google.common.truth.Truth
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyInt
@@ -126,6 +127,7 @@
         verify(iActivityManager).requestBugReportWithExtraAttachments(any())
     }
 
+    @Ignore("b/392753499")
     @Test
     fun sharesTracesDirectly_afterReceivingShareCommand_withTakeBugreportFalse() {
         underTest.takeBugReport = false
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/retail/data/repository/RetailModeSettingsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/retail/data/repository/RetailModeSettingsRepositoryTest.kt
index 47bfda4..0d03247 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/retail/data/repository/RetailModeSettingsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/retail/data/repository/RetailModeSettingsRepositoryTest.kt
@@ -24,7 +24,6 @@
 import com.android.systemui.retail.data.repository.impl.RetailModeSettingsRepository
 import com.android.systemui.util.settings.FakeGlobalSettings
 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
@@ -32,7 +31,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class RetailModeSettingsRepositoryTest : SysuiTestCase() {
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 3187cca6..c5fac08 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.scene
 
 import android.provider.Settings
@@ -70,7 +68,6 @@
 import com.android.telecom.mockTelecomManager
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.flowOf
@@ -98,7 +95,6 @@
  *   being used when the state is as required (e.g. cannot unlock an already unlocked device, cannot
  *   put to sleep a device that's already asleep, etc.).
  */
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
index 227b3a6..4c6ab8b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.scene.data.repository
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -31,7 +29,6 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
 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
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 405cfd3..9cc6c0f 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
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.scene.domain.interactor
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -35,7 +33,6 @@
 import com.android.systemui.testKosmos
 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
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractorTest.kt
index 707cd04..0192b5b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractorTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.scene.domain.interactor
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -41,7 +39,6 @@
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.TestScope
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 de54e75..fd485ed 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
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.scene.domain.interactor
 
 import android.app.StatusBarManager
@@ -50,7 +48,6 @@
 import com.android.systemui.statusbar.disableflags.shared.model.DisableFlagsModel
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.flowOf
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
index 695edaf..590aaee 100644
--- 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
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.scene.domain.startable
 
 import android.content.pm.UserInfo
@@ -37,7 +35,6 @@
 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
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 af30e43..3373310 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
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.scene.domain.startable
 
 import android.app.StatusBarManager
@@ -124,7 +122,6 @@
 import com.android.systemui.util.settings.data.repository.userAwareSecureSettingsRepository
 import com.google.android.msdl.data.model.MSDLToken
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
@@ -2697,6 +2694,34 @@
             assertThat(isVisible).isFalse()
         }
 
+    @Test
+    fun deviceLocks_whenNoLongerTrusted_whileDeviceNotEntered() =
+        testScope.runTest {
+            prepareState(isDeviceUnlocked = true, initialSceneKey = Scenes.Gone)
+            underTest.start()
+
+            val isDeviceEntered by collectLastValue(kosmos.deviceEntryInteractor.isDeviceEntered)
+            val deviceUnlockStatus by
+                collectLastValue(kosmos.deviceUnlockedInteractor.deviceUnlockStatus)
+            val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene)
+            assertThat(isDeviceEntered).isTrue()
+            assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
+            assertThat(currentScene).isEqualTo(Scenes.Gone)
+            kosmos.fakeTrustRepository.setCurrentUserTrusted(true)
+            kosmos.sceneInteractor.changeScene(Scenes.Lockscreen, "reason")
+            runCurrent()
+            assertThat(isDeviceEntered).isFalse()
+            assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+
+            kosmos.fakeTrustRepository.setCurrentUserTrusted(false)
+            runCurrent()
+
+            assertThat(isDeviceEntered).isFalse()
+            assertThat(deviceUnlockStatus?.isUnlocked).isFalse()
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+        }
+
     private fun TestScope.emulateSceneTransition(
         transitionStateFlow: MutableStateFlow<ObservableTransitionState>,
         toScene: SceneKey,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/ScrimStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/ScrimStartableTest.kt
index 0e90afe..572bc4d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/ScrimStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/ScrimStartableTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.scene.domain.startable
 
 import androidx.test.filters.SmallTest
@@ -47,7 +45,6 @@
 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.flow.flowOf
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
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
index 9601f20..99146d8 100644
--- 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
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.scene.domain.startable
 
 import android.app.StatusBarManager
@@ -49,7 +47,6 @@
 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
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModelTest.kt
index 048dd66..0647db4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModelTest.kt
@@ -33,17 +33,15 @@
 import com.android.systemui.shade.domain.interactor.enableDualShade
 import com.android.systemui.shade.domain.interactor.enableSingleShade
 import com.android.systemui.shade.domain.interactor.enableSplitShade
-import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
 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.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
@@ -56,7 +54,7 @@
 
     @Before
     fun setUp() {
-        underTest = GoneUserActionsViewModel(shadeInteractor = kosmos.shadeInteractor)
+        underTest = GoneUserActionsViewModel(shadeModeInteractor = kosmos.shadeModeInteractor)
         underTest.activateIn(testScope)
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerHapticsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerHapticsViewModelTest.kt
index ca9500b..7330b51 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerHapticsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerHapticsViewModelTest.kt
@@ -37,10 +37,11 @@
 import com.android.systemui.scene.sceneContainerHapticsViewModelFactory
 import com.android.systemui.scene.shared.model.Overlays
 import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.domain.interactor.disableDualShade
+import com.android.systemui.shade.domain.interactor.enableDualShade
 import com.android.systemui.testKosmos
 import com.google.android.msdl.data.model.MSDLToken
 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.runCurrent
@@ -53,11 +54,10 @@
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.verifyNoMoreInteractions
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableSceneContainer
-class SceneContainerHapticsViewModelTest() : SysuiTestCase() {
+class SceneContainerHapticsViewModelTest : SysuiTestCase() {
 
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
@@ -74,10 +74,10 @@
     }
 
     @EnableFlags(Flags.FLAG_MSDL_FEEDBACK)
-    @DisableFlags(Flags.FLAG_DUAL_SHADE)
     @Test
     fun onValidSceneTransition_withMSDL_playsMSDLShadePullHaptics() =
         testScope.runTest {
+            kosmos.disableDualShade()
             // GIVEN a valid scene transition to play haptics
             val validTransition = createTransitionState(from = Scenes.Gone, to = Scenes.Shade)
 
@@ -91,10 +91,10 @@
         }
 
     @EnableFlags(Flags.FLAG_MSDL_FEEDBACK)
-    @DisableFlags(Flags.FLAG_DUAL_SHADE)
     @Test
     fun onInValidSceneTransition_withMSDL_doesNotPlayMSDLShadePullHaptics() =
         testScope.runTest {
+            kosmos.disableDualShade()
             // GIVEN an invalid scene transition to play haptics
             val invalidTransition = createTransitionState(from = Scenes.Shade, to = Scenes.Gone)
 
@@ -107,10 +107,11 @@
             assertThat(msdlPlayer.latestPropertiesPlayed).isNull()
         }
 
-    @DisableFlags(Flags.FLAG_DUAL_SHADE, Flags.FLAG_MSDL_FEEDBACK)
+    @DisableFlags(Flags.FLAG_MSDL_FEEDBACK)
     @Test
     fun onValidSceneTransition_withoutMSDL_playsHapticConstantForShadePullHaptics() =
         testScope.runTest {
+            kosmos.disableDualShade()
             // GIVEN a valid scene transition to play haptics
             val validTransition = createTransitionState(from = Scenes.Gone, to = Scenes.Shade)
 
@@ -122,10 +123,11 @@
             verify(view).performHapticFeedback(eq(HapticFeedbackConstants.GESTURE_START))
         }
 
-    @DisableFlags(Flags.FLAG_DUAL_SHADE, Flags.FLAG_MSDL_FEEDBACK)
+    @DisableFlags(Flags.FLAG_MSDL_FEEDBACK)
     @Test
     fun onInValidSceneTransition_withoutMSDL_doesNotPlayHapticConstantForShadePullHaptics() =
         testScope.runTest {
+            kosmos.disableDualShade()
             // GIVEN an invalid scene transition to play haptics
             val invalidTransition = createTransitionState(from = Scenes.Shade, to = Scenes.Gone)
 
@@ -137,10 +139,11 @@
             verifyNoMoreInteractions(view)
         }
 
-    @EnableFlags(Flags.FLAG_MSDL_FEEDBACK, Flags.FLAG_DUAL_SHADE)
+    @EnableFlags(Flags.FLAG_MSDL_FEEDBACK)
     @Test
     fun onValidOverlayTransition_withMSDL_playsMSDLShadePullHaptics() =
         testScope.runTest {
+            kosmos.enableDualShade()
             // GIVEN a valid scene transition to play haptics
             val validTransition =
                 createTransitionState(from = Scenes.Gone, to = Overlays.NotificationsShade)
@@ -154,10 +157,11 @@
             assertThat(msdlPlayer.latestPropertiesPlayed).isNull()
         }
 
-    @EnableFlags(Flags.FLAG_MSDL_FEEDBACK, Flags.FLAG_DUAL_SHADE)
+    @EnableFlags(Flags.FLAG_MSDL_FEEDBACK)
     @Test
     fun onInValidOverlayTransition_withMSDL_doesNotPlayMSDLShadePullHaptics() =
         testScope.runTest {
+            kosmos.enableDualShade()
             // GIVEN an invalid scene transition to play haptics
             val invalidTransition =
                 createTransitionState(from = Scenes.Bouncer, to = Overlays.NotificationsShade)
@@ -171,11 +175,11 @@
             assertThat(msdlPlayer.latestPropertiesPlayed).isNull()
         }
 
-    @EnableFlags(Flags.FLAG_DUAL_SHADE)
     @DisableFlags(Flags.FLAG_MSDL_FEEDBACK)
     @Test
     fun onValidOverlayTransition_withoutMSDL_playsHapticConstantForShadePullHaptics() =
         testScope.runTest {
+            kosmos.enableDualShade()
             // GIVEN a valid scene transition to play haptics
             val validTransition =
                 createTransitionState(from = Scenes.Gone, to = Overlays.NotificationsShade)
@@ -188,11 +192,11 @@
             verify(view).performHapticFeedback(eq(HapticFeedbackConstants.GESTURE_START))
         }
 
-    @EnableFlags(Flags.FLAG_DUAL_SHADE)
     @DisableFlags(Flags.FLAG_MSDL_FEEDBACK)
     @Test
     fun onInValidOverlayTransition_withoutMSDL_doesNotPlayHapticConstantForShadePullHaptics() =
         testScope.runTest {
+            kosmos.enableDualShade()
             // GIVEN an invalid scene transition to play haptics
             val invalidTransition =
                 createTransitionState(from = Scenes.Bouncer, to = Overlays.NotificationsShade)
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 399b48f..30d9f73 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
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.scene.ui.viewmodel
 
 import android.view.MotionEvent
@@ -42,7 +40,7 @@
 import com.android.systemui.shade.domain.interactor.enableDualShade
 import com.android.systemui.shade.domain.interactor.enableSingleShade
 import com.android.systemui.shade.domain.interactor.enableSplitShade
-import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeMode
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.statusbar.data.repository.fakeRemoteInputRepository
 import com.android.systemui.testKosmos
@@ -50,7 +48,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -58,7 +55,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableSceneContainer
@@ -324,7 +320,7 @@
     @Test
     fun edgeDetector_singleShade_usesDefaultEdgeDetector() =
         testScope.runTest {
-            val shadeMode by collectLastValue(kosmos.shadeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
             kosmos.enableSingleShade()
 
             assertThat(shadeMode).isEqualTo(ShadeMode.Single)
@@ -334,7 +330,7 @@
     @Test
     fun edgeDetector_splitShade_usesDefaultEdgeDetector() =
         testScope.runTest {
-            val shadeMode by collectLastValue(kosmos.shadeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
             kosmos.enableSplitShade()
 
             assertThat(shadeMode).isEqualTo(ShadeMode.Split)
@@ -344,7 +340,7 @@
     @Test
     fun edgeDetector_dualShade_narrowScreen_usesSplitEdgeDetector() =
         testScope.runTest {
-            val shadeMode by collectLastValue(kosmos.shadeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
             kosmos.enableDualShade(wideLayout = false)
 
             assertThat(shadeMode).isEqualTo(ShadeMode.Dual)
@@ -354,7 +350,7 @@
     @Test
     fun edgeDetector_dualShade_wideScreen_usesSplitEdgeDetector() =
         testScope.runTest {
-            val shadeMode by collectLastValue(kosmos.shadeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
             kosmos.enableDualShade(wideLayout = true)
 
             assertThat(shadeMode).isEqualTo(ShadeMode.Dual)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/UserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/UserActionsViewModelTest.kt
index d5f57da..c42a46c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/UserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/UserActionsViewModelTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.scene.ui.viewmodel
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -31,7 +29,6 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runCurrent
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt
index ade5941..9724974 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.screenrecord.RecordingController
 import com.android.systemui.screenrecord.data.model.ScreenRecordModel
 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
@@ -38,7 +37,6 @@
 import org.mockito.kotlin.whenever
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class ScreenRecordRepositoryTest : SysuiTestCase() {
     private val kosmos = Kosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt
index 4000d6c..0da01fc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt
@@ -16,7 +16,6 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
 import junit.framework.Assert.assertEquals
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
@@ -53,7 +52,6 @@
     lateinit var workProfileData: WorkProfileMessageController.WorkProfileFirstRunData
 
     @Before
-    @ExperimentalCoroutinesApi
     fun setup() {
         MockitoAnnotations.initMocks(this)
         messageContainer =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt
index 5987e74..ccf419f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt
@@ -23,7 +23,6 @@
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import java.lang.IllegalStateException
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.advanceUntilIdle
@@ -35,7 +34,6 @@
 import org.mockito.Mockito.verify
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class ScreenshotSoundControllerTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/appclips/AppClipsServiceTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/appclips/AppClipsServiceTest.java
index d8897e9..81301b3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/appclips/AppClipsServiceTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/appclips/AppClipsServiceTest.java
@@ -183,14 +183,14 @@
         when(mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)).thenReturn(true);
         when(mOptionalBubbles.isEmpty()).thenReturn(false);
         when(mOptionalBubbles.get()).thenReturn(mBubbles);
-        when(mBubbles.isAppBubbleTaskId(eq((FAKE_TASK_ID)))).thenReturn(false);
+        when(mBubbles.isNoteBubbleTaskId(eq((FAKE_TASK_ID)))).thenReturn(false);
     }
 
     private void mockForScreenshotBlocked() {
         when(mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)).thenReturn(true);
         when(mOptionalBubbles.isEmpty()).thenReturn(false);
         when(mOptionalBubbles.get()).thenReturn(mBubbles);
-        when(mBubbles.isAppBubbleTaskId(eq((FAKE_TASK_ID)))).thenReturn(true);
+        when(mBubbles.isNoteBubbleTaskId(eq((FAKE_TASK_ID)))).thenReturn(true);
         when(mDevicePolicyManager.getScreenCaptureDisabled(eq(null))).thenReturn(true);
     }
 
@@ -199,7 +199,7 @@
         when(mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)).thenReturn(true);
         when(mOptionalBubbles.isEmpty()).thenReturn(false);
         when(mOptionalBubbles.get()).thenReturn(mBubbles);
-        when(mBubbles.isAppBubbleTaskId(eq((FAKE_TASK_ID)))).thenReturn(true);
+        when(mBubbles.isNoteBubbleTaskId(eq((FAKE_TASK_ID)))).thenReturn(true);
         when(mDevicePolicyManager.getScreenCaptureDisabled(eq(null))).thenReturn(false);
     }
 
@@ -208,7 +208,7 @@
         when(mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)).thenReturn(true);
         when(mOptionalBubbles.isEmpty()).thenReturn(false);
         when(mOptionalBubbles.get()).thenReturn(mBubbles);
-        when(mBubbles.isAppBubbleTaskId(eq((FAKE_TASK_ID)))).thenReturn(true);
+        when(mBubbles.isNoteBubbleTaskId(eq((FAKE_TASK_ID)))).thenReturn(true);
         when(mDevicePolicyManager.getScreenCaptureDisabled(eq(null))).thenReturn(false);
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 62c3604..85e5936 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -375,7 +375,6 @@
         SystemClock systemClock = new FakeSystemClock();
         mStatusBarStateController = new StatusBarStateControllerImpl(
                 mUiEventLogger,
-                () -> mKosmos.getInteractionJankMonitor(),
                 mJavaAdapter,
                 () -> mKeyguardInteractor,
                 () -> mKeyguardTransitionInteractor,
@@ -456,7 +455,6 @@
                         mock(HeadsUpManager.class),
                         new StatusBarStateControllerImpl(
                                 new UiEventLoggerFake(),
-                                () -> mKosmos.getInteractionJankMonitor(),
                                 mJavaAdapter,
                                 () -> mKeyguardInteractor,
                                 () -> mKeyguardTransitionInteractor,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
index 93d1f59..72a5783 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
@@ -75,7 +75,6 @@
 import com.android.systemui.window.ui.viewmodel.WindowRootViewModel
 import com.google.common.truth.Truth.assertThat
 import java.util.Optional
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
@@ -93,7 +92,6 @@
 import org.mockito.MockitoAnnotations
 import org.mockito.kotlin.eq
 
-@ExperimentalCoroutinesApi
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplWithCoroutinesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplWithCoroutinesTest.kt
index ee3f801..6b5f176 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplWithCoroutinesTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/QuickSettingsControllerImplWithCoroutinesTest.kt
@@ -21,7 +21,6 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.statusbar.disableflags.shared.model.DisableFlagsModel
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.cancelChildren
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -29,7 +28,6 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class QuickSettingsControllerImplWithCoroutinesTest : QuickSettingsControllerImplBaseTest() {
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt
index 420418b..054c1b8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt
@@ -37,7 +37,6 @@
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -49,7 +48,6 @@
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableSceneContainer
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTrackerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTrackerTest.kt
index 56356b4..487f2c7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTrackerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTrackerTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.testKosmos
 import kotlin.test.Test
 import kotlin.time.Duration.Companion.seconds
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runTest
 import org.junit.runner.RunWith
@@ -61,7 +60,6 @@
             verify(latencyTracker).onActionEnd(any())
         }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun onChange_doFrameTimesOut_previousCancelled() =
         testScope.runTest {
@@ -77,7 +75,6 @@
             verify(latencyTracker).onActionCancel(any())
         }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun onChange_onMovedToDisplayTimesOut_cancelled() =
         testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/PrivacyChipRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/PrivacyChipRepositoryTest.kt
index 613f256..2f45526 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/PrivacyChipRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/data/repository/PrivacyChipRepositoryTest.kt
@@ -36,7 +36,6 @@
 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
@@ -47,7 +46,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations.initMocks
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PrivacyChipRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt
index ba559b5..1859e25 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.shade.domain.interactor
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -39,7 +37,6 @@
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
 import com.android.systemui.testKosmos
 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.TestScope
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PrivacyChipInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PrivacyChipInteractorTest.kt
index f0293a8e..14f0a45 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PrivacyChipInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PrivacyChipInteractorTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.whenever
 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
@@ -44,7 +43,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations.initMocks
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class PrivacyChipInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorSceneContainerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorSceneContainerImplTest.kt
index b917014..ca039ad 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorSceneContainerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeAnimationInteractorSceneContainerImplTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runCurrent
@@ -34,7 +33,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ShadeAnimationInteractorSceneContainerImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt
index fa4da42..61777a4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt
@@ -35,7 +35,6 @@
 import com.android.systemui.shared.recents.utilities.Utilities
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.test.TestScope
@@ -46,7 +45,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableSceneContainer
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImplTest.kt
index da652c4..4ee6200 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImplTest.kt
@@ -47,7 +47,6 @@
 import com.android.systemui.user.data.repository.fakeUserRepository
 import com.android.systemui.util.mockito.whenever
 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
@@ -56,7 +55,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class ShadeInteractorImplTest(flags: FlagsParameterization) : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImplTest.kt
index 238a1c1..1e46f78 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImplTest.kt
@@ -32,14 +32,12 @@
 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.Assert.assertThrows
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @DisableSceneContainer
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImplTest.kt
index 5c9cf82..508836e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImplTest.kt
@@ -35,7 +35,6 @@
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.testKosmos
 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.TestScope
@@ -44,7 +43,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableSceneContainer
@@ -597,7 +595,7 @@
     fun expandNotificationsShade_dualShade_opensOverlay() =
         testScope.runTest {
             kosmos.enableDualShade()
-            val shadeMode by collectLastValue(kosmos.shadeModeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
             val currentScene by collectLastValue(sceneInteractor.currentScene)
             val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
             assertThat(shadeMode).isEqualTo(ShadeMode.Dual)
@@ -614,7 +612,7 @@
     fun expandNotificationsShade_singleShade_switchesToShadeScene() =
         testScope.runTest {
             kosmos.enableSingleShade()
-            val shadeMode by collectLastValue(kosmos.shadeModeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
             val currentScene by collectLastValue(sceneInteractor.currentScene)
             val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
             assertThat(shadeMode).isEqualTo(ShadeMode.Single)
@@ -631,7 +629,7 @@
     fun expandNotificationsShade_dualShadeQuickSettingsOpen_replacesOverlay() =
         testScope.runTest {
             kosmos.enableDualShade()
-            val shadeMode by collectLastValue(kosmos.shadeModeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
             val currentScene by collectLastValue(sceneInteractor.currentScene)
             val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
             assertThat(shadeMode).isEqualTo(ShadeMode.Dual)
@@ -649,7 +647,7 @@
     fun expandQuickSettingsShade_dualShade_opensOverlay() =
         testScope.runTest {
             kosmos.enableDualShade()
-            val shadeMode by collectLastValue(kosmos.shadeModeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
             val currentScene by collectLastValue(sceneInteractor.currentScene)
             val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
             assertThat(shadeMode).isEqualTo(ShadeMode.Dual)
@@ -666,7 +664,7 @@
     fun expandQuickSettingsShade_singleShade_switchesToQuickSettingsScene() =
         testScope.runTest {
             kosmos.enableSingleShade()
-            val shadeMode by collectLastValue(kosmos.shadeModeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
             val currentScene by collectLastValue(sceneInteractor.currentScene)
             val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
             assertThat(shadeMode).isEqualTo(ShadeMode.Single)
@@ -683,7 +681,7 @@
     fun expandQuickSettingsShade_splitShade_switchesToShadeScene() =
         testScope.runTest {
             kosmos.enableSplitShade()
-            val shadeMode by collectLastValue(kosmos.shadeModeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
             val currentScene by collectLastValue(sceneInteractor.currentScene)
             val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
             assertThat(shadeMode).isEqualTo(ShadeMode.Split)
@@ -700,7 +698,7 @@
     fun expandQuickSettingsShade_dualShadeNotificationsOpen_replacesOverlay() =
         testScope.runTest {
             kosmos.enableDualShade()
-            val shadeMode by collectLastValue(kosmos.shadeModeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
             val currentScene by collectLastValue(sceneInteractor.currentScene)
             val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
             assertThat(shadeMode).isEqualTo(ShadeMode.Dual)
@@ -732,7 +730,7 @@
     fun collapseNotificationsShade_singleShade_switchesToLockscreen() =
         testScope.runTest {
             kosmos.enableSingleShade()
-            val shadeMode by collectLastValue(kosmos.shadeModeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
             val currentScene by collectLastValue(sceneInteractor.currentScene)
             val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
             assertThat(shadeMode).isEqualTo(ShadeMode.Single)
@@ -764,7 +762,7 @@
     fun collapseQuickSettingsShadeNotBypassingShade_singleShade_switchesToShade() =
         testScope.runTest {
             kosmos.enableSingleShade()
-            val shadeMode by collectLastValue(kosmos.shadeModeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
             val currentScene by collectLastValue(sceneInteractor.currentScene)
             val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
             assertThat(shadeMode).isEqualTo(ShadeMode.Single)
@@ -786,7 +784,7 @@
     fun collapseQuickSettingsShadeNotBypassingShade_splitShade_switchesToLockscreen() =
         testScope.runTest {
             kosmos.enableSplitShade()
-            val shadeMode by collectLastValue(kosmos.shadeModeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
             val currentScene by collectLastValue(sceneInteractor.currentScene)
             val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
             assertThat(shadeMode).isEqualTo(ShadeMode.Split)
@@ -808,7 +806,7 @@
     fun collapseQuickSettingsShadeBypassingShade_singleShade_switchesToLockscreen() =
         testScope.runTest {
             kosmos.enableSingleShade()
-            val shadeMode by collectLastValue(kosmos.shadeModeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
             val currentScene by collectLastValue(sceneInteractor.currentScene)
             val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
             assertThat(shadeMode).isEqualTo(ShadeMode.Single)
@@ -844,7 +842,7 @@
         }
 
     private fun TestScope.openShade(overlay: OverlayKey) {
-        val shadeMode by collectLastValue(kosmos.shadeModeInteractor.shadeMode)
+        val shadeMode by collectLastValue(kosmos.shadeMode)
         val isAnyExpanded by collectLastValue(underTest.isAnyExpanded)
         val currentScene by collectLastValue(sceneInteractor.currentScene)
         val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt
index 0406c3e..b8f66ac 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt
@@ -39,7 +39,7 @@
 import com.android.systemui.shade.ShadeExpansionListener
 import com.android.systemui.shade.domain.interactor.disableDualShade
 import com.android.systemui.shade.domain.interactor.enableDualShade
-import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeMode
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.statusbar.notification.stack.notificationStackScrollLayoutController
 import com.android.systemui.statusbar.phone.scrimController
@@ -48,7 +48,6 @@
 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.TestScope
@@ -60,13 +59,11 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class ShadeStartableTest(flags: FlagsParameterization) : SysuiTestCase() {
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
-    private val shadeInteractor by lazy { kosmos.shadeInteractor }
     private val sceneInteractor by lazy { kosmos.sceneInteractor }
     private val shadeExpansionStateManager by lazy { kosmos.shadeExpansionStateManager }
     private val fakeConfigurationRepository by lazy { kosmos.fakeConfigurationRepository }
@@ -91,7 +88,7 @@
         testScope.runTest {
             overrideResource(R.bool.config_use_split_notification_shade, false)
             kosmos.disableDualShade()
-            val shadeMode by collectLastValue(shadeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
 
             underTest.start()
             assertThat(shadeMode).isEqualTo(ShadeMode.Single)
@@ -110,7 +107,7 @@
         testScope.runTest {
             overrideResource(R.bool.config_use_split_notification_shade, false)
             kosmos.enableDualShade()
-            val shadeMode by collectLastValue(shadeInteractor.shadeMode)
+            val shadeMode by collectLastValue(kosmos.shadeMode)
 
             underTest.start()
             assertThat(shadeMode).isEqualTo(ShadeMode.Dual)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModelTest.kt
index f5022b9..2038adc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModelTest.kt
@@ -35,14 +35,12 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class NotificationShadeWindowModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt
index 8ce20d2..061e04e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt
@@ -23,12 +23,14 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.domain.interactor.disableDualShade
 import com.android.systemui.shade.domain.interactor.enableDualShade
+import com.android.systemui.shade.domain.interactor.enableSingleShade
+import com.android.systemui.shade.domain.interactor.enableSplitShade
+import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel.HeaderChipHighlight
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.fakeMobileIconsInteractor
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.argThat
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -41,7 +43,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableSceneContainer
@@ -273,6 +274,116 @@
             assertThat(currentOverlays).doesNotContain(Overlays.QuickSettingsShade)
         }
 
+    @Test
+    fun highlightChips_notifsOpenInSingleShade_bothNone() =
+        testScope.runTest {
+            kosmos.enableSingleShade()
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
+            setScene(Scenes.Shade)
+            assertThat(currentScene).isEqualTo(Scenes.Shade)
+            assertThat(currentOverlays).isEmpty()
+
+            assertThat(underTest.notificationsChipHighlight).isEqualTo(HeaderChipHighlight.None)
+            assertThat(underTest.quickSettingsChipHighlight).isEqualTo(HeaderChipHighlight.None)
+        }
+
+    @Test
+    fun highlightChips_notifsOpenInSplitShade_bothNone() =
+        testScope.runTest {
+            kosmos.enableSplitShade()
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
+            setScene(Scenes.Shade)
+            assertThat(currentScene).isEqualTo(Scenes.Shade)
+            assertThat(currentOverlays).isEmpty()
+
+            assertThat(underTest.notificationsChipHighlight).isEqualTo(HeaderChipHighlight.None)
+            assertThat(underTest.quickSettingsChipHighlight).isEqualTo(HeaderChipHighlight.None)
+        }
+
+    @Test
+    fun highlightChips_quickSettingsOpenInSingleShade_bothNone() =
+        testScope.runTest {
+            kosmos.enableSingleShade()
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
+            setScene(Scenes.QuickSettings)
+            assertThat(currentScene).isEqualTo(Scenes.QuickSettings)
+            assertThat(currentOverlays).isEmpty()
+
+            assertThat(underTest.notificationsChipHighlight).isEqualTo(HeaderChipHighlight.None)
+            assertThat(underTest.quickSettingsChipHighlight).isEqualTo(HeaderChipHighlight.None)
+        }
+
+    @Test
+    fun highlightChips_notifsOpenInDualShade_notifsStrongQuickSettingsWeak() =
+        testScope.runTest {
+            kosmos.enableDualShade()
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
+
+            // Test the lockscreen scenario.
+            setScene(Scenes.Lockscreen)
+            setOverlay(Overlays.NotificationsShade)
+            assertThat(underTest.notificationsChipHighlight).isEqualTo(HeaderChipHighlight.Strong)
+            assertThat(underTest.quickSettingsChipHighlight).isEqualTo(HeaderChipHighlight.Weak)
+
+            // Test the unlocked scenario.
+            setDeviceEntered(true)
+            setScene(Scenes.Gone)
+            setOverlay(Overlays.NotificationsShade)
+            assertThat(currentScene).isEqualTo(Scenes.Gone)
+            assertThat(currentOverlays).isNotEmpty()
+            assertThat(underTest.notificationsChipHighlight).isEqualTo(HeaderChipHighlight.Strong)
+            assertThat(underTest.quickSettingsChipHighlight).isEqualTo(HeaderChipHighlight.Weak)
+        }
+
+    @Test
+    fun highlightChips_quickSettingsOpenInDualShade_notifsWeakQuickSettingsStrong() =
+        testScope.runTest {
+            kosmos.enableDualShade()
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
+
+            // Test the lockscreen scenario.
+            setScene(Scenes.Lockscreen)
+            setOverlay(Overlays.QuickSettingsShade)
+            assertThat(underTest.notificationsChipHighlight).isEqualTo(HeaderChipHighlight.Weak)
+            assertThat(underTest.quickSettingsChipHighlight).isEqualTo(HeaderChipHighlight.Strong)
+
+            // Test the unlocked scenario.
+            setDeviceEntered(true)
+            setScene(Scenes.Gone)
+            setOverlay(Overlays.QuickSettingsShade)
+            assertThat(currentScene).isEqualTo(Scenes.Gone)
+            assertThat(currentOverlays).isNotEmpty()
+            assertThat(underTest.notificationsChipHighlight).isEqualTo(HeaderChipHighlight.Weak)
+            assertThat(underTest.quickSettingsChipHighlight).isEqualTo(HeaderChipHighlight.Strong)
+        }
+
+    @Test
+    fun highlightChips_noOverlaysInDualShade_bothNone() =
+        testScope.runTest {
+            kosmos.enableDualShade()
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
+
+            // Test the lockscreen scenario.
+            setScene(Scenes.Lockscreen)
+            assertThat(currentOverlays).isEmpty()
+            assertThat(underTest.notificationsChipHighlight).isEqualTo(HeaderChipHighlight.None)
+            assertThat(underTest.quickSettingsChipHighlight).isEqualTo(HeaderChipHighlight.None)
+
+            // Test the unlocked scenario.
+            setDeviceEntered(true)
+            setScene(Scenes.Gone)
+            assertThat(currentScene).isEqualTo(Scenes.Gone)
+            assertThat(currentOverlays).isEmpty()
+            assertThat(underTest.notificationsChipHighlight).isEqualTo(HeaderChipHighlight.None)
+            assertThat(underTest.quickSettingsChipHighlight).isEqualTo(HeaderChipHighlight.None)
+        }
+
     companion object {
         private val SUB_1 =
             SubscriptionModel(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelTest.kt
index 27faeb8..623a0eb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelTest.kt
@@ -46,7 +46,6 @@
 import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider
 import com.google.common.truth.Truth.assertThat
 import java.util.Locale
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.update
@@ -57,7 +56,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelTest.kt
index 8f904f7..9a4f8ea 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelTest.kt
@@ -51,7 +51,6 @@
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -60,7 +59,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt
index 6b2c4b2..4bd02e0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt
@@ -4,7 +4,6 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.emptyFlow
@@ -16,7 +15,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ConditionExtensionsTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
index a79f408..d2ea62d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
@@ -29,10 +29,12 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ShadeInterpolation
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeExpansionChangeEvent
+import com.android.systemui.shared.Flags as SharedFlags
 import com.android.systemui.statusbar.phone.BiometricUnlockController
 import com.android.systemui.statusbar.phone.DozeParameters
 import com.android.systemui.statusbar.phone.ScrimController
@@ -80,6 +82,7 @@
     @Mock private lateinit var blurUtils: BlurUtils
     @Mock private lateinit var biometricUnlockController: BiometricUnlockController
     @Mock private lateinit var keyguardStateController: KeyguardStateController
+    @Mock private lateinit var keyguardInteractor: KeyguardInteractor
     @Mock private lateinit var choreographer: Choreographer
     @Mock private lateinit var wallpaperController: WallpaperController
     @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
@@ -123,6 +126,7 @@
                 blurUtils,
                 biometricUnlockController,
                 keyguardStateController,
+                keyguardInteractor,
                 choreographer,
                 wallpaperController,
                 notificationShadeWindowController,
@@ -308,6 +312,7 @@
     }
 
     @Test
+    @DisableFlags(SharedFlags.FLAG_AMBIENT_AOD)
     fun onDozeAmountChanged_appliesBlur() {
         statusBarStateListener.onDozeAmountChanged(1f, 1f)
         notificationShadeDepthController.updateBlurCallback.doFrame(0)
@@ -315,6 +320,14 @@
     }
 
     @Test
+    @EnableFlags(SharedFlags.FLAG_AMBIENT_AOD)
+    fun onDozeAmountChanged_doesNotApplyBlurWithAmbientAod() {
+        statusBarStateListener.onDozeAmountChanged(1f, 1f)
+        notificationShadeDepthController.updateBlurCallback.doFrame(0)
+        verify(blurUtils).applyBlur(any(), eq(0), eq(false))
+    }
+
+    @Test
     fun setFullShadeTransition_appliesBlur_onlyIfSupported() {
         reset(blurUtils)
         `when`(blurUtils.blurRadiusOfRatio(anyFloat())).then { answer ->
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt
index 72a2ce5..03dee3a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt
@@ -40,7 +40,6 @@
 import com.google.common.truth.Truth.assertThat
 import junit.framework.Assert.assertTrue
 import kotlin.test.Test
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -49,7 +48,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class OperatorNameViewControllerTest : SysuiTestCase() {
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 a51e0c0..7a982a3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar
 
 import android.animation.ObjectAnimator
@@ -33,7 +31,6 @@
 import com.android.systemui.flags.DisableSceneContainer
 import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.flags.parameterizeSceneContainerFlag
-import com.android.systemui.jank.interactionJankMonitor
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
@@ -59,7 +56,6 @@
 import com.android.systemui.util.kotlin.JavaAdapter
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Assert.assertEquals
@@ -113,7 +109,6 @@
             object :
                 StatusBarStateControllerImpl(
                     uiEventLogger,
-                    { kosmos.interactionJankMonitor },
                     JavaAdapter(testScope.backgroundScope),
                     { kosmos.keyguardInteractor },
                     { kosmos.keyguardTransitionInteractor },
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
index 75262a4..03c0751 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
@@ -24,9 +24,9 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.Expandable
+import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.activityStarter
 import com.android.systemui.res.R
@@ -47,6 +47,7 @@
 import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
+import com.android.systemui.testKosmos
 import com.android.systemui.util.time.fakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
@@ -60,7 +61,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class CallChipViewModelTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val notificationListRepository = kosmos.activeNotificationListRepository
     private val testScope = kosmos.testScope
     private val repo = kosmos.ongoingCallRepository
@@ -162,25 +163,34 @@
 
     @Test
     @DisableFlags(StatusBarConnectedDisplays.FLAG_NAME)
-    fun chip_zeroStartTime_cdFlagOff_iconIsNotifIcon() =
+    fun chip_zeroStartTime_cdFlagOff_iconIsNotifIcon_withContentDescription() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
             val notifIcon = createStatusBarIconViewOrNull()
-            repo.setOngoingCallState(inCallModel(startTimeMs = 0, notificationIcon = notifIcon))
+            repo.setOngoingCallState(
+                inCallModel(
+                    startTimeMs = 0,
+                    notificationIcon = notifIcon,
+                    appName = "Fake app name",
+                )
+            )
 
             assertThat((latest as OngoingActivityChipModel.Shown).icon)
                 .isInstanceOf(OngoingActivityChipModel.ChipIcon.StatusBarView::class.java)
             val actualIcon =
-                (((latest as OngoingActivityChipModel.Shown).icon)
-                        as OngoingActivityChipModel.ChipIcon.StatusBarView)
-                    .impl
-            assertThat(actualIcon).isEqualTo(notifIcon)
+                (latest as OngoingActivityChipModel.Shown).icon
+                    as OngoingActivityChipModel.ChipIcon.StatusBarView
+            assertThat(actualIcon.impl).isEqualTo(notifIcon)
+            assertThat(actualIcon.contentDescription.loadContentDescription(context))
+                .contains("Ongoing call")
+            assertThat(actualIcon.contentDescription.loadContentDescription(context))
+                .contains("Fake app name")
         }
 
     @Test
     @EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
-    fun chip_zeroStartTime_cdFlagOn_iconIsNotifKeyIcon() =
+    fun chip_zeroStartTime_cdFlagOn_iconIsNotifKeyIcon_withContentDescription() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
@@ -189,11 +199,22 @@
                     startTimeMs = 0,
                     notificationIcon = createStatusBarIconViewOrNull(),
                     notificationKey = "notifKey",
+                    appName = "Fake app name",
                 )
             )
 
             assertThat((latest as OngoingActivityChipModel.Shown).icon)
-                .isEqualTo(OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon("notifKey"))
+                .isInstanceOf(
+                    OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon::class.java
+                )
+            val actualIcon =
+                (latest as OngoingActivityChipModel.Shown).icon
+                    as OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon
+            assertThat(actualIcon.notificationKey).isEqualTo("notifKey")
+            assertThat(actualIcon.contentDescription.loadContentDescription(context))
+                .contains("Ongoing call")
+            assertThat(actualIcon.contentDescription.loadContentDescription(context))
+                .contains("Fake app name")
         }
 
     @Test
@@ -216,7 +237,7 @@
 
     @Test
     @EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
-    fun chip_notifIconFlagOn_butNullNotifIcon_iconNotifKey() =
+    fun chip_notifIconFlagOn_butNullNotifIcon_cdFlagOn_iconIsNotifKeyIcon_withContentDescription() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
@@ -225,11 +246,22 @@
                     startTimeMs = 1000,
                     notificationIcon = null,
                     notificationKey = "notifKey",
+                    appName = "Fake app name",
                 )
             )
 
             assertThat((latest as OngoingActivityChipModel.Shown).icon)
-                .isEqualTo(OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon("notifKey"))
+                .isInstanceOf(
+                    OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon::class.java
+                )
+            val actualIcon =
+                (latest as OngoingActivityChipModel.Shown).icon
+                    as OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon
+            assertThat(actualIcon.notificationKey).isEqualTo("notifKey")
+            assertThat(actualIcon.contentDescription.loadContentDescription(context))
+                .contains("Ongoing call")
+            assertThat(actualIcon.contentDescription.loadContentDescription(context))
+                .contains("Fake app name")
         }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt
index dd0ac1c..b2174c1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt
@@ -28,14 +28,12 @@
 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.junit.runner.RunWith
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class MediaRouterChipInteractorTest : SysuiTestCase() {
     val kosmos = Kosmos()
     val testScope = kosmos.testScope
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt
index b297bed..274efbb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt
@@ -16,8 +16,6 @@
 
 package com.android.systemui.statusbar.chips.casttootherdevice.ui.view
 
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import org.junit.runner.RunWith
 import android.content.ComponentName
 import android.content.DialogInterface
 import android.content.Intent
@@ -25,6 +23,11 @@
 import android.content.packageManager
 import android.content.pm.ApplicationInfo
 import android.content.pm.PackageManager
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.view.View
+import android.view.Window
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.kosmos.Kosmos
@@ -40,19 +43,19 @@
 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.junit.runner.RunWith
 import org.mockito.kotlin.any
 import org.mockito.kotlin.argumentCaptor
 import org.mockito.kotlin.eq
 import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class EndCastScreenToOtherDeviceDialogDelegateTest : SysuiTestCase() {
     private val kosmos = Kosmos().also { it.testCase = this }
     private val sysuiDialog = mock<SystemUIDialog>()
@@ -250,6 +253,36 @@
             assertThat(kosmos.fakeMediaProjectionRepository.stopProjectingInvoked).isTrue()
         }
 
+    @Test
+    @EnableFlags(com.android.media.projection.flags.Flags.FLAG_SHOW_STOP_DIALOG_POST_CALL_END)
+    fun accessibilityDataSensitive_flagEnabled_appliesSetting() {
+        createAndSetDelegate(ENTIRE_SCREEN)
+
+        val window = mock<Window>()
+        val decorView = mock<View>()
+        whenever(sysuiDialog.window).thenReturn(window)
+        whenever(window.decorView).thenReturn(decorView)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(decorView).setAccessibilityDataSensitive(View.ACCESSIBILITY_DATA_SENSITIVE_YES)
+    }
+
+    @Test
+    @DisableFlags(com.android.media.projection.flags.Flags.FLAG_SHOW_STOP_DIALOG_POST_CALL_END)
+    fun accessibilityDataSensitive_flagDisabled_doesNotApplySetting() {
+        createAndSetDelegate(ENTIRE_SCREEN)
+
+        val window = mock<Window>()
+        val decorView = mock<View>()
+        whenever(sysuiDialog.window).thenReturn(window)
+        whenever(window.decorView).thenReturn(decorView)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(decorView, never()).setAccessibilityDataSensitive(any())
+    }
+
     private fun createAndSetDelegate(state: MediaProjectionState.Projecting) {
         underTest =
             EndCastScreenToOtherDeviceDialogDelegate(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt
index 9e8f22e..88207d1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt
@@ -18,6 +18,10 @@
 
 import android.content.DialogInterface
 import android.content.applicationContext
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.view.View
+import android.view.Window
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -33,18 +37,19 @@
 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.junit.runner.RunWith
+import org.mockito.kotlin.any
 import org.mockito.kotlin.argumentCaptor
 import org.mockito.kotlin.eq
 import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
 import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class EndGenericCastToOtherDeviceDialogDelegateTest : SysuiTestCase() {
     private val kosmos = Kosmos().also { it.testCase = this }
     private val sysuiDialog = mock<SystemUIDialog>()
@@ -132,7 +137,7 @@
             verify(sysuiDialog)
                 .setPositiveButton(
                     eq(R.string.cast_to_other_device_stop_dialog_button),
-                    clickListener.capture()
+                    clickListener.capture(),
                 )
 
             // Verify that clicking the button stops the recording
@@ -144,6 +149,36 @@
             assertThat(kosmos.fakeMediaRouterRepository.lastStoppedDevice).isEqualTo(device)
         }
 
+    @Test
+    @EnableFlags(com.android.media.projection.flags.Flags.FLAG_SHOW_STOP_DIALOG_POST_CALL_END)
+    fun accessibilityDataSensitive_flagEnabled_appliesSetting() {
+        createAndSetDelegate()
+
+        val window = mock<Window>()
+        val decorView = mock<View>()
+        whenever(sysuiDialog.window).thenReturn(window)
+        whenever(window.decorView).thenReturn(decorView)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(decorView).setAccessibilityDataSensitive(View.ACCESSIBILITY_DATA_SENSITIVE_YES)
+    }
+
+    @Test
+    @DisableFlags(com.android.media.projection.flags.Flags.FLAG_SHOW_STOP_DIALOG_POST_CALL_END)
+    fun accessibilityDataSensitive_flagDisabled_doesNotApplySetting() {
+        createAndSetDelegate()
+
+        val window = mock<Window>()
+        val decorView = mock<View>()
+        whenever(sysuiDialog.window).thenReturn(window)
+        whenever(window.decorView).thenReturn(decorView)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(decorView, never()).setAccessibilityDataSensitive(any())
+    }
+
     private fun createAndSetDelegate(deviceName: String? = null) {
         underTest =
             EndGenericCastToOtherDeviceDialogDelegate(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorTest.kt
index fe15eac..05f2585 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorTest.kt
@@ -49,6 +49,7 @@
             val startingNotif =
                 activeNotificationModel(
                     key = "notif1",
+                    appName = "Fake Name",
                     statusBarChipIcon = icon,
                     promotedContent = PROMOTED_CONTENT,
                 )
@@ -58,6 +59,7 @@
             val latest by collectLastValue(underTest.notificationChip)
 
             assertThat(latest!!.key).isEqualTo("notif1")
+            assertThat(latest!!.appName).isEqualTo("Fake Name")
             assertThat(latest!!.statusBarChipIconView).isEqualTo(icon)
             assertThat(latest!!.promotedContent).isEqualTo(PROMOTED_CONTENT)
         }
@@ -70,6 +72,7 @@
                 factory.create(
                     activeNotificationModel(
                         key = "notif1",
+                        appName = "Fake Name",
                         statusBarChipIcon = originalIconView,
                         promotedContent = PROMOTED_CONTENT,
                     ),
@@ -82,12 +85,14 @@
             underTest.setNotification(
                 activeNotificationModel(
                     key = "notif1",
+                    appName = "New Name",
                     statusBarChipIcon = newIconView,
                     promotedContent = PROMOTED_CONTENT,
                 )
             )
 
             assertThat(latest!!.key).isEqualTo("notif1")
+            assertThat(latest!!.appName).isEqualTo("New Name")
             assertThat(latest!!.statusBarChipIconView).isEqualTo(newIconView)
         }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
index 942e6554..1f77ddc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.chips.notification.ui.viewmodel
 
+import android.content.Context
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
 import android.view.View
@@ -23,6 +24,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.Flags.FLAG_PROMOTE_NOTIFICATIONS_AUTOMATICALLY
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.kosmos.collectLastValue
@@ -125,7 +127,7 @@
 
     @Test
     @DisableFlags(FLAG_PROMOTE_NOTIFICATIONS_AUTOMATICALLY)
-    fun chips_onePromotedNotif_statusBarIconViewMatches() =
+    fun chips_onePromotedNotif_connectedDisplaysFlagDisabled_statusBarIconViewMatches() =
         kosmos.runTest {
             val latest by collectLastValue(underTest.chips)
 
@@ -134,6 +136,7 @@
                 listOf(
                     activeNotificationModel(
                         key = "notif",
+                        appName = "Fake App Name",
                         statusBarChipIcon = icon,
                         promotedContent = PromotedNotificationContentModel.Builder("notif").build(),
                     )
@@ -142,7 +145,13 @@
 
             assertThat(latest).hasSize(1)
             val chip = latest!![0]
-            assertIsNotifChip(chip, icon, "notif")
+            assertIsNotifChip(
+                chip,
+                context,
+                icon,
+                expectedNotificationKey = "notif",
+                expectedContentDescriptionSubstrings = listOf("Ongoing", "Fake App Name"),
+            )
         }
 
     @Test
@@ -157,6 +166,7 @@
                 listOf(
                     activeNotificationModel(
                         key = notifKey,
+                        appName = "Fake App Name",
                         statusBarChipIcon = null,
                         promotedContent = PromotedNotificationContentModel.Builder(notifKey).build(),
                     )
@@ -165,9 +175,13 @@
 
             assertThat(latest).hasSize(1)
             val chip = latest!![0]
-            assertThat(chip).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
-            assertThat(chip.icon)
-                .isEqualTo(OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon(notifKey))
+            assertIsNotifChip(
+                chip,
+                context,
+                expectedIcon = null,
+                expectedNotificationKey = "notif",
+                expectedContentDescriptionSubstrings = listOf("Ongoing", "Fake App Name"),
+            )
         }
 
     @Test
@@ -230,8 +244,8 @@
             )
 
             assertThat(latest).hasSize(2)
-            assertIsNotifChip(latest!![0], firstIcon, "notif1")
-            assertIsNotifChip(latest!![1], secondIcon, "notif2")
+            assertIsNotifChip(latest!![0], context, firstIcon, "notif1")
+            assertIsNotifChip(latest!![1], context, secondIcon, "notif2")
         }
 
     @Test
@@ -590,7 +604,7 @@
             // THEN the "notif" chip keeps showing time
             val chip = latest!![0]
             assertThat(chip).isInstanceOf(OngoingActivityChipModel.Shown.ShortTimeDelta::class.java)
-            assertIsNotifChip(chip, icon, "notif")
+            assertIsNotifChip(chip, context, icon, "notif")
         }
 
     @Test
@@ -705,24 +719,41 @@
     companion object {
         fun assertIsNotifChip(
             latest: OngoingActivityChipModel?,
+            context: Context,
             expectedIcon: StatusBarIconView?,
-            notificationKey: String,
+            expectedNotificationKey: String,
+            expectedContentDescriptionSubstrings: List<String> = emptyList(),
         ) {
             val shown = latest as OngoingActivityChipModel.Shown
             if (StatusBarConnectedDisplays.isEnabled) {
                 assertThat(shown.icon)
-                    .isEqualTo(
-                        OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon(notificationKey)
+                    .isInstanceOf(
+                        OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon::class.java
                     )
+                val icon = shown.icon as OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon
+
+                assertThat(icon.notificationKey).isEqualTo(expectedNotificationKey)
+                expectedContentDescriptionSubstrings.forEach {
+                    assertThat(icon.contentDescription.loadContentDescription(context)).contains(it)
+                }
             } else {
-                assertThat(latest.icon)
-                    .isEqualTo(OngoingActivityChipModel.ChipIcon.StatusBarView(expectedIcon!!))
+                assertThat(shown.icon)
+                    .isInstanceOf(OngoingActivityChipModel.ChipIcon.StatusBarView::class.java)
+                val icon = shown.icon as OngoingActivityChipModel.ChipIcon.StatusBarView
+                assertThat(icon.impl).isEqualTo(expectedIcon!!)
+                expectedContentDescriptionSubstrings.forEach {
+                    assertThat(icon.contentDescription.loadContentDescription(context)).contains(it)
+                }
             }
         }
 
         fun assertIsNotifKey(latest: OngoingActivityChipModel?, expectedKey: String) {
-            assertThat((latest as OngoingActivityChipModel.Shown).icon)
-                .isEqualTo(OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon(expectedKey))
+            assertThat(
+                    ((latest as OngoingActivityChipModel.Shown).icon
+                            as OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon)
+                        .notificationKey
+                )
+                .isEqualTo(expectedKey)
         }
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt
index 11a125a..538247e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt
@@ -34,7 +34,6 @@
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -42,7 +41,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class ScreenRecordChipInteractorTest : SysuiTestCase() {
     private val kosmos = testKosmos().useUnconfinedTestDispatcher()
     private val testScope = kosmos.testScope
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt
index 709e0b5..f560ee7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt
@@ -23,6 +23,10 @@
 import android.content.applicationContext
 import android.content.packageManager
 import android.content.pm.ApplicationInfo
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.view.View
+import android.view.Window
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -37,7 +41,6 @@
 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.junit.runner.RunWith
@@ -45,12 +48,12 @@
 import org.mockito.kotlin.argumentCaptor
 import org.mockito.kotlin.eq
 import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class EndScreenRecordingDialogDelegateTest : SysuiTestCase() {
     private val kosmos = Kosmos().also { it.testCase = this }
 
@@ -130,7 +133,7 @@
             verify(sysuiDialog)
                 .setPositiveButton(
                     eq(R.string.screenrecord_stop_dialog_button),
-                    clickListener.capture()
+                    clickListener.capture(),
                 )
 
             // Verify that clicking the button stops the recording
@@ -142,6 +145,36 @@
             assertThat(kosmos.screenRecordRepository.stopRecordingInvoked).isTrue()
         }
 
+    @Test
+    @EnableFlags(com.android.media.projection.flags.Flags.FLAG_SHOW_STOP_DIALOG_POST_CALL_END)
+    fun accessibilityDataSensitive_flagEnabled_appliesSetting() {
+        createAndSetDelegate(recordedTask = null)
+
+        val window = mock<Window>()
+        val decorView = mock<View>()
+        whenever(sysuiDialog.window).thenReturn(window)
+        whenever(window.decorView).thenReturn(decorView)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(decorView).setAccessibilityDataSensitive(View.ACCESSIBILITY_DATA_SENSITIVE_YES)
+    }
+
+    @Test
+    @DisableFlags(com.android.media.projection.flags.Flags.FLAG_SHOW_STOP_DIALOG_POST_CALL_END)
+    fun accessibilityDataSensitive_flagDisabled_doesNotApplySetting() {
+        createAndSetDelegate(recordedTask = null)
+
+        val window = mock<Window>()
+        val decorView = mock<View>()
+        whenever(sysuiDialog.window).thenReturn(window)
+        whenever(window.decorView).thenReturn(decorView)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(decorView, never()).setAccessibilityDataSensitive(any())
+    }
+
     private fun createAndSetDelegate(recordedTask: ActivityManager.RunningTaskInfo?) {
         underTest =
             EndScreenRecordingDialogDelegate(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndGenericShareToAppDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndGenericShareToAppDialogDelegateTest.kt
index 411d306..27ed059 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndGenericShareToAppDialogDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndGenericShareToAppDialogDelegateTest.kt
@@ -18,6 +18,11 @@
 
 import android.content.DialogInterface
 import android.content.applicationContext
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.view.View
+import android.view.Window
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.kosmos.testScope
@@ -28,29 +33,27 @@
 import com.android.systemui.testKosmos
 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.junit.runner.RunWith
 import org.mockito.kotlin.any
 import org.mockito.kotlin.argumentCaptor
 import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
 import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
 class EndGenericShareToAppDialogDelegateTest : SysuiTestCase() {
     private val kosmos = testKosmos()
     private val sysuiDialog = mock<SystemUIDialog>()
-    private val underTest =
-        EndGenericShareToAppDialogDelegate(
-            kosmos.endMediaProjectionDialogHelper,
-            kosmos.applicationContext,
-            stopAction = kosmos.mediaProjectionChipInteractor::stopProjecting,
-        )
+    private lateinit var underTest: EndGenericShareToAppDialogDelegate
 
     @Test
     fun positiveButton_clickStopsRecording() =
         kosmos.testScope.runTest {
+            createAndSetDelegate()
             underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
 
             assertThat(kosmos.fakeMediaProjectionRepository.stopProjectingInvoked).isFalse()
@@ -62,4 +65,43 @@
 
             assertThat(kosmos.fakeMediaProjectionRepository.stopProjectingInvoked).isTrue()
         }
+
+    @Test
+    @EnableFlags(com.android.media.projection.flags.Flags.FLAG_SHOW_STOP_DIALOG_POST_CALL_END)
+    fun accessibilityDataSensitive_flagEnabled_appliesSetting() {
+        createAndSetDelegate()
+
+        val window = mock<Window>()
+        val decorView = mock<View>()
+        whenever(sysuiDialog.window).thenReturn(window)
+        whenever(window.decorView).thenReturn(decorView)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(decorView).setAccessibilityDataSensitive(View.ACCESSIBILITY_DATA_SENSITIVE_YES)
+    }
+
+    @Test
+    @DisableFlags(com.android.media.projection.flags.Flags.FLAG_SHOW_STOP_DIALOG_POST_CALL_END)
+    fun accessibilityDataSensitive_flagDisabled_doesNotApplySetting() {
+        createAndSetDelegate()
+
+        val window = mock<Window>()
+        val decorView = mock<View>()
+        whenever(sysuiDialog.window).thenReturn(window)
+        whenever(window.decorView).thenReturn(decorView)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(decorView, never()).setAccessibilityDataSensitive(any())
+    }
+
+    private fun createAndSetDelegate() {
+        underTest =
+            EndGenericShareToAppDialogDelegate(
+                kosmos.endMediaProjectionDialogHelper,
+                kosmos.applicationContext,
+                stopAction = kosmos.mediaProjectionChipInteractor::stopProjecting,
+            )
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegateTest.kt
index 6885a6b..95aa6cd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegateTest.kt
@@ -23,6 +23,11 @@
 import android.content.packageManager
 import android.content.pm.ApplicationInfo
 import android.content.pm.PackageManager
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.view.View
+import android.view.Window
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.kosmos.Kosmos
@@ -38,18 +43,19 @@
 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.junit.runner.RunWith
 import org.mockito.kotlin.any
 import org.mockito.kotlin.argumentCaptor
 import org.mockito.kotlin.eq
 import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
 class EndShareScreenToAppDialogDelegateTest : SysuiTestCase() {
     private val kosmos = Kosmos().also { it.testCase = this }
     private val sysuiDialog = mock<SystemUIDialog>()
@@ -193,6 +199,40 @@
             assertThat(kosmos.fakeMediaProjectionRepository.stopProjectingInvoked).isTrue()
         }
 
+    @Test
+    @EnableFlags(com.android.media.projection.flags.Flags.FLAG_SHOW_STOP_DIALOG_POST_CALL_END)
+    fun accessibilityDataSensitive_flagEnabled_appliesSetting() {
+        createAndSetDelegate(ENTIRE_SCREEN)
+        whenever(kosmos.packageManager.getApplicationInfo(eq(HOST_PACKAGE), any<Int>()))
+            .thenThrow(PackageManager.NameNotFoundException())
+
+        val window = mock<Window>()
+        val decorView = mock<View>()
+        whenever(sysuiDialog.window).thenReturn(window)
+        whenever(window.decorView).thenReturn(decorView)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(decorView).setAccessibilityDataSensitive(View.ACCESSIBILITY_DATA_SENSITIVE_YES)
+    }
+
+    @Test
+    @DisableFlags(com.android.media.projection.flags.Flags.FLAG_SHOW_STOP_DIALOG_POST_CALL_END)
+    fun accessibilityDataSensitive_flagDisabled_doesNotApplySetting() {
+        createAndSetDelegate(ENTIRE_SCREEN)
+        whenever(kosmos.packageManager.getApplicationInfo(eq(HOST_PACKAGE), any<Int>()))
+            .thenThrow(PackageManager.NameNotFoundException())
+
+        val window = mock<Window>()
+        val decorView = mock<View>()
+        whenever(sysuiDialog.window).thenReturn(window)
+        whenever(window.decorView).thenReturn(decorView)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(decorView, never()).setAccessibilityDataSensitive(any())
+    }
+
     private fun createAndSetDelegate(state: MediaProjectionState.Projecting) {
         underTest =
             EndShareScreenToAppDialogDelegate(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
index 5a66888..3961e17 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
@@ -297,6 +297,33 @@
         }
 
     @Test
+    @EnableFlags(com.android.media.projection.flags.Flags.FLAG_SHOW_STOP_DIALOG_POST_CALL_END)
+    fun stopDialog_flagEnabled_eventEmitted_dialogCannotBeDismissedByTouchOutside() =
+        kosmos.runTest {
+            val latestDialogModel by collectLastValue(underTest.stopDialogToShow)
+
+            mediaProjectionRepo.mediaProjectionState.value =
+                MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
+
+            fakeMediaProjectionRepository.emitProjectionStartedDuringCallAndActivePostCallEvent()
+
+            // Verify that the dialog is shown
+            assertThat(latestDialogModel)
+                .isInstanceOf(MediaProjectionStopDialogModel.Shown::class.java)
+
+            val dialogModel = latestDialogModel as MediaProjectionStopDialogModel.Shown
+
+            whenever(dialogModel.dialogDelegate.createDialog()).thenReturn(mockDialog)
+
+            dialogModel.createAndShowDialog()
+
+            verify(mockDialog).show()
+
+            // Verify that setCanceledOnTouchOutside(false) is called
+            verify(mockDialog).setCanceledOnTouchOutside(false)
+        }
+
+    @Test
     fun chip_notProjectingState_isHidden() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt
index d099e70..52d9663 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
@@ -39,7 +38,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class ChipTransitionHelperTest : SysuiTestCase() {
     private val kosmos = Kosmos()
     private val testScope = kosmos.testScope
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
index 7a33cbe..08f1cf0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
@@ -52,7 +52,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.time.fakeSystemClock
 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.runCurrent
@@ -71,7 +70,6 @@
 /** Tests for [OngoingActivityChipsViewModel] when the [StatusBarNotifChips] flag is disabled. */
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 @DisableFlags(StatusBarNotifChips.FLAG_NAME)
 class OngoingActivityChipsViewModelTest : SysuiTestCase() {
     private val kosmos = testKosmos()
@@ -404,7 +402,7 @@
         }
 
         fun assertIsCallChip(latest: OngoingActivityChipModel?, notificationKey: String) {
-            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
             if (StatusBarConnectedDisplays.isEnabled) {
                 assertNotificationIcon(latest, notificationKey)
                 return
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt
index 28f3601..29528cc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt
@@ -18,15 +18,20 @@
 
 import android.content.DialogInterface
 import android.content.packageManager
+import android.content.res.Configuration
+import android.content.res.mainResources
 import android.graphics.Bitmap
 import android.graphics.drawable.BitmapDrawable
+import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
 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.animation.Expandable
+import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.display.data.repository.displayStateRepository
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
@@ -48,22 +53,21 @@
 import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsScreenRecordChip
 import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsShareToAppChip
 import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.getStopActionFromDialog
-import com.android.systemui.statusbar.commandline.commandRegistry
+import com.android.systemui.statusbar.core.StatusBarRootModernization
 import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
 import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
 import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
 import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
 import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
+import com.android.systemui.statusbar.notification.shared.CallType
 import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
 import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
 import com.android.systemui.testKosmos
 import com.android.systemui.util.time.fakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import java.io.PrintWriter
-import java.io.StringWriter
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.test.runCurrent
@@ -79,21 +83,17 @@
 /** Tests for [OngoingActivityChipsViewModel] when the [StatusBarNotifChips] flag is enabled. */
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 @EnableFlags(StatusBarNotifChips.FLAG_NAME)
 class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() {
     private val kosmos = testKosmos().useUnconfinedTestDispatcher()
     private val testScope = kosmos.testScope
     private val systemClock = kosmos.fakeSystemClock
-    private val commandRegistry = kosmos.commandRegistry
 
     private val screenRecordState = kosmos.screenRecordRepository.screenRecordState
     private val mediaProjectionState = kosmos.fakeMediaProjectionRepository.mediaProjectionState
     private val callRepo = kosmos.ongoingCallRepository
     private val activeNotificationListRepository = kosmos.activeNotificationListRepository
 
-    private val pw = PrintWriter(StringWriter())
-
     private val mockSystemUIDialog = mock<SystemUIDialog>()
     private val chipBackgroundView = mock<ChipBackgroundContainer>()
     private val chipView =
@@ -202,6 +202,152 @@
         }
 
     @Test
+    fun chips_oneChip_notSquished() =
+        testScope.runTest {
+            callRepo.setOngoingCallState(inCallModel(startTimeMs = 34, notificationKey = "call"))
+
+            val latest by collectLastValue(underTest.chips)
+
+            // The call chip isn't squished (squished chips would be icon only)
+            assertThat(latest!!.primary)
+                .isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
+        }
+
+    @Test
+    @DisableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+    fun chips_twoTimerChips_isSmallPortrait_andChipsModernizationDisabled_bothSquished() =
+        testScope.runTest {
+            screenRecordState.value = ScreenRecordModel.Recording
+            callRepo.setOngoingCallState(inCallModel(startTimeMs = 34, notificationKey = "call"))
+
+            val latest by collectLastValue(underTest.chips)
+
+            // Squished chips are icon only
+            assertThat(latest!!.primary)
+                .isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+            assertThat(latest!!.secondary)
+                .isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+        }
+
+    @Test
+    @DisableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+    fun chips_countdownChipAndTimerChip_countdownNotSquished_butTimerSquished() =
+        testScope.runTest {
+            screenRecordState.value = ScreenRecordModel.Starting(millisUntilStarted = 2000)
+            callRepo.setOngoingCallState(inCallModel(startTimeMs = 34, notificationKey = "call"))
+
+            val latest by collectLastValue(underTest.chips)
+
+            // The screen record countdown isn't squished to icon-only
+            assertThat(latest!!.primary)
+                .isInstanceOf(OngoingActivityChipModel.Shown.Countdown::class.java)
+            // But the call chip *is* squished
+            assertThat(latest!!.secondary)
+                .isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+        }
+
+    @Test
+    @DisableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+    fun chips_numberOfChipsChanges_chipsGetSquishedAndUnsquished() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chips)
+
+            // WHEN there's only one chip
+            screenRecordState.value = ScreenRecordModel.Recording
+            callRepo.setOngoingCallState(OngoingCallModel.NoCall)
+
+            // The screen record isn't squished because it's the only one
+            assertThat(latest!!.primary)
+                .isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
+            assertThat(latest!!.secondary).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
+
+            // WHEN there's 2 chips
+            callRepo.setOngoingCallState(inCallModel(startTimeMs = 34, notificationKey = "call"))
+
+            // THEN they both become squished
+            assertThat(latest!!.primary)
+                .isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+            // But the call chip *is* squished
+            assertThat(latest!!.secondary)
+                .isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+
+            // WHEN we go back down to 1 chip
+            screenRecordState.value = ScreenRecordModel.DoingNothing
+
+            // THEN the remaining chip unsquishes
+            assertThat(latest!!.primary)
+                .isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
+            assertThat(latest!!.secondary).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
+        }
+
+    @Test
+    @DisableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+    fun chips_twoChips_isLandscape_notSquished() =
+        testScope.runTest {
+            screenRecordState.value = ScreenRecordModel.Recording
+            callRepo.setOngoingCallState(inCallModel(startTimeMs = 34, notificationKey = "call"))
+
+            // WHEN we're in landscape
+            val config =
+                Configuration(kosmos.mainResources.configuration).apply {
+                    orientation = Configuration.ORIENTATION_LANDSCAPE
+                }
+            kosmos.fakeConfigurationRepository.onConfigurationChange(config)
+
+            val latest by collectLastValue(underTest.chips)
+
+            // THEN the chips aren't squished (squished chips would be icon only)
+            assertThat(latest!!.primary)
+                .isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
+            assertThat(latest!!.secondary)
+                .isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
+        }
+
+    @Test
+    @DisableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+    fun chips_twoChips_isLargeScreen_notSquished() =
+        testScope.runTest {
+            screenRecordState.value = ScreenRecordModel.Recording
+            callRepo.setOngoingCallState(inCallModel(startTimeMs = 34, notificationKey = "call"))
+
+            // WHEN we're on a large screen
+            kosmos.displayStateRepository.setIsLargeScreen(true)
+
+            val latest by collectLastValue(underTest.chips)
+
+            // THEN the chips aren't squished (squished chips would be icon only)
+            assertThat(latest!!.primary)
+                .isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
+            assertThat(latest!!.secondary)
+                .isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
+        }
+
+    @Test
+    @EnableFlags(StatusBarChipsModernization.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
+    fun chips_twoChips_chipsModernizationEnabled_notSquished() =
+        testScope.runTest {
+            screenRecordState.value = ScreenRecordModel.Recording
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "call",
+                        statusBarChipIcon = createStatusBarIconViewOrNull(),
+                        callType = CallType.Ongoing,
+                        whenTime = 499,
+                    )
+                )
+            )
+
+            val latest by collectLastValue(underTest.chips)
+
+            // Squished chips would be icon only
+            assertThat(latest!!.primary)
+                .isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
+            assertThat(latest!!.secondary)
+                .isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
+        }
+
+    @Test
     fun primaryChip_screenRecordShowAndShareToAppShow_screenRecordShown() =
         testScope.runTest {
             screenRecordState.value = ScreenRecordModel.Recording
@@ -311,7 +457,7 @@
                 )
             )
 
-            assertIsNotifChip(latest!!.primary, icon, "notif")
+            assertIsNotifChip(latest!!.primary, context, icon, "notif")
             assertThat(latest!!.secondary).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
         }
 
@@ -339,8 +485,8 @@
                 )
             )
 
-            assertIsNotifChip(latest!!.primary, firstIcon, "firstNotif")
-            assertIsNotifChip(latest!!.secondary, secondIcon, "secondNotif")
+            assertIsNotifChip(latest!!.primary, context, firstIcon, "firstNotif")
+            assertIsNotifChip(latest!!.secondary, context, secondIcon, "secondNotif")
         }
 
     @Test
@@ -374,8 +520,8 @@
                 )
             )
 
-            assertIsNotifChip(latest!!.primary, firstIcon, "firstNotif")
-            assertIsNotifChip(latest!!.secondary, secondIcon, "secondNotif")
+            assertIsNotifChip(latest!!.primary, context, firstIcon, "firstNotif")
+            assertIsNotifChip(latest!!.secondary, context, secondIcon, "secondNotif")
         }
 
     @Test
@@ -407,7 +553,7 @@
             )
 
             assertIsCallChip(latest!!.primary, callNotificationKey)
-            assertIsNotifChip(latest!!.secondary, firstIcon, "firstNotif")
+            assertIsNotifChip(latest!!.secondary, context, firstIcon, "firstNotif")
         }
 
     @Test
@@ -456,7 +602,7 @@
 
             val latest by collectLastValue(underTest.primaryChip)
 
-            assertIsNotifChip(latest, notifIcon, "notif")
+            assertIsNotifChip(latest, context, notifIcon, "notif")
 
             // WHEN the higher priority call chip is added
             callRepo.setOngoingCallState(
@@ -527,7 +673,7 @@
             callRepo.setOngoingCallState(OngoingCallModel.NoCall)
 
             // THEN the lower priority notif is used
-            assertIsNotifChip(latest, notifIcon, "notif")
+            assertIsNotifChip(latest, context, notifIcon, "notif")
         }
 
     @Test
@@ -552,7 +698,7 @@
 
             val latest by collectLastValue(underTest.chips)
 
-            assertIsNotifChip(latest!!.primary, notifIcon, "notif")
+            assertIsNotifChip(latest!!.primary, context, notifIcon, "notif")
             assertThat(latest!!.secondary).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
 
             // WHEN the higher priority call chip is added
@@ -563,7 +709,7 @@
             // THEN the higher priority call chip is used as primary and notif is demoted to
             // secondary
             assertIsCallChip(latest!!.primary, callNotificationKey)
-            assertIsNotifChip(latest!!.secondary, notifIcon, "notif")
+            assertIsNotifChip(latest!!.secondary, context, notifIcon, "notif")
 
             // WHEN the higher priority media projection chip is added
             mediaProjectionState.value =
@@ -590,13 +736,13 @@
 
             // THEN media projection and notif remain
             assertIsShareToAppChip(latest!!.primary)
-            assertIsNotifChip(latest!!.secondary, notifIcon, "notif")
+            assertIsNotifChip(latest!!.secondary, context, notifIcon, "notif")
 
             // WHEN media projection is dropped
             mediaProjectionState.value = MediaProjectionState.NotProjecting
 
             // THEN notif is promoted to primary
-            assertIsNotifChip(latest!!.primary, notifIcon, "notif")
+            assertIsNotifChip(latest!!.primary, context, notifIcon, "notif")
             assertThat(latest!!.secondary).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
         }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarterTest.kt
index c06da4b..fee939d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarterTest.kt
@@ -18,6 +18,7 @@
 
 import android.platform.test.annotations.EnableFlags
 import android.view.Display
+import android.view.mockIWindowManager
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -28,16 +29,16 @@
 import com.android.systemui.testKosmos
 import com.google.common.truth.Expect
 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.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.never
 import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
@@ -51,75 +52,110 @@
     private val fakeInitializerStore = kosmos.fakeStatusBarInitializerStore
     private val fakePrivacyDotStore = kosmos.fakePrivacyDotWindowControllerStore
     private val fakeLightBarStore = kosmos.fakeLightBarControllerStore
+    private val windowManager = kosmos.mockIWindowManager
+
     // Lazy, so that @EnableFlags is set before initializer is instantiated.
     private val underTest by lazy { kosmos.multiDisplayStatusBarStarter }
 
+    @Before
+    fun setup() {
+        whenever(windowManager.shouldShowSystemDecors(Display.DEFAULT_DISPLAY)).thenReturn(true)
+        whenever(windowManager.shouldShowSystemDecors(DISPLAY_1)).thenReturn(true)
+        whenever(windowManager.shouldShowSystemDecors(DISPLAY_2)).thenReturn(true)
+        whenever(windowManager.shouldShowSystemDecors(DISPLAY_3)).thenReturn(true)
+        whenever(windowManager.shouldShowSystemDecors(DISPLAY_4_NO_SYSTEM_DECOR)).thenReturn(false)
+    }
+
     @Test
     fun start_startsInitializersForCurrentDisplays() =
         testScope.runTest {
-            fakeDisplayRepository.addDisplay(displayId = 1)
-            fakeDisplayRepository.addDisplay(displayId = 2)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_1)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_2)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
 
             underTest.start()
             runCurrent()
 
             expect
-                .that(fakeInitializerStore.forDisplay(displayId = 1).startedByCoreStartable)
+                .that(fakeInitializerStore.forDisplay(displayId = DISPLAY_1).startedByCoreStartable)
                 .isTrue()
             expect
-                .that(fakeInitializerStore.forDisplay(displayId = 2).startedByCoreStartable)
+                .that(fakeInitializerStore.forDisplay(displayId = DISPLAY_2).startedByCoreStartable)
                 .isTrue()
+            expect
+                .that(
+                    fakeInitializerStore
+                        .forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
+                        .startedByCoreStartable
+                )
+                .isFalse()
         }
 
     @Test
     fun start_startsOrchestratorForCurrentDisplays() =
         testScope.runTest {
-            fakeDisplayRepository.addDisplay(displayId = 1)
-            fakeDisplayRepository.addDisplay(displayId = 2)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_1)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_2)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
 
             underTest.start()
             runCurrent()
 
-            verify(fakeOrchestratorFactory.createdOrchestratorForDisplay(displayId = 1)!!).start()
-            verify(fakeOrchestratorFactory.createdOrchestratorForDisplay(displayId = 2)!!).start()
+            verify(fakeOrchestratorFactory.createdOrchestratorForDisplay(displayId = DISPLAY_1)!!)
+                .start()
+            verify(fakeOrchestratorFactory.createdOrchestratorForDisplay(displayId = DISPLAY_2)!!)
+                .start()
+            assertThat(
+                    fakeOrchestratorFactory.createdOrchestratorForDisplay(
+                        displayId = DISPLAY_4_NO_SYSTEM_DECOR
+                    )
+                )
+                .isNull()
         }
 
     @Test
     fun start_startsPrivacyDotForCurrentDisplays() =
         testScope.runTest {
-            fakeDisplayRepository.addDisplay(displayId = 1)
-            fakeDisplayRepository.addDisplay(displayId = 2)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_1)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_2)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
 
             underTest.start()
             runCurrent()
 
-            verify(fakePrivacyDotStore.forDisplay(displayId = 1)).start()
-            verify(fakePrivacyDotStore.forDisplay(displayId = 2)).start()
+            verify(fakePrivacyDotStore.forDisplay(displayId = DISPLAY_1)).start()
+            verify(fakePrivacyDotStore.forDisplay(displayId = DISPLAY_2)).start()
+            verify(fakePrivacyDotStore.forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR), never())
+                .start()
         }
 
     @Test
     fun start_doesNotStartLightBarControllerForCurrentDisplays() =
         testScope.runTest {
-            fakeDisplayRepository.addDisplay(displayId = 1)
-            fakeDisplayRepository.addDisplay(displayId = 2)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_1)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_2)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
 
             underTest.start()
             runCurrent()
 
-            verify(fakeLightBarStore.forDisplay(displayId = 1), never()).start()
-            verify(fakeLightBarStore.forDisplay(displayId = 2), never()).start()
+            verify(fakeLightBarStore.forDisplay(displayId = DISPLAY_1), never()).start()
+            verify(fakeLightBarStore.forDisplay(displayId = DISPLAY_2), never()).start()
+            verify(fakeLightBarStore.forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR), never())
+                .start()
         }
 
     @Test
     fun start_createsLightBarControllerForCurrentDisplays() =
         testScope.runTest {
-            fakeDisplayRepository.addDisplay(displayId = 1)
-            fakeDisplayRepository.addDisplay(displayId = 2)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_1)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_2)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
 
             underTest.start()
             runCurrent()
 
-            assertThat(fakeLightBarStore.perDisplayMocks.keys).containsExactly(1, 2)
+            assertThat(fakeLightBarStore.perDisplayMocks.keys).containsExactly(1, DISPLAY_2)
         }
 
     @Test
@@ -135,121 +171,174 @@
         }
 
     @Test
-    fun displayAdded_orchestratorForNewDisplayIsStarted() =
+    fun displayAdded_orchestratorForNewDisplay() =
         testScope.runTest {
             underTest.start()
             runCurrent()
 
-            fakeDisplayRepository.addDisplay(displayId = 3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
             runCurrent()
 
-            verify(fakeOrchestratorFactory.createdOrchestratorForDisplay(displayId = 3)!!).start()
+            verify(fakeOrchestratorFactory.createdOrchestratorForDisplay(displayId = DISPLAY_3)!!)
+                .start()
+            assertThat(
+                    fakeOrchestratorFactory.createdOrchestratorForDisplay(
+                        displayId = DISPLAY_4_NO_SYSTEM_DECOR
+                    )
+                )
+                .isNull()
         }
 
     @Test
-    fun displayAdded_initializerForNewDisplayIsStarted() =
+    fun displayAdded_initializerForNewDisplay() =
         testScope.runTest {
             underTest.start()
             runCurrent()
 
-            fakeDisplayRepository.addDisplay(displayId = 3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
             runCurrent()
 
             expect
-                .that(fakeInitializerStore.forDisplay(displayId = 3).startedByCoreStartable)
+                .that(fakeInitializerStore.forDisplay(displayId = DISPLAY_3).startedByCoreStartable)
                 .isTrue()
+            expect
+                .that(
+                    fakeInitializerStore
+                        .forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
+                        .startedByCoreStartable
+                )
+                .isFalse()
         }
 
     @Test
-    fun displayAdded_privacyDotForNewDisplayIsStarted() =
+    fun displayAdded_privacyDotForNewDisplay() =
         testScope.runTest {
             underTest.start()
             runCurrent()
 
-            fakeDisplayRepository.addDisplay(displayId = 3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
             runCurrent()
 
-            verify(fakePrivacyDotStore.forDisplay(displayId = 3)).start()
+            verify(fakePrivacyDotStore.forDisplay(displayId = DISPLAY_3)).start()
+            verify(fakePrivacyDotStore.forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR), never())
+                .start()
         }
 
     @Test
-    fun displayAdded_lightBarForNewDisplayIsCreated() =
+    fun displayAdded_lightBarForNewDisplayCreate() =
         testScope.runTest {
             underTest.start()
             runCurrent()
 
-            fakeDisplayRepository.addDisplay(displayId = 3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
             runCurrent()
 
-            assertThat(fakeLightBarStore.perDisplayMocks.keys).containsExactly(3)
+            assertThat(fakeLightBarStore.perDisplayMocks.keys).containsExactly(DISPLAY_3)
         }
 
     @Test
-    fun displayAdded_lightBarForNewDisplayIsNotStarted() =
+    fun displayAdded_lightBarForNewDisplayStart() =
         testScope.runTest {
             underTest.start()
             runCurrent()
 
-            fakeDisplayRepository.addDisplay(displayId = 3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
             runCurrent()
 
-            verify(fakeLightBarStore.forDisplay(displayId = 3), never()).start()
+            verify(fakeLightBarStore.forDisplay(displayId = DISPLAY_3), never()).start()
+            verify(fakeLightBarStore.forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR), never())
+                .start()
         }
 
     @Test
-    fun displayAddedDuringStart_initializerForNewDisplayIsStarted() =
+    fun displayAddedDuringStart_initializerForNewDisplay() =
         testScope.runTest {
             underTest.start()
 
-            fakeDisplayRepository.addDisplay(displayId = 3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
             runCurrent()
 
             expect
-                .that(fakeInitializerStore.forDisplay(displayId = 3).startedByCoreStartable)
+                .that(fakeInitializerStore.forDisplay(displayId = DISPLAY_3).startedByCoreStartable)
                 .isTrue()
+            expect
+                .that(
+                    fakeInitializerStore
+                        .forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
+                        .startedByCoreStartable
+                )
+                .isFalse()
         }
 
     @Test
-    fun displayAddedDuringStart_orchestratorForNewDisplayIsStarted() =
+    fun displayAddedDuringStart_orchestratorForNewDisplay() =
         testScope.runTest {
             underTest.start()
 
-            fakeDisplayRepository.addDisplay(displayId = 3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
             runCurrent()
 
-            verify(fakeOrchestratorFactory.createdOrchestratorForDisplay(displayId = 3)!!).start()
+            verify(fakeOrchestratorFactory.createdOrchestratorForDisplay(displayId = DISPLAY_3)!!)
+                .start()
+            assertThat(
+                    fakeOrchestratorFactory.createdOrchestratorForDisplay(
+                        displayId = DISPLAY_4_NO_SYSTEM_DECOR
+                    )
+                )
+                .isNull()
         }
 
     @Test
-    fun displayAddedDuringStart_privacyDotForNewDisplayIsStarted() =
+    fun displayAddedDuringStart_privacyDotForNewDisplay() =
         testScope.runTest {
             underTest.start()
 
-            fakeDisplayRepository.addDisplay(displayId = 3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
             runCurrent()
 
-            verify(fakePrivacyDotStore.forDisplay(displayId = 3)).start()
+            verify(fakePrivacyDotStore.forDisplay(displayId = DISPLAY_3)).start()
+            verify(fakePrivacyDotStore.forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR), never())
+                .start()
         }
 
     @Test
-    fun displayAddedDuringStart_lightBarForNewDisplayIsCreated() =
+    fun displayAddedDuringStart_lightBarForNewDisplayCreate() =
         testScope.runTest {
             underTest.start()
 
-            fakeDisplayRepository.addDisplay(displayId = 3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
             runCurrent()
 
-            assertThat(fakeLightBarStore.perDisplayMocks.keys).containsExactly(3)
+            assertThat(fakeLightBarStore.perDisplayMocks.keys).containsExactly(DISPLAY_3)
         }
 
     @Test
-    fun displayAddedDuringStart_lightBarForNewDisplayIsNotStarted() =
+    fun displayAddedDuringStart_lightBarForNewDisplayStart() =
         testScope.runTest {
             underTest.start()
 
-            fakeDisplayRepository.addDisplay(displayId = 3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_3)
+            fakeDisplayRepository.addDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR)
             runCurrent()
 
-            verify(fakeLightBarStore.forDisplay(displayId = 3), never()).start()
+            verify(fakeLightBarStore.forDisplay(displayId = DISPLAY_3), never()).start()
+            verify(fakeLightBarStore.forDisplay(displayId = DISPLAY_4_NO_SYSTEM_DECOR), never())
+                .start()
         }
+
+    companion object {
+        const val DISPLAY_1 = 1
+        const val DISPLAY_2 = 2
+        const val DISPLAY_3 = 3
+        const val DISPLAY_4_NO_SYSTEM_DECOR = 4
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/RemoteInputRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/RemoteInputRepositoryImplTest.kt
index 3b720ef..e48c17c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/RemoteInputRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/RemoteInputRepositoryImplTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.data.repository
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -25,7 +23,6 @@
 import com.android.systemui.statusbar.NotificationRemoteInputManager
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
index cd07821..45fbbac 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
@@ -40,7 +40,6 @@
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
@@ -50,7 +49,6 @@
 import org.mockito.Mockito.verify
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class DisableFlagsRepositoryTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/domain/interactor/RemoteInputInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/domain/interactor/RemoteInputInteractorTest.kt
index 60da53c..e44eaaf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/domain/interactor/RemoteInputInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/domain/interactor/RemoteInputInteractorTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.domain.interactor
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -26,7 +24,6 @@
 import com.android.systemui.statusbar.data.repository.fakeRemoteInputRepository
 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
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt
index 742494b..01e8dfe 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/SystemEventCoordinatorTest.kt
@@ -25,7 +25,6 @@
 import com.android.systemui.statusbar.policy.BatteryController
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.time.FakeSystemClock
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.test.TestScope
@@ -43,7 +42,6 @@
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 class SystemEventCoordinatorTest : SysuiTestCase() {
 
     private val fakeSystemClock = FakeSystemClock()
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 c3547bc..0f1cdac 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
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification
 
 import android.testing.TestableLooper.RunWithLooper
@@ -41,7 +39,6 @@
 import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModel
 import com.android.systemui.testKosmos
 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.runCurrent
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
index 3abd620..c987b61 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
@@ -47,7 +47,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -65,7 +64,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(ParameterizedAndroidJunit4::class)
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/LockScreenMinimalismCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/LockScreenMinimalismCoordinatorTest.kt
index 14148cd..a905394 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/LockScreenMinimalismCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/LockScreenMinimalismCoordinatorTest.kt
@@ -13,8 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification.collection.coordinator
 
 import android.app.Notification
@@ -52,7 +50,6 @@
 import com.google.common.truth.Truth.assertThat
 import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestCoroutineScheduler
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinatorTest.kt
index 5f154ac..7781df1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinatorTest.kt
@@ -13,8 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification.collection.coordinator
 
 import android.app.Notification
@@ -56,7 +54,6 @@
 import com.google.common.truth.Truth.assertThat
 import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestCoroutineScheduler
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
index 8f21ddff..ad4925c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification.collection.coordinator
 
 import android.app.Notification
@@ -74,7 +72,6 @@
 import com.android.systemui.statusbar.policy.sensitiveNotificationProtectionController
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.withArgCaptor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractorTest.kt
index 83c6150..d3befa9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractorTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification.domain.interactor
 
 import android.platform.test.annotations.DisableFlags
@@ -35,7 +33,6 @@
 import com.android.systemui.statusbar.notification.shared.CallType
 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
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 fae7d51..a7ae35d 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
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification.domain.interactor
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -38,7 +36,6 @@
 import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
 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
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 0195e9d..7f0f199 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
@@ -31,7 +31,6 @@
 import com.android.systemui.testKosmos
 import com.google.common.truth.Expect
 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
@@ -39,7 +38,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class NotificationsSoundPolicyInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt
index 5d9aa71..35b19c1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt
@@ -47,7 +47,7 @@
     private val notifsRepository = kosmos.activeNotificationListRepository
     private val notifsInteractor = kosmos.activeNotificationsInteractor
     private val underTest =
-        RenderNotificationListInteractor(notifsRepository, sectionStyleProvider = mock())
+        RenderNotificationListInteractor(notifsRepository, sectionStyleProvider = mock(), context)
 
     @Test
     fun setRenderedList_preservesOrdering() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/emptyshade/ui/viewmodel/EmptyShadeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/emptyshade/ui/viewmodel/EmptyShadeViewModelTest.kt
index 163ae47..5ba972de 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/emptyshade/ui/viewmodel/EmptyShadeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/emptyshade/ui/viewmodel/EmptyShadeViewModelTest.kt
@@ -40,7 +40,6 @@
 import com.android.systemui.testKosmos
 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.After
@@ -50,7 +49,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(ParameterizedAndroidJunit4::class)
 @SmallTest
 class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt
index b3a60b0..cb2de88 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification.footer.ui.viewmodel
 
 import android.platform.test.annotations.DisableFlags
@@ -45,7 +43,6 @@
 import com.android.systemui.util.ui.isAnimating
 import com.android.systemui.util.ui.value
 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
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt
index 9dfc922..339f8fa 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt
@@ -46,6 +46,7 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
 import com.android.systemui.statusbar.notification.collection.provider.visualStabilityProvider
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper
 import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
@@ -678,25 +679,32 @@
     }
 
     @Test
+    @DisableFlags(StatusBarNotifChips.FLAG_NAME, PromotedNotificationUi.FLAG_NAME)
+    fun testIsSticky_promotedAndExpanded_notifChipsFlagOff_promotedUiFlagOff_true() {
+        assertThat(getIsSticky_promotedAndExpanded()).isTrue()
+    }
+
+    @Test
+    @EnableFlags(StatusBarNotifChips.FLAG_NAME, PromotedNotificationUi.FLAG_NAME)
+    fun testIsSticky_promotedAndExpanded_notifChipsFlagOn_promotedUiFlagOn_false() {
+        assertThat(getIsSticky_promotedAndExpanded()).isFalse()
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
     @DisableFlags(StatusBarNotifChips.FLAG_NAME)
-    fun testIsSticky_promotedAndExpanded_notifChipsFlagOff_true() {
-        val notif = Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
-        notif.flags = FLAG_PROMOTED_ONGOING
-        val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, notif)
-        val row = testHelper.createRow().apply { setPinnedStatus(PinnedStatus.PinnedBySystem) }
-        notifEntry.row = row
-
-        underTest.showNotification(notifEntry)
-
-        val headsUpEntry = underTest.getHeadsUpEntry(notifEntry.key)
-        headsUpEntry!!.setExpanded(true)
-
-        assertThat(underTest.isSticky(notifEntry.key)).isTrue()
+    fun testIsSticky_promotedAndExpanded_promotedUiFlagOn_false() {
+        assertThat(getIsSticky_promotedAndExpanded()).isFalse()
     }
 
     @Test
     @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+    @DisableFlags(PromotedNotificationUi.FLAG_NAME)
     fun testIsSticky_promotedAndExpanded_notifChipsFlagOn_false() {
+        assertThat(getIsSticky_promotedAndExpanded()).isFalse()
+    }
+
+    private fun getIsSticky_promotedAndExpanded(): Boolean {
         val notif = Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
         notif.flags = FLAG_PROMOTED_ONGOING
         val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, notif)
@@ -708,7 +716,7 @@
         val headsUpEntry = underTest.getHeadsUpEntry(notifEntry.key)
         headsUpEntry!!.setExpanded(true)
 
-        assertThat(underTest.isSticky(notifEntry.key)).isFalse()
+        return underTest.isSticky(notifEntry.key)
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt
index f07303e..ee4d099 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt
@@ -15,6 +15,7 @@
 
 package com.android.systemui.statusbar.notification.icon.domain.interactor
 
+import android.platform.test.annotations.DisableFlags
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -24,6 +25,7 @@
 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.headsup.shared.StatusBarNoHunBehavior
 import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
 import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
 import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
@@ -44,7 +46,6 @@
 import com.android.wm.shell.bubbles.bubbles
 import com.android.wm.shell.bubbles.bubblesOptional
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -63,7 +64,7 @@
             kosmos.activeNotificationsInteractor,
             kosmos.bubblesOptional,
             kosmos.headsUpNotificationIconInteractor,
-            kosmos.notificationsKeyguardViewStateRepository
+            kosmos.notificationsKeyguardViewStateRepository,
         )
 
     @Before
@@ -142,7 +143,6 @@
         }
 }
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AlwaysOnDisplayNotificationIconsInteractorTest : SysuiTestCase() {
@@ -308,6 +308,7 @@
         }
 
     @Test
+    @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME)
     fun filteredEntrySet_includesIsolatedIcon() =
         testScope.runTest {
             val filteredSet by collectLastValue(underTest.statusBarNotifs)
@@ -318,31 +319,11 @@
 
 private val testIcons =
     listOf(
-        activeNotificationModel(
-            key = "notif1",
-        ),
-        activeNotificationModel(
-            key = "notif2",
-            isAmbient = true,
-        ),
-        activeNotificationModel(
-            key = "notif3",
-            isRowDismissed = true,
-        ),
-        activeNotificationModel(
-            key = "notif4",
-            isSilent = true,
-        ),
-        activeNotificationModel(
-            key = "notif5",
-            isLastMessageFromReply = true,
-        ),
-        activeNotificationModel(
-            key = "notif6",
-            isSuppressedFromStatusBar = true,
-        ),
-        activeNotificationModel(
-            key = "notif7",
-            isPulsing = true,
-        ),
+        activeNotificationModel(key = "notif1"),
+        activeNotificationModel(key = "notif2", isAmbient = true),
+        activeNotificationModel(key = "notif3", isRowDismissed = true),
+        activeNotificationModel(key = "notif4", isSilent = true),
+        activeNotificationModel(key = "notif5", isLastMessageFromReply = true),
+        activeNotificationModel(key = "notif6", isSuppressedFromStatusBar = true),
+        activeNotificationModel(key = "notif7", isPulsing = true),
     )
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
index 76390fd..fb734ac 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
@@ -46,7 +46,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.whenever
 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
@@ -55,7 +54,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 class NotificationIconContainerAlwaysOnDisplayViewModelTest(flags: FlagsParameterization) :
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
index abb1edf..8054bd1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
@@ -237,9 +237,9 @@
 
         assertThat(content).isNotNull()
         assertThat(content?.style).isEqualTo(Style.Progress)
-        assertThat(content?.progress).isNotNull()
-        assertThat(content?.progress?.progress).isEqualTo(75)
-        assertThat(content?.progress?.progressMax).isEqualTo(100)
+        assertThat(content?.newProgress).isNotNull()
+        assertThat(content?.newProgress?.progress).isEqualTo(75)
+        assertThat(content?.newProgress?.progressMax).isEqualTo(100)
     }
 
     @Test
@@ -255,6 +255,43 @@
         assertThat(content?.style).isEqualTo(Style.Ineligible)
     }
 
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun extractsContent_fromOldProgressDeterminate() {
+        val entry = createEntry {
+            setProgress(TEST_PROGRESS_MAX, TEST_PROGRESS, /* indeterminate= */ false)
+        }
+
+        val content = extractContent(entry)
+
+        assertThat(content).isNotNull()
+
+        val oldProgress = content?.oldProgress
+        assertThat(oldProgress).isNotNull()
+
+        assertThat(content).isNotNull()
+        assertThat(content?.oldProgress).isNotNull()
+        assertThat(content?.oldProgress?.progress).isEqualTo(TEST_PROGRESS)
+        assertThat(content?.oldProgress?.max).isEqualTo(TEST_PROGRESS_MAX)
+        assertThat(content?.oldProgress?.isIndeterminate).isFalse()
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun extractsContent_fromOldProgressIndeterminate() {
+        val entry = createEntry {
+            setProgress(TEST_PROGRESS_MAX, TEST_PROGRESS, /* indeterminate= */ true)
+        }
+
+        val content = extractContent(entry)
+
+        assertThat(content).isNotNull()
+        assertThat(content?.oldProgress).isNotNull()
+        assertThat(content?.oldProgress?.progress).isEqualTo(TEST_PROGRESS)
+        assertThat(content?.oldProgress?.max).isEqualTo(TEST_PROGRESS_MAX)
+        assertThat(content?.oldProgress?.isIndeterminate).isTrue()
+    }
+
     private fun extractContent(entry: NotificationEntry): PromotedNotificationContentModel? {
         val recoveredBuilder = Notification.Builder(context, entry.sbn.notification)
         return underTest.extractContent(entry, recoveredBuilder)
@@ -277,6 +314,9 @@
         private const val TEST_CONTENT_TEXT = "content text"
         private const val TEST_SHORT_CRITICAL_TEXT = "short"
 
+        private const val TEST_PROGRESS = 50
+        private const val TEST_PROGRESS_MAX = 100
+
         private const val TEST_PERSON_NAME = "person name"
         private const val TEST_PERSON_KEY = "person key"
         private val TEST_PERSON =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
index da48833..99dcd6c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.mock
 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.advanceTimeBy
@@ -47,7 +46,6 @@
 private const val FREE_IMAGE_DELAY_MS = 4000L
 private const val MAX_IMAGE_SIZE = 512 // size of the test drawables in pixels
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWithLooper
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfoTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfoTest.java
deleted file mode 100644
index 66277e2..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfoTest.java
+++ /dev/null
@@ -1,308 +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.row;
-
-import static android.app.Notification.EXTRA_BUILDER_APPLICATION_INFO;
-import static android.app.NotificationManager.IMPORTANCE_LOW;
-import static android.print.PrintManager.PRINT_SPOOLER_PACKAGE_NAME;
-import static android.service.notification.NotificationAssistantService.ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNotNull;
-
-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.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.INotificationManager;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.UserHandle;
-import android.platform.test.annotations.EnableFlags;
-import android.service.notification.NotificationAssistantService;
-import android.service.notification.StatusBarNotification;
-import android.telecom.TelecomManager;
-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.internal.logging.MetricsLogger;
-import com.android.internal.logging.testing.UiEventLoggerFake;
-import com.android.systemui.Dependency;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.res.R;
-import com.android.systemui.statusbar.notification.AssistantFeedbackController;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
-
-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.List;
-import java.util.concurrent.CountDownLatch;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-@TestableLooper.RunWithLooper
-public class BundleNotificationInfoTest extends SysuiTestCase {
-    private static final String TEST_PACKAGE_NAME = "test_package";
-    private static final String TEST_SYSTEM_PACKAGE_NAME = PRINT_SPOOLER_PACKAGE_NAME;
-    private static final int TEST_UID = 1;
-    private static final String TEST_CHANNEL = "test_channel";
-    private static final String TEST_CHANNEL_NAME = "TEST CHANNEL NAME";
-
-    private TestableLooper mTestableLooper;
-    private BundleNotificationInfo mInfo;
-    private NotificationChannel mNotificationChannel;
-    private StatusBarNotification mSbn;
-    private NotificationEntry mEntry;
-    private UiEventLoggerFake mUiEventLogger = new UiEventLoggerFake();
-
-    @Rule
-    public MockitoRule mockito = MockitoJUnit.rule();
-    @Mock
-    private MetricsLogger mMetricsLogger;
-    @Mock
-    private INotificationManager mMockINotificationManager;
-    @Mock
-    private PackageManager mMockPackageManager;
-    @Mock
-    private OnUserInteractionCallback mOnUserInteractionCallback;
-    @Mock
-    private ChannelEditorDialogController mChannelEditorDialogController;
-    @Mock
-    private AssistantFeedbackController mAssistantFeedbackController;
-    @Mock
-    private TelecomManager mTelecomManager;
-
-    @Before
-    public void setUp() throws Exception {
-        mTestableLooper = TestableLooper.get(this);
-
-        mContext.addMockSystemService(TelecomManager.class, mTelecomManager);
-
-        mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
-        // Inflate the layout
-        final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
-        mInfo = (BundleNotificationInfo) layoutInflater.inflate(R.layout.bundle_notification_info,
-                null);
-        mInfo.setGutsParent(mock(NotificationGuts.class));
-        // Our view is never attached to a window so the View#post methods in
-        // BundleNotificationInfo never get called. Setting this will skip the post and do the
-        // action immediately.
-        mInfo.mSkipPost = true;
-
-        // PackageManager must return a packageInfo and applicationInfo.
-        final PackageInfo packageInfo = new PackageInfo();
-        packageInfo.packageName = TEST_PACKAGE_NAME;
-        when(mMockPackageManager.getPackageInfo(eq(TEST_PACKAGE_NAME), anyInt()))
-                .thenReturn(packageInfo);
-        final ApplicationInfo applicationInfo = new ApplicationInfo();
-        applicationInfo.uid = TEST_UID;  // non-zero
-        final PackageInfo systemPackageInfo = new PackageInfo();
-        systemPackageInfo.packageName = TEST_SYSTEM_PACKAGE_NAME;
-        when(mMockPackageManager.getPackageInfo(eq(TEST_SYSTEM_PACKAGE_NAME), anyInt()))
-                .thenReturn(systemPackageInfo);
-        when(mMockPackageManager.getPackageInfo(eq("android"), anyInt()))
-                .thenReturn(packageInfo);
-
-        // Package has one channel by default.
-        when(mMockINotificationManager.getNumNotificationChannelsForPackage(
-                eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(1);
-
-        // Some test channels.
-        mNotificationChannel = new NotificationChannel(
-                TEST_CHANNEL, TEST_CHANNEL_NAME, IMPORTANCE_LOW);
-        Notification notification = new Notification();
-        notification.extras.putParcelable(EXTRA_BUILDER_APPLICATION_INFO, applicationInfo);
-        mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
-                notification, UserHandle.getUserHandleForUid(TEST_UID), null, 0);
-        mEntry = new NotificationEntryBuilder().setSbn(mSbn).build();
-        when(mAssistantFeedbackController.isFeedbackEnabled()).thenReturn(false);
-        when(mAssistantFeedbackController.getInlineDescriptionResource(any()))
-                .thenReturn(R.string.notification_channel_summary_automatic);
-    }
-
-    @Test
-    @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
-    public void testBindNotification_setsOnClickListenerForFeedback() throws Exception {
-        // When Notification Assistant is available,
-        when(mMockINotificationManager.getAllowedNotificationAssistant()).thenReturn(
-                new ComponentName("assistantPkg", "assistantCls"));
-
-        // ...and Package manager has an intent that matches.
-        ArrayList<ResolveInfo> resolveInfos = new ArrayList<>();
-        ResolveInfo info = new ResolveInfo();
-        info.activityInfo = new ActivityInfo();
-        info.activityInfo.packageName = "assistantPkg";
-        info.activityInfo.name = "assistantCls";
-        resolveInfos.add(info);
-        when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(resolveInfos);
-
-        // And we attempt to bind the notification to the Info object
-        final CountDownLatch latch = new CountDownLatch(1);
-        mInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                (View v, Intent intent) -> {
-                    // Assert that the intent action and package match.
-                    assertEquals(intent.getAction(),
-                            ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS);
-                    assertEquals(intent.getPackage(), "assistantPkg");
-                    latch.countDown();
-                },
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
-        // and the feedback button is clicked,
-        final View feedbackButton = mInfo.findViewById(R.id.notification_guts_bundle_feedback);
-        feedbackButton.performClick();
-
-        // then of the intents queried for is the feedback intent,
-        ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
-        verify(mMockPackageManager, atLeastOnce()).queryIntentActivities(captor.capture(),
-                anyInt());
-        List<Intent> capturedIntents = captor.getAllValues();
-        Intent feedbackIntent = null;
-        for (int i = 0; i < capturedIntents.size(); i++) {
-            final Intent capturedIntent = capturedIntents.get(i);
-            if (capturedIntent.getAction() == ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS
-                    && capturedIntent.getPackage().equals("assistantPkg")) {
-                feedbackIntent = capturedIntent;
-            }
-        }
-        assertNotNull("feedbackIntent should be not null", feedbackIntent);
-        assertEquals(mSbn.getKey(),
-                feedbackIntent.getExtra(NotificationAssistantService.EXTRA_NOTIFICATION_KEY));
-
-        // and verify that listener was triggered.
-        assertEquals(0, latch.getCount());
-        assertEquals(View.VISIBLE, feedbackButton.getVisibility());
-    }
-
-    @Test
-    @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
-    public void testBindNotification_hidesFeedbackButtonWhenNoNAS() throws Exception {
-        // When the Notification Assistant is not available
-        when(mMockINotificationManager.getAllowedNotificationAssistant()).thenReturn(null);
-        final CountDownLatch latch = new CountDownLatch(1);
-
-        mInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                (View v, Intent intent) -> {
-                    // Assert that the intent action and package match.
-                    assertEquals(intent.getAction(),
-                            ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS);
-                    assertEquals(intent.getPackage(), "assistantPkg");
-                    latch.countDown();
-                },
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
-
-        final View feedbackButton = mInfo.findViewById(R.id.notification_guts_bundle_feedback);
-        feedbackButton.performClick();
-        // Listener was not triggered
-        assertEquals(1, latch.getCount());
-        assertEquals(View.GONE, feedbackButton.getVisibility());
-    }
-
-    @Test
-    @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
-    public void testBindNotification_hidesFeedbackButtonWhenNoIntent() throws Exception {
-        // When the Notification Assistant is available,
-        when(mMockINotificationManager.getAllowedNotificationAssistant()).thenReturn(
-                new ComponentName("assistantPkg", "assistantCls"));
-
-        // But the intent activity is null
-        when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(null);
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        mInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                (View v, Intent intent) -> {
-                    // Assert that the intent action and package match.
-                    assertEquals(intent.getAction(),
-                            ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS);
-                    assertEquals(intent.getPackage(), "assistantPkg");
-                    latch.countDown();
-                },
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
-
-        final View feedbackButton = mInfo.findViewById(R.id.notification_guts_bundle_feedback);
-        feedbackButton.performClick();
-        // Listener was not triggered
-        assertEquals(1, latch.getCount());
-        assertEquals(View.GONE, feedbackButton.getVisibility());
-    }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
index 28b2ee8d..d43cc78 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
@@ -13,8 +13,6 @@
  * 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
 
 import android.R
@@ -81,7 +79,6 @@
 import java.util.Optional
 import kotlin.test.assertNotNull
 import kotlin.test.fail
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Assert.assertEquals
@@ -522,6 +519,7 @@
                 eq(entry),
                 any<NotificationInfo.OnSettingsClickListener>(),
                 any<NotificationInfo.OnAppSettingsClickListener>(),
+                any<NotificationInfo.OnFeedbackClickListener>(),
                 any<UiEventLogger>(),
                 /* isDeviceProvisioned = */ eq(false),
                 /* isNonblockable = */ eq(false),
@@ -559,6 +557,7 @@
                 eq(entry),
                 any<NotificationInfo.OnSettingsClickListener>(),
                 any<NotificationInfo.OnAppSettingsClickListener>(),
+                any<NotificationInfo.OnFeedbackClickListener>(),
                 any<UiEventLogger>(),
                 /* isDeviceProvisioned = */ eq(true),
                 /* isNonblockable = */ eq(false),
@@ -594,44 +593,7 @@
                 eq(entry),
                 any<NotificationInfo.OnSettingsClickListener>(),
                 any<NotificationInfo.OnAppSettingsClickListener>(),
-                any<UiEventLogger>(),
-                /* isDeviceProvisioned = */ eq(false),
-                /* isNonblockable = */ eq(false),
-                /* wasShownHighPriority = */ eq(false),
-                eq(assistantFeedbackController),
-                eq(metricsLogger),
-                any<View.OnClickListener>(),
-            )
-    }
-
-    @Test
-    @Throws(Exception::class)
-    fun testInitializeBundleNotificationInfoView() {
-        val infoView: BundleNotificationInfo = mock()
-        val row = spy(helper.createRow())
-        val entry = row.entry
-
-        // Modify the notification entry to have a channel that is in SYSTEM_RESERVED_IDS
-        val channel = NotificationChannel(NotificationChannel.NEWS_ID, "name", 2)
-        NotificationEntryHelper.modifyRanking(entry).setChannel(channel).build()
-
-        whenever(row.isNonblockable).thenReturn(false)
-        val statusBarNotification = entry.sbn
-        // Can we change this to a call to bindGuts instead? We have the row,
-        // we need a MenuItem that we can put the infoView into.
-        gutsManager.initializeBundleNotificationInfo(row, infoView)
-
-        verify(infoView)
-            .bindNotification(
-                any<PackageManager>(),
-                any<INotificationManager>(),
-                eq(onUserInteractionCallback),
-                eq(channelEditorDialogController),
-                eq(statusBarNotification.packageName),
-                any<NotificationChannel>(),
-                eq(entry),
-                any<NotificationInfo.OnSettingsClickListener>(),
-                any<NotificationInfo.OnAppSettingsClickListener>(),
+                any<NotificationInfo.OnFeedbackClickListener>(),
                 any<UiEventLogger>(),
                 /* isDeviceProvisioned = */ eq(false),
                 /* isNonblockable = */ eq(false),
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index fdba7ba..a64339e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.notification.row;
 
 import static android.app.Notification.EXTRA_BUILDER_APPLICATION_INFO;
+import static android.app.NotificationChannel.SOCIAL_MEDIA_ID;
 import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
@@ -41,18 +42,26 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.Flags;
 import android.app.INotificationManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
 import android.app.PendingIntent;
 import android.app.Person;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.graphics.drawable.Drawable;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.service.notification.StatusBarNotification;
 import android.telecom.TelecomManager;
 import android.testing.TestableLooper;
@@ -69,6 +78,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.res.R;
+import com.android.systemui.statusbar.RankingBuilder;
 import com.android.systemui.statusbar.notification.AssistantFeedbackController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
@@ -82,6 +92,8 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
+import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.CountDownLatch;
 
 @SmallTest
@@ -98,6 +110,7 @@
     private NotificationInfo mNotificationInfo;
     private NotificationChannel mNotificationChannel;
     private NotificationChannel mDefaultNotificationChannel;
+    private NotificationChannel mClassifiedNotificationChannel;
     private StatusBarNotification mSbn;
     private NotificationEntry mEntry;
     private UiEventLoggerFake mUiEventLogger = new UiEventLoggerFake();
@@ -119,6 +132,9 @@
     @Mock
     private TelecomManager mTelecomManager;
 
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     @Before
     public void setUp() throws Exception {
         mTestableLooper = TestableLooper.get(this);
@@ -149,6 +165,14 @@
         when(mMockPackageManager.getPackageInfo(eq("android"), anyInt()))
                 .thenReturn(packageInfo);
 
+        ComponentName assistant = new ComponentName("package", "service");
+        when(mMockINotificationManager.getAllowedNotificationAssistant()).thenReturn(assistant);
+        ResolveInfo ri = new ResolveInfo();
+        ri.activityInfo = new ActivityInfo();
+        ri.activityInfo.packageName = assistant.getPackageName();
+        ri.activityInfo.name = "activity";
+        when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(List.of(ri));
+
         // Package has one channel by default.
         when(mMockINotificationManager.getNumNotificationChannelsForPackage(
                 eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(1);
@@ -159,6 +183,9 @@
         mDefaultNotificationChannel = new NotificationChannel(
                 NotificationChannel.DEFAULT_CHANNEL_ID, TEST_CHANNEL_NAME,
                 IMPORTANCE_LOW);
+        mClassifiedNotificationChannel =
+                new NotificationChannel(SOCIAL_MEDIA_ID, "social", IMPORTANCE_LOW);
+
         Notification notification = new Notification();
         notification.extras.putParcelable(EXTRA_BUILDER_APPLICATION_INFO, applicationInfo);
         mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
@@ -168,10 +195,8 @@
         when(mAssistantFeedbackController.getInlineDescriptionResource(any()))
                 .thenReturn(R.string.notification_channel_summary_automatic);
     }
-
-    @Test
-    public void testBindNotification_SetsTextApplicationName() throws Exception {
-        when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
+    
+    private void doStandardBind() throws Exception {
         mNotificationInfo.bindNotification(
                 mMockPackageManager,
                 mMockINotificationManager,
@@ -182,12 +207,19 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
                 true,
                 mAssistantFeedbackController,
                 mMetricsLogger, null);
+    }
+
+    @Test
+    public void testBindNotification_SetsTextApplicationName() throws Exception {
+        when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
+        doStandardBind();
         final TextView textView = mNotificationInfo.findViewById(R.id.pkg_name);
         assertTrue(textView.getText().toString().contains("App Name"));
         assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
@@ -198,44 +230,14 @@
         final Drawable iconDrawable = mock(Drawable.class);
         when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
                 .thenReturn(iconDrawable);
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger, null);
+        doStandardBind();
         final ImageView iconView = mNotificationInfo.findViewById(R.id.pkg_icon);
         assertEquals(iconDrawable, iconView.getDrawable());
     }
 
     @Test
     public void testBindNotification_noDelegate() throws Exception {
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger, null);
+        doStandardBind();
         final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
         assertEquals(GONE, nameView.getVisibility());
     }
@@ -261,6 +263,7 @@
                 entry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -274,22 +277,7 @@
 
     @Test
     public void testBindNotification_GroupNameHiddenIfNoGroup() throws Exception {
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger, null);
+        doStandardBind();
         final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
         assertEquals(GONE, groupNameView.getVisibility());
     }
@@ -302,22 +290,7 @@
         when(mMockINotificationManager.getNotificationChannelGroupForPackage(
                 eq("test_group_id"), eq(TEST_PACKAGE_NAME), eq(TEST_UID)))
                 .thenReturn(notificationChannelGroup);
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger, null);
+        doStandardBind();
         final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
         assertEquals(View.VISIBLE, groupNameView.getVisibility());
         assertEquals("Test Group Name", groupNameView.getText());
@@ -325,22 +298,7 @@
 
     @Test
     public void testBindNotification_SetsTextChannelName() throws Exception {
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger, null);
+        doStandardBind();
         final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
         assertEquals(TEST_CHANNEL_NAME, textView.getText());
     }
@@ -357,6 +315,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -383,6 +342,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -406,13 +366,13 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 true,
                 true,
                 mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+                mMetricsLogger, null);
         final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
         assertEquals(VISIBLE, textView.getVisibility());
     }
@@ -433,6 +393,7 @@
                     latch.countDown();
                 },
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -449,23 +410,7 @@
 
     @Test
     public void testBindNotification_SettingsButtonInvisibleWhenNoClickListener() throws Exception {
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
         assertTrue(settingsButton.getVisibility() != View.VISIBLE);
     }
@@ -485,6 +430,7 @@
                     assertEquals(mNotificationChannel, c);
                 },
                 null,
+                null,
                 mUiEventLogger,
                 false,
                 false,
@@ -498,23 +444,7 @@
 
     @Test
     public void testBindNotification_SettingsButtonReappearsAfterSecondBind() throws Exception {
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
         mNotificationInfo.bindNotification(
                 mMockPackageManager,
                 mMockINotificationManager,
@@ -525,6 +455,7 @@
                 mEntry,
                 (View v, NotificationChannel c, int appUid) -> { },
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -548,13 +479,13 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 true,
                 true,
                 mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+                mMetricsLogger, null);
         final TextView view = mNotificationInfo.findViewById(R.id.non_configurable_text);
         assertEquals(View.VISIBLE, view.getVisibility());
         assertEquals(mContext.getString(R.string.notification_unblockable_desc),
@@ -582,23 +513,7 @@
         mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
                 nb.build(), UserHandle.getUserHandleForUid(TEST_UID), null, 0);
         mEntry.setSbn(mSbn);
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
         final TextView view = mNotificationInfo.findViewById(R.id.non_configurable_call_text);
         assertEquals(View.VISIBLE, view.getVisibility());
         assertEquals(mContext.getString(R.string.notification_unblockable_call_desc),
@@ -613,9 +528,6 @@
     public void testBindNotification_whenCurrentlyInCall_notCall() throws Exception {
         when(mMockINotificationManager.isInCall(anyString(), anyInt())).thenReturn(true);
 
-        Person person = new Person.Builder()
-                .setName("caller")
-                .build();
         Notification.Builder nb = new Notification.Builder(
                 mContext, mNotificationChannel.getId())
                 .setContentTitle("foo")
@@ -626,23 +538,7 @@
         mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
                 nb.build(), UserHandle.getUserHandleForUid(TEST_UID), null, 0);
         mEntry.setSbn(mSbn);
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
         assertEquals(GONE,
                 mNotificationInfo.findViewById(R.id.non_configurable_call_text).getVisibility());
         assertEquals(VISIBLE,
@@ -654,46 +550,14 @@
     @Test
     public void testBindNotification_automaticIsVisible() throws Exception {
         when(mAssistantFeedbackController.isFeedbackEnabled()).thenReturn(true);
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
         assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.automatic).getVisibility());
         assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.automatic_summary).getVisibility());
     }
 
     @Test
     public void testBindNotification_automaticIsGone() throws Exception {
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
         assertEquals(GONE, mNotificationInfo.findViewById(R.id.automatic).getVisibility());
         assertEquals(GONE, mNotificationInfo.findViewById(R.id.automatic_summary).getVisibility());
     }
@@ -702,45 +566,13 @@
     public void testBindNotification_automaticIsSelected() throws Exception {
         when(mAssistantFeedbackController.isFeedbackEnabled()).thenReturn(true);
         mNotificationChannel.unlockFields(USER_LOCKED_IMPORTANCE);
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
         assertTrue(mNotificationInfo.findViewById(R.id.automatic).isSelected());
     }
 
     @Test
     public void testBindNotification_alertIsSelected() throws Exception {
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
         assertTrue(mNotificationInfo.findViewById(R.id.alert).isSelected());
     }
 
@@ -756,6 +588,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -768,23 +601,7 @@
 
     @Test
     public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception {
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
         mTestableLooper.processAllMessages();
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
                 anyString(), eq(TEST_UID), any());
@@ -792,23 +609,7 @@
 
     @Test
     public void testBindNotification_LogsOpen() throws Exception {
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
         assertEquals(1, mUiEventLogger.numLogs());
         assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_OPEN.getId(),
                 mUiEventLogger.eventId(0));
@@ -827,6 +628,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -845,23 +647,7 @@
     public void testDoesNotUpdateNotificationChannelAfterImportanceChangedSilenced()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
 
         mNotificationInfo.findViewById(R.id.silence).performClick();
         mTestableLooper.processAllMessages();
@@ -873,23 +659,7 @@
     public void testDoesNotUpdateNotificationChannelAfterImportanceChangedAutomatic()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
 
         mNotificationInfo.findViewById(R.id.automatic).performClick();
         mTestableLooper.processAllMessages();
@@ -902,23 +672,7 @@
             throws Exception {
         when(mAssistantFeedbackController.isFeedbackEnabled()).thenReturn(true);
         mNotificationChannel.unlockFields(USER_LOCKED_IMPORTANCE);
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
 
         mNotificationInfo.handleCloseControls(true, false);
         mTestableLooper.processAllMessages();
@@ -930,23 +684,7 @@
     public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged()
             throws Exception {
         int originalImportance = mNotificationChannel.getImportance();
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
 
         mNotificationInfo.handleCloseControls(true, false);
         mTestableLooper.processAllMessages();
@@ -966,23 +704,7 @@
     public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnspecified()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
 
         mNotificationInfo.handleCloseControls(true, false);
 
@@ -995,23 +717,7 @@
     @Test
     public void testSilenceCallsUpdateNotificationChannel() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
 
         mNotificationInfo.findViewById(R.id.silence).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -1047,6 +753,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -1075,23 +782,7 @@
         when(mAssistantFeedbackController.isFeedbackEnabled()).thenReturn(true);
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
         mNotificationChannel.lockFields(USER_LOCKED_IMPORTANCE);
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
 
         mNotificationInfo.findViewById(R.id.automatic).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -1108,23 +799,7 @@
     public void testSilenceCallsUpdateNotificationChannel_channelImportanceUnspecified()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
 
         mNotificationInfo.findViewById(R.id.silence).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -1155,6 +830,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -1194,6 +870,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -1226,6 +903,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -1255,23 +933,7 @@
     @Test
     public void testAdjustImportanceTemporarilyAllowsReordering() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                null,
-                null,
-                mUiEventLogger,
-                true,
-                false,
-                true,
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                null);
+        doStandardBind();
 
         mNotificationInfo.findViewById(R.id.silence).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -1295,6 +957,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -1327,6 +990,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -1363,6 +1027,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -1397,6 +1062,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -1431,6 +1097,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -1458,6 +1125,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
@@ -1468,4 +1136,54 @@
 
         assertFalse(mNotificationInfo.willBeRemoved());
     }
+
+
+    @Test
+    @DisableFlags(Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+    public void testBindNotification_HidesFeedbackLink_flagOff() throws Exception {
+        doStandardBind();
+        assertEquals(GONE, mNotificationInfo.findViewById(R.id.feedback).getVisibility());
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+    public void testBindNotification_SetsFeedbackLink_isReservedChannel() throws RemoteException {
+        mEntry.setRanking(new RankingBuilder(mEntry.getRanking())
+                .setSummarization("something").build());
+        final CountDownLatch latch = new CountDownLatch(1);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mOnUserInteractionCallback,
+                mChannelEditorDialogController,
+                TEST_PACKAGE_NAME,
+                mClassifiedNotificationChannel,
+                mEntry,
+                null,
+                null,
+                (View v, Intent intent) -> {
+                    latch.countDown();
+                },
+                mUiEventLogger,
+                true,
+                false,
+                false,
+                mAssistantFeedbackController,
+                mMetricsLogger,
+                null);
+
+        final View feedback = mNotificationInfo.findViewById(R.id.feedback);
+        assertEquals(VISIBLE, feedback.getVisibility());
+        feedback.performClick();
+        // Verify that listener was triggered.
+        assertEquals(0, latch.getCount());
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+    public void testBindNotification_hidesFeedbackLink_notReservedChannel() throws Exception {
+        doStandardBind();
+
+        assertEquals(GONE, mNotificationInfo.findViewById(R.id.feedback).getVisibility());
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfoTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfoTest.java
index b33f93d..acdbd62 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfoTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfoTest.java
@@ -138,6 +138,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mUiEventLogger,
                 true,
                 false,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt
index 0dc871a..961616c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification.row.ui.viewmodel
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -25,7 +23,6 @@
 import com.android.systemui.accessibility.domain.interactor.AccessibilityInteractor
 import com.android.systemui.coroutines.collectLastValue
 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
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt
index f88bd7e..c42b24d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/NotificationViewFlipperViewModelTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification.row.ui.viewmodel
 
 import android.platform.test.annotations.EnableFlags
@@ -31,7 +29,6 @@
 import com.android.systemui.statusbar.notification.shared.NotificationViewFlipperPausing
 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
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt
index 4c6e25a..8eea2a8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification.shelf.domain.interactor
 
 import android.os.PowerManager
@@ -34,7 +32,6 @@
 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.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt
index 578950f..4aaf6fc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt
@@ -24,7 +24,6 @@
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.TestScope
@@ -38,7 +37,6 @@
 import org.mockito.Mockito.verify
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class DisplaySwitchNotificationsHiderTrackerTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt
index 8163a68..d14ff35 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt
@@ -18,6 +18,7 @@
 
 import android.os.testableLooper
 import android.testing.TestableLooper.RunWithLooper
+import androidx.dynamicanimation.animation.SpringForce
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -46,13 +47,14 @@
     private val childrenNumber = 5
     private val stackScrollLayout = mock<NotificationStackScrollLayout>()
     private val sectionsManager = mock<NotificationSectionsManager>()
-    private val swipedMultiplier = 0.5f
     private val msdlPlayer = kosmos.fakeMSDLPlayer
+    private var canRowBeDismissed = true
 
     private val underTest = kosmos.magneticNotificationRowManagerImpl
 
     private lateinit var notificationTestHelper: NotificationTestHelper
     private lateinit var children: NotificationChildrenContainer
+    private lateinit var swipedRow: ExpandableNotificationRow
 
     @Before
     fun setUp() {
@@ -60,14 +62,15 @@
         notificationTestHelper =
             NotificationTestHelper(mContext, mDependency, kosmos.testableLooper, featureFlags)
         children = notificationTestHelper.createGroup(childrenNumber).childrenContainer
+        swipedRow = children.attachedChildren[childrenNumber / 2]
+        configureMagneticRowListener(swipedRow)
     }
 
     @Test
     fun setMagneticAndRoundableTargets_onIdle_targetsGetSet() =
         kosmos.testScope.runTest {
             // WHEN the targets are set for a row
-            val row = children.attachedChildren[childrenNumber / 2]
-            setTargetsForRow(row)
+            setTargets()
 
             // THEN the magnetic and roundable targets are defined and the state is TARGETS_SET
             assertThat(underTest.currentState).isEqualTo(State.TARGETS_SET)
@@ -79,22 +82,34 @@
     fun setMagneticRowTranslation_whenTargetsAreSet_startsPulling() =
         kosmos.testScope.runTest {
             // GIVEN targets are set
-            val row = children.attachedChildren[childrenNumber / 2]
-            setTargetsForRow(row)
+            setTargets()
 
             // WHEN setting a translation for the swiped row
-            underTest.setMagneticRowTranslation(row, translation = 100f)
+            underTest.setMagneticRowTranslation(swipedRow, translation = 100f)
 
             // THEN the state moves to PULLING
             assertThat(underTest.currentState).isEqualTo(State.PULLING)
         }
 
     @Test
+    fun setMagneticRowTranslation_whenIdle_doesNotSetMagneticTranslation() =
+        kosmos.testScope.runTest {
+            // GIVEN an IDLE state
+            // WHEN setting a translation for the swiped row
+            val row = children.attachedChildren[childrenNumber / 2]
+            underTest.setMagneticRowTranslation(row, translation = 100f)
+
+            // THEN no magnetic translations are set
+            val canSetMagneticTranslation =
+                underTest.setMagneticRowTranslation(row, translation = 100f)
+            assertThat(canSetMagneticTranslation).isFalse()
+        }
+
+    @Test
     fun setMagneticRowTranslation_whenRowIsNotSwiped_doesNotSetMagneticTranslation() =
         kosmos.testScope.runTest {
             // GIVEN that targets are set
-            val row = children.attachedChildren[childrenNumber / 2]
-            setTargetsForRow(row)
+            setTargets()
 
             // WHEN setting a translation for a row that is not being swiped
             val differentRow = children.attachedChildren[childrenNumber / 2 - 1]
@@ -106,41 +121,61 @@
         }
 
     @Test
-    fun setMagneticRowTranslation_belowThreshold_whilePulling_setsMagneticTranslations() =
+    fun setMagneticRowTranslation_whenDismissible_belowThreshold_whenPulling_setsTranslations() =
         kosmos.testScope.runTest {
             // GIVEN a threshold of 100 px
             val threshold = 100f
             underTest.setSwipeThresholdPx(threshold)
 
             // GIVEN that targets are set and the rows are being pulled
-            val row = children.attachedChildren[childrenNumber / 2]
-            setTargetsForRow(row)
-            underTest.setMagneticRowTranslation(row, translation = 100f)
+            setTargets()
+            underTest.setMagneticRowTranslation(swipedRow, translation = 100f)
 
             // WHEN setting a translation that will fall below the threshold
-            val translation = threshold / swipedMultiplier - 50f
-            underTest.setMagneticRowTranslation(row, translation)
+            val translation = threshold / underTest.swipedRowMultiplier - 50f
+            underTest.setMagneticRowTranslation(swipedRow, translation)
 
             // THEN the targets continue to be pulled and translations are set
             assertThat(underTest.currentState).isEqualTo(State.PULLING)
-            assertThat(row.translation).isEqualTo(swipedMultiplier * translation)
+            assertThat(swipedRow.translation).isEqualTo(underTest.swipedRowMultiplier * translation)
         }
 
     @Test
-    fun setMagneticRowTranslation_aboveThreshold_whilePulling_detachesMagneticTargets() =
+    fun setMagneticRowTranslation_whenNotDismissible_belowThreshold_whenPulling_setsTranslations() =
         kosmos.testScope.runTest {
             // GIVEN a threshold of 100 px
             val threshold = 100f
             underTest.setSwipeThresholdPx(threshold)
 
             // GIVEN that targets are set and the rows are being pulled
-            val row = children.attachedChildren[childrenNumber / 2]
-            setTargetsForRow(row)
-            underTest.setMagneticRowTranslation(row, translation = 100f)
+            canRowBeDismissed = false
+            setTargets()
+            underTest.setMagneticRowTranslation(swipedRow, translation = 100f)
+
+            // WHEN setting a translation that will fall below the threshold
+            val translation = threshold / underTest.swipedRowMultiplier - 50f
+            underTest.setMagneticRowTranslation(swipedRow, translation)
+
+            // THEN the targets continue to be pulled and reduced translations are set
+            val expectedTranslation = getReducedTranslation(translation)
+            assertThat(underTest.currentState).isEqualTo(State.PULLING)
+            assertThat(swipedRow.translation).isEqualTo(expectedTranslation)
+        }
+
+    @Test
+    fun setMagneticRowTranslation_whenDismissible_aboveThreshold_whilePulling_detaches() =
+        kosmos.testScope.runTest {
+            // GIVEN a threshold of 100 px
+            val threshold = 100f
+            underTest.setSwipeThresholdPx(threshold)
+
+            // GIVEN that targets are set and the rows are being pulled
+            setTargets()
+            underTest.setMagneticRowTranslation(swipedRow, translation = 100f)
 
             // WHEN setting a translation that will fall above the threshold
-            val translation = threshold / swipedMultiplier + 50f
-            underTest.setMagneticRowTranslation(row, translation)
+            val translation = threshold / underTest.swipedRowMultiplier + 50f
+            underTest.setMagneticRowTranslation(swipedRow, translation)
 
             // THEN the swiped view detaches and the correct detach haptics play
             assertThat(underTest.currentState).isEqualTo(State.DETACHED)
@@ -148,15 +183,36 @@
         }
 
     @Test
+    fun setMagneticRowTranslation_whenNotDismissible_aboveThreshold_whilePulling_doesNotDetach() =
+        kosmos.testScope.runTest {
+            // GIVEN a threshold of 100 px
+            val threshold = 100f
+            underTest.setSwipeThresholdPx(threshold)
+
+            // GIVEN that targets are set and the rows are being pulled
+            canRowBeDismissed = false
+            setTargets()
+            underTest.setMagneticRowTranslation(swipedRow, translation = 100f)
+
+            // WHEN setting a translation that will fall above the threshold
+            val translation = threshold / underTest.swipedRowMultiplier + 50f
+            underTest.setMagneticRowTranslation(swipedRow, translation)
+
+            // THEN the swiped view does not detach and the reduced translation is set
+            val expectedTranslation = getReducedTranslation(translation)
+            assertThat(underTest.currentState).isEqualTo(State.PULLING)
+            assertThat(swipedRow.translation).isEqualTo(expectedTranslation)
+        }
+
+    @Test
     fun setMagneticRowTranslation_whileDetached_setsTranslationAndStaysDetached() =
         kosmos.testScope.runTest {
             // GIVEN that the swiped view has been detached
-            val row = children.attachedChildren[childrenNumber / 2]
-            setDetachedState(row)
+            setDetachedState()
 
             // WHEN setting a new translation
             val translation = 300f
-            underTest.setMagneticRowTranslation(row, translation)
+            underTest.setMagneticRowTranslation(swipedRow, translation)
 
             // THEN the swiped view continues to be detached
             assertThat(underTest.currentState).isEqualTo(State.DETACHED)
@@ -166,14 +222,13 @@
     fun onMagneticInteractionEnd_whilePulling_goesToIdle() =
         kosmos.testScope.runTest {
             // GIVEN targets are set
-            val row = children.attachedChildren[childrenNumber / 2]
-            setTargetsForRow(row)
+            setTargets()
 
             // WHEN setting a translation for the swiped row
-            underTest.setMagneticRowTranslation(row, translation = 100f)
+            underTest.setMagneticRowTranslation(swipedRow, translation = 100f)
 
             // WHEN the interaction ends on the row
-            underTest.onMagneticInteractionEnd(row, velocity = null)
+            underTest.onMagneticInteractionEnd(swipedRow, velocity = null)
 
             // THEN the state resets
             assertThat(underTest.currentState).isEqualTo(State.IDLE)
@@ -183,32 +238,56 @@
     fun onMagneticInteractionEnd_whileDetached_goesToIdle() =
         kosmos.testScope.runTest {
             // GIVEN the swiped row is detached
-            val row = children.attachedChildren[childrenNumber / 2]
-            setDetachedState(row)
+            setDetachedState()
 
             // WHEN the interaction ends on the row
-            underTest.onMagneticInteractionEnd(row, velocity = null)
+            underTest.onMagneticInteractionEnd(swipedRow, velocity = null)
 
             // THEN the state resets
             assertThat(underTest.currentState).isEqualTo(State.IDLE)
         }
 
-    private fun setDetachedState(row: ExpandableNotificationRow) {
+    private fun setDetachedState() {
         val threshold = 100f
         underTest.setSwipeThresholdPx(threshold)
 
         // Set the pulling state
-        setTargetsForRow(row)
-        underTest.setMagneticRowTranslation(row, translation = 100f)
+        setTargets()
+        underTest.setMagneticRowTranslation(swipedRow, translation = 100f)
 
         // Set a translation that will fall above the threshold
-        val translation = threshold / swipedMultiplier + 50f
-        underTest.setMagneticRowTranslation(row, translation)
+        val translation = threshold / underTest.swipedRowMultiplier + 50f
+        underTest.setMagneticRowTranslation(swipedRow, translation)
 
         assertThat(underTest.currentState).isEqualTo(State.DETACHED)
     }
 
-    private fun setTargetsForRow(row: ExpandableNotificationRow) {
-        underTest.setMagneticAndRoundableTargets(row, stackScrollLayout, sectionsManager)
+    private fun setTargets() {
+        underTest.setMagneticAndRoundableTargets(swipedRow, stackScrollLayout, sectionsManager)
+    }
+
+    private fun getReducedTranslation(originalTranslation: Float) =
+        underTest.swipedRowMultiplier *
+            originalTranslation *
+            MagneticNotificationRowManagerImpl.MAGNETIC_REDUCTION
+
+    private fun configureMagneticRowListener(row: ExpandableNotificationRow) {
+        val listener =
+            object : MagneticRowListener {
+                override fun setMagneticTranslation(translation: Float) {
+                    row.translation = translation
+                }
+
+                override fun triggerMagneticForce(
+                    endTranslation: Float,
+                    springForce: SpringForce,
+                    startVelocity: Float,
+                ) {}
+
+                override fun cancelMagneticAnimations() {}
+
+                override fun canRowBeDismissed(): Boolean = canRowBeDismissed
+            }
+        row.magneticRowListener = listener
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index 39cff63..7659fb4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -6,6 +6,7 @@
 import android.widget.FrameLayout
 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
@@ -30,7 +31,6 @@
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
 import com.google.common.truth.Expect
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import org.junit.Assume
 import org.junit.Before
 import org.junit.Rule
@@ -58,7 +58,6 @@
     private val notificationRow = mock<ExpandableNotificationRow>()
     private val notificationEntry = mock<NotificationEntry>()
     private val dumpManager = mock<DumpManager>()
-    @OptIn(ExperimentalCoroutinesApi::class)
     private val mStatusBarKeyguardViewManager = mock<StatusBarKeyguardViewManager>()
     private val notificationShelf = mock<NotificationShelf>()
     private val emptyShadeView =
@@ -66,7 +65,6 @@
             layout(/* l= */ 0, /* t= */ 0, /* r= */ 100, /* b= */ 100)
         }
     private val footerView = FooterView(context, /* attrs= */ null)
-    @OptIn(ExperimentalCoroutinesApi::class)
     private val ambientState =
         AmbientState(
             context,
@@ -481,7 +479,11 @@
         stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
 
         val marginBottom =
-            context.resources.getDimensionPixelSize(R.dimen.notification_panel_margin_bottom)
+            context.resources.getDimensionPixelSize(
+                if (Flags.notificationsRedesignFooterView())
+                    R.dimen.notification_2025_panel_margin_bottom
+                else R.dimen.notification_panel_margin_bottom
+            )
         val fullHeight = ambientState.layoutMaxHeight + marginBottom - ambientState.stackY
         val centeredY = ambientState.stackY + fullHeight / 2f - emptyShadeView.height / 2f
         assertThat(emptyShadeView.viewState.yTranslation).isEqualTo(centeredY)
@@ -499,7 +501,6 @@
         assertThat(notificationRow.viewState.alpha).isEqualTo(1f)
     }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun resetViewStates_expansionChanging_notificationBecomesTransparent() {
         whenever(mStatusBarKeyguardViewManager.isPrimaryBouncerInTransit).thenReturn(false)
@@ -509,7 +510,6 @@
         )
     }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun resetViewStates_expansionChangingWhileBouncerInTransit_viewBecomesTransparent() {
         whenever(mStatusBarKeyguardViewManager.isPrimaryBouncerInTransit).thenReturn(true)
@@ -519,7 +519,6 @@
         )
     }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun resetViewStates_expansionChanging_notificationAlphaUpdated() {
         whenever(mStatusBarKeyguardViewManager.isPrimaryBouncerInTransit).thenReturn(false)
@@ -529,7 +528,6 @@
         )
     }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun resetViewStates_largeScreen_expansionChanging_alphaUpdated_largeScreenValue() {
         val expansionFraction = 0.6f
@@ -545,7 +543,6 @@
         )
     }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun expansionChanging_largeScreen_bouncerInTransit_alphaUpdated_bouncerValues() {
         ambientState.isSmallScreen = false
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt
index d665b31..5db9bca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/HideNotificationsInteractorTest.kt
@@ -39,7 +39,6 @@
 import com.google.common.truth.Truth.assertThat
 import java.time.Duration
 import java.util.Optional
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
@@ -50,7 +49,6 @@
 import org.junit.runner.RunWith
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 open class HideNotificationsInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt
index 1c6bda9..d52f5de 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackInteractorTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification.stack.domain.interactor
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -29,7 +27,6 @@
 import com.android.systemui.power.shared.model.WakefulnessState
 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
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt
index 4176d1c..21ebe7f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractorTest.kt
@@ -15,8 +15,6 @@
  *
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification.stack.domain.interactor
 
 import android.platform.test.flag.junit.FlagsParameterization
@@ -32,7 +30,6 @@
 import com.android.systemui.res.R
 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
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationStatsLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationStatsLoggerTest.kt
index 13280f2..80e9e36 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationStatsLoggerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationStatsLoggerTest.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.util.mockito.eq
 import com.google.common.truth.Truth.assertThat
 import java.util.concurrent.Callable
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
@@ -42,7 +41,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class NotificationStatsLoggerTest : SysuiTestCase() {
@@ -172,6 +170,41 @@
         }
 
     @Test
+    fun onNotificationVisibilityChanged_thenShadeNotInteractive_noDuplicateLogs() =
+        testScope.runTest {
+            // GIVEN a visible Notifications is reported
+            val (ranks, locations) = fakeNotificationMaps("key0")
+            val callable = Callable { locations }
+            underTest.onNotificationLocationsChanged(callable, ranks)
+            runCurrent()
+            clearInvocations(mockStatusBarService, mockNotificationListenerService)
+
+            // WHEN the same Notification becomins invisible
+            val emptyCallable = Callable { emptyMap<String, Int>() }
+            underTest.onNotificationLocationsChanged(emptyCallable, ranks)
+            // AND notifications become non interactible
+            underTest.onLockscreenOrShadeNotInteractive(emptyList())
+            runCurrent()
+
+            // THEN visibility changes are reported
+            verify(mockStatusBarService)
+                .onNotificationVisibilityChanged(eq(emptyArray()), visibilityArrayCaptor.capture())
+            val noLongerVisible = visibilityArrayCaptor.value
+            assertThat(noLongerVisible).hasLength(1)
+            assertThat(noLongerVisible[0]).apply {
+                isKeyEqualTo("key0")
+                isRankEqualTo(0)
+                notVisible()
+                isInMainArea()
+                isCountEqualTo(1)
+            }
+
+            // AND nothing else is logged
+            verifyNoMoreInteractions(mockStatusBarService)
+            verifyNoMoreInteractions(mockNotificationListenerService)
+        }
+
+    @Test
     fun onNotificationListUpdated_itemsChangedPositions_nothingLogged() =
         testScope.runTest {
             // GIVEN some visible Notifications are reported
@@ -255,14 +288,14 @@
                     activeNotificationModel(
                         key = "key0",
                         uid = 0,
-                        packageName = "com.android.first"
+                        packageName = "com.android.first",
                     ),
                     activeNotificationModel(
                         key = "key1",
                         uid = 1,
-                        packageName = "com.android.second"
+                        packageName = "com.android.second",
                     ),
-                )
+                ),
             )
             runCurrent()
 
@@ -288,7 +321,7 @@
                 key = "key",
                 isExpanded = true,
                 location = ExpandableViewState.LOCATION_MAIN_AREA,
-                isUserAction = true
+                isUserAction = true,
             )
             runCurrent()
 
@@ -298,7 +331,7 @@
                     /* key = */ "key",
                     /* userAction = */ true,
                     /* expanded = */ true,
-                    NotificationVisibility.NotificationLocation.LOCATION_MAIN_AREA.ordinal
+                    NotificationVisibility.NotificationLocation.LOCATION_MAIN_AREA.ordinal,
                 )
         }
 
@@ -310,7 +343,7 @@
                 key = "key",
                 isExpanded = true,
                 location = ExpandableViewState.LOCATION_MAIN_AREA,
-                isUserAction = true
+                isUserAction = true,
             )
             runCurrent()
             clearInvocations(mockStatusBarService)
@@ -320,7 +353,7 @@
                 key = "key",
                 isExpanded = true,
                 location = ExpandableViewState.LOCATION_MAIN_AREA,
-                isUserAction = true
+                isUserAction = true,
             )
             runCurrent()
 
@@ -336,7 +369,7 @@
                 key = "key",
                 isExpanded = true,
                 location = ExpandableViewState.LOCATION_BOTTOM_STACK_HIDDEN,
-                isUserAction = true
+                isUserAction = true,
             )
             runCurrent()
 
@@ -352,7 +385,7 @@
                 key = "key",
                 isExpanded = true,
                 location = ExpandableViewState.LOCATION_GONE,
-                isUserAction = false
+                isUserAction = false,
             )
             runCurrent()
 
@@ -368,7 +401,7 @@
                     /* key = */ "key",
                     /* userAction = */ false,
                     /* expanded = */ true,
-                    NotificationVisibility.NotificationLocation.LOCATION_MAIN_AREA.ordinal
+                    NotificationVisibility.NotificationLocation.LOCATION_MAIN_AREA.ordinal,
                 )
         }
 
@@ -380,7 +413,7 @@
                 key = "key",
                 isExpanded = true,
                 location = ExpandableViewState.LOCATION_GONE,
-                isUserAction = false
+                isUserAction = false,
             )
             runCurrent()
             // AND we open the shade, so we log its events
@@ -406,7 +439,7 @@
                     /* key = */ "key",
                     /* userAction = */ false,
                     /* expanded = */ true,
-                    NotificationVisibility.NotificationLocation.LOCATION_MAIN_AREA.ordinal
+                    NotificationVisibility.NotificationLocation.LOCATION_MAIN_AREA.ordinal,
                 )
         }
 
@@ -418,7 +451,7 @@
                 key = "key",
                 isExpanded = false,
                 location = ExpandableViewState.LOCATION_MAIN_AREA,
-                isUserAction = false
+                isUserAction = false,
             )
             runCurrent()
 
@@ -435,7 +468,7 @@
                 key = "key",
                 isExpanded = true,
                 location = ExpandableViewState.LOCATION_MAIN_AREA,
-                isUserAction = true
+                isUserAction = true,
             )
             runCurrent()
 
@@ -445,7 +478,7 @@
                     /* key = */ "key",
                     /* userAction = */ true,
                     /* expanded = */ true,
-                    NotificationVisibility.NotificationLocation.LOCATION_MAIN_AREA.ordinal
+                    NotificationVisibility.NotificationLocation.LOCATION_MAIN_AREA.ordinal,
                 )
 
             // AND the Notification is expanded again
@@ -453,7 +486,7 @@
                 key = "key",
                 isExpanded = false,
                 location = ExpandableViewState.LOCATION_MAIN_AREA,
-                isUserAction = true
+                isUserAction = true,
             )
             runCurrent()
 
@@ -463,7 +496,7 @@
                     /* key = */ "key",
                     /* userAction = */ true,
                     /* expanded = */ false,
-                    NotificationVisibility.NotificationLocation.LOCATION_MAIN_AREA.ordinal
+                    NotificationVisibility.NotificationLocation.LOCATION_MAIN_AREA.ordinal,
                 )
         }
 
@@ -475,14 +508,14 @@
                 key = "key1",
                 isExpanded = true,
                 location = ExpandableViewState.LOCATION_MAIN_AREA,
-                isUserAction = true
+                isUserAction = true,
             )
             runCurrent()
             underTest.onNotificationExpansionChanged(
                 key = "key2",
                 isExpanded = true,
                 location = ExpandableViewState.LOCATION_MAIN_AREA,
-                isUserAction = true
+                isUserAction = true,
             )
             runCurrent()
             clearInvocations(mockStatusBarService)
@@ -502,14 +535,14 @@
                 key = "key1",
                 isExpanded = true,
                 location = ExpandableViewState.LOCATION_MAIN_AREA,
-                isUserAction = true
+                isUserAction = true,
             )
             runCurrent()
             underTest.onNotificationExpansionChanged(
                 key = "key2",
                 isExpanded = true,
                 location = ExpandableViewState.LOCATION_MAIN_AREA,
-                isUserAction = true
+                isUserAction = true,
             )
             runCurrent()
             clearInvocations(mockStatusBarService)
@@ -537,10 +570,15 @@
 
 private class NotificationVisibilitySubject(private val visibility: NotificationVisibility) {
     fun isKeyEqualTo(key: String) = assertThat(visibility.key).isEqualTo(key)
+
     fun isRankEqualTo(rank: Int) = assertThat(visibility.rank).isEqualTo(rank)
+
     fun isCountEqualTo(count: Int) = assertThat(visibility.count).isEqualTo(count)
+
     fun isVisible() = assertThat(this.visibility.visible).isTrue()
+
     fun notVisible() = assertThat(this.visibility.visible).isFalse()
+
     fun isInMainArea() =
         assertThat(this.visibility.location)
             .isEqualTo(NotificationVisibility.NotificationLocation.LOCATION_MAIN_AREA)
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 1b4f9a7..911b1b5 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
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification.stack.ui.viewmodel
 
 import android.platform.test.flag.junit.FlagsParameterization
@@ -48,7 +46,6 @@
 import com.android.systemui.util.ui.isAnimating
 import com.android.systemui.util.ui.value
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
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 786b359..af00e2a 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
@@ -15,13 +15,14 @@
  *
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification.stack.ui.viewmodel
 
+import android.platform.test.annotations.DisableFlags
+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_NOTIFICATIONS_REDESIGN_FOOTER_VIEW
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.bouncer.data.repository.keyguardBouncerRepository
 import com.android.systemui.common.shared.model.NotificationContainerBounds
@@ -74,7 +75,6 @@
 import com.google.common.collect.Range
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.assertIs
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.TestScope
@@ -298,6 +298,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_NOTIFICATIONS_REDESIGN_FOOTER_VIEW)
     fun validateMarginBottom() =
         testScope.runTest {
             overrideResource(R.dimen.notification_panel_margin_bottom, 50)
@@ -310,6 +311,19 @@
         }
 
     @Test
+    @EnableFlags(FLAG_NOTIFICATIONS_REDESIGN_FOOTER_VIEW)
+    fun validateMarginBottom_footerRedesign() =
+        testScope.runTest {
+            overrideResource(R.dimen.notification_2025_panel_margin_bottom, 50)
+
+            val dimens by collectLastValue(underTest.configurationBasedDimensions)
+
+            configurationRepository.onAnyConfigurationChange()
+
+            assertThat(dimens!!.marginBottom).isEqualTo(50)
+        }
+
+    @Test
     @DisableSceneContainer
     fun validateMarginTopWithLargeScreenHeader_usesHelper() =
         testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt
index b0b80a9..52c41a0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ActivityStarterImplTest.kt
@@ -25,11 +25,14 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ActivityTransitionAnimator
 import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.shared.Flags as SharedFlags
 import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.testKosmos
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.time.FakeSystemClock
 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
@@ -48,6 +51,7 @@
     @Mock private lateinit var activityStarterInternal: ActivityStarterInternalImpl
     @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
     private lateinit var underTest: ActivityStarterImpl
+    private val kosmos = testKosmos()
     private val mainExecutor = FakeExecutor(FakeSystemClock())
 
     @Before
@@ -69,12 +73,18 @@
     @EnableSceneContainer
     @Test
     fun registerTransition_forwardsTheRequest() {
-        val cookie = mock(ActivityTransitionAnimator.TransitionCookie::class.java)
-        val controllerFactory = mock(ActivityTransitionAnimator.ControllerFactory::class.java)
+        with(kosmos) {
+            testScope.runTest {
+                val cookie = mock(ActivityTransitionAnimator.TransitionCookie::class.java)
+                val controllerFactory =
+                    mock(ActivityTransitionAnimator.ControllerFactory::class.java)
 
-        underTest.registerTransition(cookie, controllerFactory)
+                underTest.registerTransition(cookie, controllerFactory, testScope)
 
-        verify(activityStarterInternal).registerTransition(eq(cookie), eq(controllerFactory))
+                verify(activityStarterInternal)
+                    .registerTransition(eq(cookie), eq(controllerFactory), eq(testScope))
+            }
+        }
     }
 
     @DisableFlags(
@@ -83,12 +93,17 @@
     )
     @Test
     fun registerTransition_doesNotForwardTheRequest_whenFlaggedOff() {
-        val cookie = mock(ActivityTransitionAnimator.TransitionCookie::class.java)
-        val controllerFactory = mock(ActivityTransitionAnimator.ControllerFactory::class.java)
+        with(kosmos) {
+            testScope.runTest {
+                val cookie = mock(ActivityTransitionAnimator.TransitionCookie::class.java)
+                val controllerFactory =
+                    mock(ActivityTransitionAnimator.ControllerFactory::class.java)
 
-        underTest.registerTransition(cookie, controllerFactory)
+                underTest.registerTransition(cookie, controllerFactory, testScope)
 
-        verify(activityStarterInternal, never()).registerTransition(any(), any())
+                verify(activityStarterInternal, never()).registerTransition(any(), any(), any())
+            }
+        }
     }
 
     @EnableFlags(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
index f318c74..7bc2bca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
@@ -43,6 +43,8 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.emergency.EmergencyGestureModule.EmergencyGestureIntentFactory;
+import com.android.systemui.flags.DisableSceneContainer;
+import com.android.systemui.flags.EnableSceneContainer;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
 import com.android.systemui.plugins.ActivityStarter;
@@ -55,10 +57,8 @@
 import com.android.systemui.shade.QuickSettingsController;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.shade.ShadeHeaderController;
-import com.android.systemui.shade.ShadeViewController;
 import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor;
 import com.android.systemui.shade.domain.interactor.ShadeInteractor;
-import com.android.systemui.shade.shared.flag.DualShade;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
@@ -67,6 +67,8 @@
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
 import com.android.systemui.wallet.controller.QuickAccessWalletController;
 
+import dagger.Lazy;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -76,8 +78,6 @@
 
 import java.util.Optional;
 
-import dagger.Lazy;
-
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase {
@@ -87,7 +87,6 @@
     @Mock private ShadeController mShadeController;
     @Mock private CommandQueue mCommandQueue;
     @Mock private QuickSettingsController mQuickSettingsController;
-    @Mock private ShadeViewController mShadeViewController;
     @Mock private PanelExpansionInteractor mPanelExpansionInteractor;
     @Mock private Lazy<ShadeInteractor> mShadeInteractorLazy;
     @Mock private ShadeHeaderController mShadeHeaderController;
@@ -242,7 +241,8 @@
     }
 
     @Test
-    @DisableFlags(value = {QSComposeFragment.FLAG_NAME, DualShade.FLAG_NAME})
+    @DisableSceneContainer
+    @DisableFlags(QSComposeFragment.FLAG_NAME)
     public void clickQsTile_flagsDisabled_callsQSPanelController() {
         ComponentName c = new ComponentName("testpkg", "testcls");
 
@@ -251,7 +251,7 @@
     }
 
     @Test
-    @DisableFlags(DualShade.FLAG_NAME)
+    @DisableSceneContainer
     @EnableFlags(QSComposeFragment.FLAG_NAME)
     public void clickQsTile_onlyQSComposeFlag_callsQSHost() {
         ComponentName c = new ComponentName("testpkg", "testcls");
@@ -262,9 +262,9 @@
     }
 
     @Test
-    @EnableFlags(DualShade.FLAG_NAME)
+    @EnableSceneContainer
     @DisableFlags(QSComposeFragment.FLAG_NAME)
-    public void clickQsTile_onlyDualShadeFlag_callsQSHost() {
+    public void clickQsTile_onlySceneContainerFlag_callsQSHost() {
         ComponentName c = new ComponentName("testpkg", "testcls");
 
         mSbcqCallbacks.clickTile(c);
@@ -273,8 +273,9 @@
     }
 
     @Test
-    @EnableFlags(value = {QSComposeFragment.FLAG_NAME, DualShade.FLAG_NAME})
-    public void clickQsTile_qsComposeAndDualShadeFlags_callsQSHost() {
+    @EnableSceneContainer
+    @EnableFlags(QSComposeFragment.FLAG_NAME)
+    public void clickQsTile_qsComposeAndSceneContainerFlags_callsQSHost() {
         ComponentName c = new ComponentName("testpkg", "testcls");
 
         mSbcqCallbacks.clickTile(c);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostCoroutinesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostCoroutinesTest.kt
index 7bc6948..52eda1c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostCoroutinesTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostCoroutinesTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.phone
 
 import android.testing.TestableLooper.RunWithLooper
@@ -32,7 +30,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.mock
 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
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt
index cb40f72..d957770 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardBypassControllerTest.kt
@@ -42,7 +42,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.tuner.TunerService
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.After
@@ -303,7 +302,6 @@
         assertThat(keyguardBypassController.bypassEnabled).isFalse()
     }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun qsExpansion_updates() {
         testScope.runTest {
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 5406acf..dffb64b 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
@@ -42,6 +42,7 @@
 import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
 import com.android.systemui.keyguard.KeyguardViewMediator
 import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.shade.ShadeController
@@ -58,12 +59,13 @@
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
+import com.android.systemui.testKosmos
 import com.android.systemui.util.concurrency.FakeExecutor
 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 kotlinx.coroutines.test.runTest
 import org.junit.Assert.assertThrows
 import org.junit.Before
 import org.junit.Test
@@ -82,7 +84,6 @@
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class LegacyActivityStarterInternalImplTest : SysuiTestCase() {
@@ -109,6 +110,7 @@
     @Mock private lateinit var communalSceneInteractor: CommunalSceneInteractor
     @Mock private lateinit var communalSettingsInteractor: CommunalSettingsInteractor
     private lateinit var underTest: LegacyActivityStarterInternalImpl
+    private val kosmos = testKosmos()
     private val mainExecutor = FakeExecutor(FakeSystemClock())
     private val shadeAnimationInteractor =
         ShadeAnimationInteractorLegacyImpl(ShadeAnimationRepository(), FakeShadeRepository())
@@ -157,13 +159,18 @@
     )
     @Test
     fun registerTransition_registers() {
-        val cookie = mock(ActivityTransitionAnimator.TransitionCookie::class.java)
-        val controllerFactory = mock(ActivityTransitionAnimator.ControllerFactory::class.java)
-        `when`(controllerFactory.cookie).thenReturn(cookie)
+        with(kosmos) {
+            testScope.runTest {
+                val cookie = mock(ActivityTransitionAnimator.TransitionCookie::class.java)
+                val controllerFactory =
+                    mock(ActivityTransitionAnimator.ControllerFactory::class.java)
+                `when`(controllerFactory.cookie).thenReturn(cookie)
 
-        underTest.registerTransition(cookie, controllerFactory)
+                underTest.registerTransition(cookie, controllerFactory, testScope)
 
-        verify(activityTransitionAnimator).register(eq(cookie), any())
+                verify(activityTransitionAnimator).register(eq(cookie), any(), eq(testScope))
+            }
+        }
     }
 
     @DisableFlags(
@@ -172,14 +179,19 @@
     )
     @Test
     fun registerTransition_throws_whenFlagsAreDisabled() {
-        val cookie = mock(ActivityTransitionAnimator.TransitionCookie::class.java)
-        val controllerFactory = mock(ActivityTransitionAnimator.ControllerFactory::class.java)
+        with(kosmos) {
+            testScope.runTest {
+                val cookie = mock(ActivityTransitionAnimator.TransitionCookie::class.java)
+                val controllerFactory =
+                    mock(ActivityTransitionAnimator.ControllerFactory::class.java)
 
-        assertThrows(IllegalStateException::class.java) {
-            underTest.registerTransition(cookie, controllerFactory)
+                assertThrows(IllegalStateException::class.java) {
+                    underTest.registerTransition(cookie, controllerFactory, testScope)
+                }
+
+                verify(activityTransitionAnimator, never()).register(any(), any(), any())
+            }
         }
-
-        verify(activityTransitionAnimator, never()).register(any(), any())
     }
 
     @EnableFlags(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
index 4313aea..4e41471 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
@@ -67,7 +67,6 @@
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.time.DateFormatUtil
 import com.android.systemui.util.time.FakeSystemClock
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runCurrent
@@ -93,7 +92,6 @@
 
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 class PhoneStatusBarPolicyTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManagerTest.kt
index d82cb86..b8b084c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManagerTest.kt
@@ -31,7 +31,6 @@
 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
@@ -40,7 +39,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class ShadeTouchableRegionManagerTest : SysuiTestCase() {
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt
index 1ee8005..0372896 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIBottomSheetDialogTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.mock
 import kotlin.test.Test
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runTest
@@ -38,7 +37,6 @@
 import org.junit.runner.RunWith
 import org.mockito.Mockito.verify
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/data/repository/KeyguardBypassRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/data/repository/KeyguardBypassRepositoryTest.kt
index a2fabf3..41fb4c1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/data/repository/KeyguardBypassRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/data/repository/KeyguardBypassRepositoryTest.kt
@@ -36,14 +36,12 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.settings.data.repository.userAwareSecureSettingsRepository
 import com.google.common.truth.Truth.assertThat
-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
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableSceneContainer
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/KeyguardBypassInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/KeyguardBypassInteractorTest.kt
index 1cc55bf..091fbb6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/KeyguardBypassInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/KeyguardBypassInteractorTest.kt
@@ -33,13 +33,11 @@
 import com.android.systemui.shade.shadeTestUtil
 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)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @EnableSceneContainer
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
index 02135f6..eb95ddb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
@@ -49,7 +49,6 @@
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.After
@@ -69,7 +68,6 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
-@OptIn(ExperimentalCoroutinesApi::class)
 @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
 class OngoingCallControllerTest : SysuiTestCase() {
     private val kosmos = Kosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt
index 14263c4..73c191b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.phone.ongoingcall.domain.interactor
 
 import android.app.PendingIntent
@@ -40,7 +38,6 @@
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
 import com.android.systemui.statusbar.window.fakeStatusBarWindowControllerStore
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/AirplaneModeRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/AirplaneModeRepositoryImplTest.kt
index 0641e17..ac92659 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/AirplaneModeRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/AirplaneModeRepositoryImplTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.settings.FakeGlobalSettings
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -41,7 +40,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AirplaneModeRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/domain/interactor/AirplaneModeInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/domain/interactor/AirplaneModeInteractorTest.kt
index 7901f47..8e03563 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/domain/interactor/AirplaneModeInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/airplane/domain/interactor/AirplaneModeInteractorTest.kt
@@ -25,7 +25,6 @@
 import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
 import com.android.systemui.testKosmos
 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.runCurrent
@@ -33,7 +32,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AirplaneModeInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
index 7d32021..e4806e6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
@@ -34,7 +34,6 @@
 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.Job
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -54,7 +53,6 @@
  * verifies that passing the given model to [DemoMobileConnectionsRepository] results in the correct
  * flows emitting from the given connection.
  */
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 internal class DemoMobileConnectionParameterizedTest(private val testCase: TestCase) :
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
index 5017dda..25359c9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
@@ -38,7 +38,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import junit.framework.Assert
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.launchIn
@@ -51,7 +50,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DemoMobileConnectionsRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt
index 715e3b4..8e55f2e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
 import com.android.systemui.util.mockito.whenever
 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
@@ -43,7 +42,6 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
index 39a1c10..4009144 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
@@ -45,7 +45,6 @@
 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.launchIn
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.test.TestScope
@@ -57,7 +56,6 @@
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.anyString
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MobileIconInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
index 6efb9c7..d17abd7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
@@ -46,14 +46,12 @@
 import com.android.systemui.util.CarrierConfigTracker
 import com.google.common.truth.Truth.assertThat
 import java.util.UUID
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceTimeBy
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MobileIconsInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt
index f99fcac..cef0824e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt
@@ -41,7 +41,6 @@
 import com.android.systemui.util.CarrierConfigTracker
 import com.android.systemui.util.mockito.mock
 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
@@ -54,7 +53,6 @@
 import org.mockito.MockitoAnnotations
 
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class LocationBasedMobileIconViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
index bf1fbad..61ed04c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
@@ -58,7 +58,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.filterIsInstance
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
@@ -73,7 +72,6 @@
 import org.mockito.MockitoAnnotations
 
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MobileIconViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt
index 31ba837..46777fa 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt
@@ -40,7 +40,6 @@
 import com.google.common.truth.Truth.assertThat
 import junit.framework.Assert.assertFalse
 import junit.framework.Assert.assertTrue
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.isActive
@@ -54,7 +53,6 @@
 import org.mockito.MockitoAnnotations
 
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MobileIconsViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt
index 19d5a16..30346ca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt
@@ -35,7 +35,6 @@
 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 kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -95,7 +94,6 @@
             testScope.backgroundScope,
         )
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun switcherActiveRepo_updatesWhenDemoModeChanges() =
         testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
index fe5b56a..c493c02 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
@@ -36,7 +36,6 @@
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
 import kotlin.time.Duration.Companion.seconds
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runTest
@@ -45,7 +44,6 @@
 import org.mockito.MockitoAnnotations
 import org.mockito.kotlin.mock
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceBasedSatelliteViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewBinder.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewBinder.kt
index a2ca12c..5b5681e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewBinder.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewBinder.kt
@@ -35,7 +35,7 @@
         viewModel: HomeStatusBarViewModel,
         systemEventChipAnimateIn: ((View) -> Unit)?,
         systemEventChipAnimateOut: ((View) -> Unit)?,
-        listener: StatusBarVisibilityChangeListener,
+        listener: StatusBarVisibilityChangeListener?,
     ) {
         this.listener = listener
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
index 0223484..4af97c0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
@@ -52,8 +52,6 @@
 
     override val isHomeStatusBarAllowedByScene = MutableStateFlow(false)
 
-    override val shouldHomeStatusBarBeVisible = MutableStateFlow(false)
-
     override val shouldShowOperatorNameView = MutableStateFlow(false)
 
     override val isClockVisible =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
index 46f625f..dc35543 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
@@ -88,16 +88,13 @@
 import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.runBlocking
-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 HomeStatusBarViewModelImplTest : SysuiTestCase() {
     private val kosmos = testKosmos().useUnconfinedTestDispatcher()
@@ -651,98 +648,6 @@
         }
 
     @Test
-    fun shouldHomeStatusBarBeVisible_keyguardNotGone_noHun_false() =
-        kosmos.runTest {
-            // Do not transition from keyguard. i.e., we don't call transitionKeyguardToGone()
-
-            // Nothing disabled
-            fakeDisableFlagsRepository.disableFlags.value =
-                DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)
-
-            val latest by collectLastValue(underTest.shouldHomeStatusBarBeVisible)
-            assertThat(latest).isFalse()
-        }
-
-    @Test
-    fun shouldHomeStatusBarBeVisible_keyguardNotGone_hun_true() =
-        kosmos.runTest {
-            // Keyguard gone
-            transitionKeyguardToGone()
-
-            // Nothing disabled
-            fakeDisableFlagsRepository.disableFlags.value =
-                DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)
-
-            // there is an active HUN
-            headsUpNotificationRepository.setNotifications(
-                UnconfinedFakeHeadsUpRowRepository(
-                    key = "key",
-                    pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
-                )
-            )
-
-            val latest by collectLastValue(underTest.shouldHomeStatusBarBeVisible)
-            assertThat(latest).isTrue()
-        }
-
-    @Test
-    fun shouldHomeStatusBarBeVisible_keyguardGone_noHun_notInCamera_true() =
-        kosmos.runTest {
-            // Keyguard gone
-            transitionKeyguardToGone()
-
-            // Nothing disabled
-            fakeDisableFlagsRepository.disableFlags.value =
-                DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)
-
-            val latest by collectLastValue(underTest.shouldHomeStatusBarBeVisible)
-            assertThat(latest).isTrue()
-        }
-
-    @Test
-    fun shouldHomeStatusBarBeVisible_keyguardGone_hun_notInCamera_true() =
-        kosmos.runTest {
-            // Keyguard gone
-            transitionKeyguardToGone()
-
-            // Nothing disabled
-            fakeDisableFlagsRepository.disableFlags.value =
-                DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)
-
-            // there is an active HUN
-            headsUpNotificationRepository.setNotifications(
-                UnconfinedFakeHeadsUpRowRepository(
-                    key = "key",
-                    pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
-                )
-            )
-
-            val latest by collectLastValue(underTest.shouldHomeStatusBarBeVisible)
-            assertThat(latest).isTrue()
-        }
-
-    @Test
-    fun shouldHomeStatusBarBeVisible_keyguardGone_noHun_inCamera_false() =
-        kosmos.runTest {
-            // Keyguard gone
-            transitionKeyguardToGone()
-
-            // Nothing disabled
-            fakeDisableFlagsRepository.disableFlags.value =
-                DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)
-
-            fakeKeyguardTransitionRepository.sendTransitionSteps(
-                from = KeyguardState.LOCKSCREEN,
-                to = KeyguardState.OCCLUDED,
-                testScope = testScope,
-            )
-            kosmos.keyguardInteractor.onCameraLaunchDetected(CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP)
-
-            val latest by collectLastValue(underTest.shouldHomeStatusBarBeVisible)
-            assertThat(latest).isFalse()
-        }
-
-    @Test
     fun isClockVisible_allowedByDisableFlags_visible() =
         kosmos.runTest {
             val latest by collectLastValue(underTest.isClockVisible)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
index 33223ae..914d9f2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
@@ -38,7 +38,6 @@
 import com.android.systemui.util.time.FakeSystemClock
 import com.android.wifitrackerlib.WifiPickerTracker
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
@@ -52,7 +51,6 @@
 import org.mockito.Mockito
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
 @SmallTest
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
index c0a1592..2aecf5b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiScanEntry
 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
@@ -39,7 +38,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
 @SmallTest
 @RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.kt
index 2225008..24fee19 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.kt
@@ -31,7 +31,6 @@
 import com.google.common.truth.Truth.assertThat
 import java.util.concurrent.atomic.AtomicBoolean
 import java.util.concurrent.atomic.AtomicInteger
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -42,7 +41,6 @@
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ZenModesCleanupStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ZenModesCleanupStartableTest.kt
index fd89581..170a84b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ZenModesCleanupStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ZenModesCleanupStartableTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.kosmos.backgroundCoroutineContext
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -40,7 +39,6 @@
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 @EnableFlags(android.app.Flags.FLAG_MODES_UI)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt
index 94f0d19..23933f6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt
@@ -24,7 +24,6 @@
 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.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestCoroutineScheduler
 import kotlinx.coroutines.test.TestDispatcher
@@ -35,7 +34,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class BluetoothRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/FakeBluetoothRepository.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/FakeBluetoothRepository.kt
index d8c0f77..cdaca51 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/FakeBluetoothRepository.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/bluetooth/FakeBluetoothRepository.kt
@@ -16,7 +16,6 @@
 
 import com.android.settingslib.bluetooth.CachedBluetoothDevice
 import com.android.settingslib.bluetooth.LocalBluetoothManager
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestCoroutineScheduler
 import kotlinx.coroutines.test.TestScope
@@ -28,7 +27,6 @@
  * [StandardTestDispatcher], etc. to create a test version of the repo. This class uses those test
  * items under-the-hood so Java classes can indirectly access them.
  */
-@OptIn(ExperimentalCoroutinesApi::class)
 class FakeBluetoothRepository(localBluetoothManager: LocalBluetoothManager) : BluetoothRepository {
 
     private val scheduler = TestCoroutineScheduler()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt
index 21ed384..703baa1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt
@@ -13,8 +13,6 @@
  * 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 androidx.test.ext.junit.runners.AndroidJUnit4
@@ -25,7 +23,6 @@
 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
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/data/repository/UserSetupRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/data/repository/UserSetupRepositoryTest.kt
index 4c8bbe0..441b330 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/data/repository/UserSetupRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/data/repository/UserSetupRepositoryTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.policy.data.repository
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -34,7 +32,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.test.runCurrent
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateTest.kt
index 2d63150..ffdebb3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.policy.ui.dialog
 
 import android.app.Dialog
@@ -37,7 +35,6 @@
 import com.android.systemui.statusbar.policy.ui.dialog.viewmodel.modesDialogViewModel
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt
index 856de8e..bae61bb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.policy.ui.dialog.viewmodel
 
 import android.app.AutomaticZenRule
@@ -41,7 +39,6 @@
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import java.util.Calendar
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
index 73e5004..ebb4697 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
@@ -44,7 +44,6 @@
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.capture
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -56,7 +55,6 @@
 import platform.test.runner.parameterized.Parameters
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(ParameterizedAndroidJunit4::class)
 class KeyguardStatusBarViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
     private val kosmos = testKosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStatePerDisplayRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStatePerDisplayRepositoryTest.kt
index 42ebaf7..a132e4d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStatePerDisplayRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStatePerDisplayRepositoryTest.kt
@@ -31,7 +31,6 @@
 import com.android.systemui.statusbar.window.shared.model.StatusBarWindowState
 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
@@ -40,7 +39,6 @@
 import org.mockito.kotlin.argumentCaptor
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class StatusBarWindowStatePerDisplayRepositoryTest : SysuiTestCase() {
     private val kosmos = testKosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStateRepositoryStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStateRepositoryStoreTest.kt
index e36178c..4734810 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStateRepositoryStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/data/repository/StatusBarWindowStateRepositoryStoreTest.kt
@@ -31,7 +31,6 @@
 import com.android.systemui.testKosmos
 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.junit.runner.RunWith
@@ -40,7 +39,6 @@
 import org.mockito.kotlin.reset
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class StatusBarWindowStateRepositoryStoreTest : SysuiTestCase() {
     private val kosmos = testKosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt
index ea91b7a..fecf1fd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt
@@ -56,7 +56,6 @@
 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.asExecutor
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.StandardTestDispatcher
@@ -75,7 +74,6 @@
 import org.mockito.MockitoAnnotations
 import org.mockito.kotlin.mock
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class DisplaySwitchLatencyTrackerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt
index 665f55b..dfc4d0f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt
@@ -37,7 +37,6 @@
 import com.android.systemui.power.shared.model.ScreenPowerState
 import com.android.systemui.statusbar.LightRevealScrim
 import com.android.systemui.util.animation.data.repository.fakeAnimationStatusRepository
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runTest
@@ -59,7 +58,6 @@
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class FoldLightRevealOverlayAnimationTest : SysuiTestCase() {
     @get:Rule val animatorTestRule = AnimatorTestRule(this)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractorTest.kt
index 12f08a3..872c84d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/domain/interactor/UnfoldTransitionInteractorTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider
 import com.google.common.truth.Truth.assertThat
 import java.util.Locale
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.async
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.test.runCurrent
@@ -34,7 +33,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class UnfoldTransitionInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
index 8a45930..3ca1f5c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
@@ -40,7 +40,6 @@
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.test.runTest
@@ -52,7 +51,6 @@
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class UserRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/UserLogoutInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/UserLogoutInteractorTest.kt
index f70b426..cf01ee1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/UserLogoutInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/UserLogoutInteractorTest.kt
@@ -27,14 +27,12 @@
 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.runBlocking
 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 UserLogoutInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractorTest.kt
index ccbdffa..3eada25 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractorTest.kt
@@ -68,7 +68,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import junit.framework.Assert.assertNotNull
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.test.runCurrent
@@ -87,7 +86,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class UserSwitcherInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
index 99cdf73..5d51c6d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
@@ -47,7 +47,6 @@
 import com.android.systemui.user.domain.interactor.UserSwitcherInteractor
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.toList
@@ -66,7 +65,6 @@
 import org.mockito.Mockito.doAnswer
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class StatusBarUserChipViewModelTest : SysuiTestCase() {
@@ -265,7 +263,7 @@
                     guestUserInteractor = guestUserInteractor,
                     uiEventLogger = uiEventLogger,
                     userRestrictionChecker = mock(),
-                    processWrapper = ProcessWrapperFake()
+                    processWrapper = ProcessWrapperFake(activityManager)
                 )
         )
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
index 917df61..8ff088f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
@@ -51,7 +51,6 @@
 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.toList
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
@@ -66,7 +65,6 @@
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class UserSwitcherViewModelTest : SysuiTestCase() {
@@ -177,7 +175,7 @@
                         guestUserInteractor = guestUserInteractor,
                         uiEventLogger = uiEventLogger,
                         userRestrictionChecker = mock(),
-                        processWrapper = ProcessWrapperFake()
+                        processWrapper = ProcessWrapperFake(activityManager)
                     ),
                 guestUserInteractor = guestUserInteractor,
             )
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
index e2ce50c..9440280 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
@@ -22,7 +22,6 @@
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.Flow
@@ -244,7 +243,6 @@
     }
 }
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ThrottleFlowTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/SettingsProxyExtTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/SettingsProxyExtTest.kt
index e281894..29d2bf9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/SettingsProxyExtTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/SettingsProxyExtTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
 import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -42,7 +41,6 @@
 /** Tests for [SettingsProxyExt]. */
 @RunWith(AndroidJUnit4::class)
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 class SettingsProxyExtTest : SysuiTestCase() {
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/SettingsProxyTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/SettingsProxyTest.kt
index e25bf13..671ef5b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/SettingsProxyTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/SettingsProxyTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceUntilIdle
@@ -45,7 +44,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 @TestableLooper.RunWithLooper
-@OptIn(ExperimentalCoroutinesApi::class)
 class SettingsProxyTest : SysuiTestCase() {
 
     private val testDispatcher = StandardTestDispatcher()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt
index 5787f7d..7b71283 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -194,7 +193,6 @@
                 )
         }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun registerContentObserverForUserAsync_callbackAfterRegister() =
         testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepositoryTestBase.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepositoryTestBase.kt
index 09db96f..8b22717 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepositoryTestBase.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepositoryTestBase.kt
@@ -25,13 +25,11 @@
 import com.android.systemui.user.data.repository.fakeUserRepository
 import com.android.systemui.util.settings.fakeSettings
 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
 
-@OptIn(ExperimentalCoroutinesApi::class)
 abstract class UserAwareSettingsRepositoryTestBase : SysuiTestCase() {
 
     protected val kosmos = testKosmos()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/ui/AnimatedValueTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/ui/AnimatedValueTest.kt
index 6637d5f..80fd015 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/ui/AnimatedValueTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/ui/AnimatedValueTest.kt
@@ -13,8 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.util.ui
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -22,7 +20,6 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/CsdWarningDialogTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/CsdWarningDialogTest.java
index bebf1cf..ac4ef06 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/CsdWarningDialogTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/CsdWarningDialogTest.java
@@ -18,16 +18,13 @@
 
 import static android.media.AudioManager.CSD_WARNING_DOSE_REACHED_1X;
 import static android.media.AudioManager.CSD_WARNING_DOSE_REPEATED_5X;
-
 import static com.google.common.truth.Truth.assertThat;
-
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.content.Intent;
@@ -48,13 +45,12 @@
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
 
-import com.google.common.collect.ImmutableList;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 
@@ -69,8 +65,8 @@
     private CsdWarningDialog mDialog;
     private static final String DISMISS_CSD_NOTIFICATION =
             "com.android.systemui.volume.DISMISS_CSD_NOTIFICATION";
-    private final Optional<ImmutableList<CsdWarningAction>> mEmptyActions =
-            Optional.of(ImmutableList.of());
+    private final Optional<List<CsdWarningAction>> mEmptyActions =
+            Optional.of(Collections.emptyList());
 
     @Before
     public void setup() {
@@ -84,7 +80,7 @@
 
     @Test
     public void create1XCsdDialogAndWait_sendsNotification() {
-        FakeExecutor executor =  new FakeExecutor(new FakeSystemClock());
+        FakeExecutor executor = new FakeExecutor(new FakeSystemClock());
         // instantiate directly instead of via factory; we don't want executor to be @Background
         mDialog = new CsdWarningDialog(CSD_WARNING_DOSE_REACHED_1X, mContext,
                 mAudioManager, mNotificationManager, executor, null,
@@ -102,7 +98,7 @@
 
     @Test
     public void create5XCsdDialogAndWait_willSendNotification() {
-        FakeExecutor executor =  new FakeExecutor(new FakeSystemClock());
+        FakeExecutor executor = new FakeExecutor(new FakeSystemClock());
         mDialog = new CsdWarningDialog(CSD_WARNING_DOSE_REPEATED_5X, mContext,
                 mAudioManager, mNotificationManager, executor, null,
                 mEmptyActions,
@@ -122,7 +118,7 @@
                 .setPackage(mContext.getPackageName());
         mDialog = new CsdWarningDialog(CSD_WARNING_DOSE_REPEATED_5X, mContext,
                 mAudioManager, mNotificationManager, executor, null,
-                Optional.of(ImmutableList.of(new CsdWarningAction("Undo", undoIntent, false))),
+                Optional.of(List.of(new CsdWarningAction("Undo", undoIntent, false))),
                 mFakeBroadcastDispatcher);
 
         when(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC)).thenReturn(25);
@@ -149,7 +145,7 @@
                 .setPackage(mContext.getPackageName());
         mDialog = new CsdWarningDialog(CSD_WARNING_DOSE_REPEATED_5X, mContext,
                 mAudioManager, mNotificationManager, executor, null,
-                Optional.of(ImmutableList.of(new CsdWarningAction("Undo", undoIntent, false))),
+                Optional.of(List.of(new CsdWarningAction("Undo", undoIntent, false))),
                 mFakeBroadcastDispatcher);
         Intent dismissIntent = new Intent(DISMISS_CSD_NOTIFICATION)
                 .setPackage(mContext.getPackageName());
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/VolumeControllerAdapterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/VolumeControllerAdapterTest.kt
index c140364..d61a7da 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/VolumeControllerAdapterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/VolumeControllerAdapterTest.kt
@@ -25,7 +25,6 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
 import com.android.systemui.volume.data.repository.audioRepository
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -36,7 +35,6 @@
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.verify
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class VolumeControllerAdapterTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/VolumeDialogControllerImplTestKt.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/VolumeDialogControllerImplTestKt.kt
index a9c352d..95d6743 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/VolumeDialogControllerImplTestKt.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/VolumeDialogControllerImplTestKt.kt
@@ -53,7 +53,6 @@
 import com.android.systemui.util.time.fakeSystemClock
 import com.android.systemui.volume.data.repository.audioRepository
 import com.android.systemui.volume.domain.interactor.FakeAudioSharingInteractor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -66,7 +65,6 @@
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 @TestableLooper.RunWithLooper
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/data/repository/VolumeDialogRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/data/repository/VolumeDialogRepositoryTest.kt
index dcac85e..2401214 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/data/repository/VolumeDialogRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/data/repository/VolumeDialogRepositoryTest.kt
@@ -23,14 +23,12 @@
 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.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 VolumeDialogRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogVisibilityInteractorTest.kt
index 31d2eb3..d0cabec 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogVisibilityInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogVisibilityInteractorTest.kt
@@ -31,7 +31,6 @@
 import com.google.common.truth.Truth.assertThat
 import kotlin.time.Duration.Companion.days
 import kotlin.time.Duration.Companion.seconds
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -41,7 +40,6 @@
 
 private val dialogTimeoutDuration = 3.seconds
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/ringer/domain/VolumeDialogRingerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/ringer/domain/VolumeDialogRingerInteractorTest.kt
index 12885a8..4ce2e10 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/ringer/domain/VolumeDialogRingerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/ringer/domain/VolumeDialogRingerInteractorTest.kt
@@ -31,12 +31,10 @@
 import com.android.systemui.plugins.fakeVolumeDialogController
 import com.android.systemui.testKosmos
 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)
 @TestableLooper.RunWithLooper
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelTest.kt
index 2dcfdd9..4e8a375 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.util.time.fakeSystemClock
 import com.android.systemui.volume.data.repository.audioSystemRepository
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -41,7 +40,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractorTest.kt
index 0a50722..4ed0d6e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSliderInputEventsInteractorTest.kt
@@ -32,7 +32,6 @@
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
 import kotlin.time.Duration.Companion.seconds
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -41,7 +40,6 @@
 
 private val volumeDialogTimeout = 3.seconds
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSlidersInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSlidersInteractorTest.kt
index 87d782e..de81212 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSlidersInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/sliders/domain/interactor/VolumeDialogSlidersInteractorTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.volume.dialog.sliders.domain.model.VolumeDialogSliderType
 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
@@ -40,7 +39,6 @@
 
 private const val AUDIO_SHARING_STREAM = 99
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioModeInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioModeInteractorTest.kt
index fe34361..6df0184 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioModeInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioModeInteractorTest.kt
@@ -23,7 +23,6 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.volume.data.repository.FakeAudioRepository
 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
@@ -32,7 +31,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class AudioModeInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioOutputInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioOutputInteractorTest.kt
index 7c55f7a..3f1b3a6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioOutputInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioOutputInteractorTest.kt
@@ -38,7 +38,6 @@
 import com.android.systemui.volume.mediaControllerRepository
 import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.TestMediaDevicesFactory
 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
@@ -51,7 +50,6 @@
 
 private const val builtInDeviceName = "This phone"
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorTest.kt
index 09d6ac6..1b4d7d0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorTest.kt
@@ -31,7 +31,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.volume.data.repository.audioSharingRepository
 import com.google.common.truth.Truth
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -40,7 +39,6 @@
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class AudioSharingInteractorTest : SysuiTestCase() {
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 1ea8a6b..35ad3a2 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
@@ -32,14 +32,12 @@
 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
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class AudioVolumeInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/VolumeDialogInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/VolumeDialogInteractorTest.kt
index 5c735e3..784ff9a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/VolumeDialogInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/VolumeDialogInteractorTest.kt
@@ -23,14 +23,12 @@
 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.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 VolumeDialogInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/startable/AudioModeLoggerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/startable/AudioModeLoggerStartableTest.kt
index 89acbc8..bbcbac7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/startable/AudioModeLoggerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/startable/AudioModeLoggerStartableTest.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.volume.domain.interactor.audioModeInteractor
 import com.android.systemui.volume.panel.ui.VolumePanelUiEvent
 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
@@ -39,7 +38,6 @@
 import org.mockito.junit.MockitoJUnit
 import org.mockito.junit.MockitoRule
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class AudioModeLoggerStartableTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/data/repository/AncSliceRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/data/repository/AncSliceRepositoryTest.kt
index 9a95274..3c9e45c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/data/repository/AncSliceRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/data/repository/AncSliceRepositoryTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.volume.panel.component.anc.FakeSliceFactory
 import com.android.systemui.volume.panel.component.anc.sliceViewManager
 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
@@ -38,7 +37,6 @@
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/AncAvailabilityCriteriaTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/AncAvailabilityCriteriaTest.kt
index 8d052fe..1bb23f6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/AncAvailabilityCriteriaTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/AncAvailabilityCriteriaTest.kt
@@ -36,14 +36,12 @@
 import com.android.systemui.volume.panel.component.anc.sliceViewManager
 import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.TestMediaDevicesFactory
 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)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/interactor/AncSliceInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/interactor/AncSliceInteractorTest.kt
index 741671e..b659059 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/interactor/AncSliceInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/anc/domain/interactor/AncSliceInteractorTest.kt
@@ -32,14 +32,12 @@
 import com.android.systemui.volume.panel.component.anc.domain.model.AncSlices
 import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.TestMediaDevicesFactory
 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)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModelTest.kt
index 254a967..9055a11 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/bottombar/ui/viewmodel/BottomBarViewModelTest.kt
@@ -34,7 +34,6 @@
 import com.android.systemui.volume.panel.ui.VolumePanelUiEvent
 import com.android.systemui.volume.panel.ui.viewmodel.volumePanelViewModel
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Rule
@@ -45,7 +44,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class BottomBarViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/captioning/ui/viewmodel/CaptioningViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/captioning/ui/viewmodel/CaptioningViewModelTest.kt
index cb6dc19..7b8dc18 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/captioning/ui/viewmodel/CaptioningViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/captioning/ui/viewmodel/CaptioningViewModelTest.kt
@@ -27,14 +27,12 @@
 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.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 CaptioningViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/MediaOutputAvailabilityCriteriaTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/MediaOutputAvailabilityCriteriaTest.kt
deleted file mode 100644
index d0cc568..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/MediaOutputAvailabilityCriteriaTest.kt
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2025 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF 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.component.mediaoutput.domain
-
-import android.content.mockedContext
-import android.content.packageManager
-import android.content.pm.PackageManager.FEATURE_PC
-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.kosmos.collectLastValue
-import com.android.systemui.kosmos.runTest
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.whenever
-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)
-@TestableLooper.RunWithLooper(setAsMainLooper = true)
-class MediaOutputAvailabilityCriteriaTest : SysuiTestCase() {
-
-    private val kosmos = testKosmos()
-    private val scope = kosmos.testScope
-
-    private lateinit var underTest: MediaOutputAvailabilityCriteria
-
-    @Before
-    fun setup() {
-        with(kosmos) {
-            underTest = MediaOutputAvailabilityCriteria(kosmos.mockedContext, scope.backgroundScope)
-        }
-    }
-
-    @Test
-    fun isDesktop_unavailable() =
-        kosmos.runTest {
-            whenever(mockedContext.getPackageManager()).thenReturn(packageManager)
-            whenever(packageManager.hasSystemFeature(FEATURE_PC)).thenReturn(true)
-
-            val isAvailable by collectLastValue(underTest.isAvailable())
-
-            assertThat(isAvailable).isFalse()
-        }
-
-    @Test
-    fun notIsDesktop_available() =
-        kosmos.runTest {
-            whenever(mockedContext.getPackageManager()).thenReturn(packageManager)
-            whenever(packageManager.hasSystemFeature(FEATURE_PC)).thenReturn(false)
-
-            val isAvailable by collectLastValue(underTest.isAvailable())
-
-            assertThat(isAvailable).isTrue()
-        }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaDeviceSessionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaDeviceSessionInteractorTest.kt
index 46df0c2..3bf112a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaDeviceSessionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaDeviceSessionInteractorTest.kt
@@ -30,14 +30,12 @@
 import com.android.systemui.volume.panel.shared.model.filterData
 import com.android.systemui.volume.remoteMediaController
 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)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorTest.kt
index 449dc20..a2dd1e7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorTest.kt
@@ -41,7 +41,6 @@
 import com.android.systemui.volume.panel.component.mediaoutput.domain.model.MediaOutputComponentModel
 import com.android.systemui.volume.panel.shared.model.filterData
 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
@@ -51,7 +50,6 @@
 
 private const val builtInDeviceName = "This phone"
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputInteractorTest.kt
index 9e86ced..dacf4d4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputInteractorTest.kt
@@ -42,14 +42,12 @@
 import com.android.systemui.volume.remotePlaybackInfo
 import com.android.systemui.volume.remotePlaybackStateBuilder
 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)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt
index 86a20dc..6753ccb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt
@@ -37,14 +37,12 @@
 import com.android.systemui.volume.mediaOutputActionsInteractor
 import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.mediaOutputComponentInteractor
 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)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
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 ebc78d8..4aaecab 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
@@ -41,14 +41,12 @@
 import com.android.systemui.volume.mediaControllerRepository
 import com.android.systemui.volume.panel.component.spatial.spatialAudioComponentInteractor
 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)
 @RunWithLooper(setAsMainLooper = true)
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 d5566ad..691d5e3 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
@@ -48,7 +48,6 @@
 import com.android.systemui.volume.panel.component.spatial.domain.model.SpatialAudioEnabledModel
 import com.android.systemui.volume.panel.component.spatial.spatialAudioComponentInteractor
 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
@@ -56,7 +55,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorTest.kt
index 76a1269..5a814fc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorTest.kt
@@ -32,14 +32,12 @@
 import com.android.systemui.volume.data.repository.audioSystemRepository
 import com.android.systemui.volume.panel.component.volume.domain.model.SliderType
 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)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelTest.kt
index b34d7b8..e484d80 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelTest.kt
@@ -31,7 +31,6 @@
 import com.android.systemui.volume.data.repository.audioSharingRepository
 import com.android.systemui.volume.domain.interactor.audioSharingInteractor
 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
@@ -39,7 +38,6 @@
 import org.junit.runner.RunWith
 import org.mockito.kotlin.mock
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AudioSharingStreamSliderViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelTest.kt
index fe6c741..25eb319 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelTest.kt
@@ -47,7 +47,6 @@
 import java.io.PrintWriter
 import java.io.StringWriter
 import javax.inject.Provider
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -56,7 +55,6 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class VolumePanelViewModelTest : SysuiTestCase() {
 
     private val kosmos =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/ui/navigation/VolumeNavigatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/ui/navigation/VolumeNavigatorTest.kt
index 7934b02..dbd50a6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/ui/navigation/VolumeNavigatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/ui/navigation/VolumeNavigatorTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.volume.panel.domain.interactor.volumePanelGlobalStateInteractor
 import com.android.systemui.volume.panel.ui.viewmodel.volumePanelViewModelFactory
 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
@@ -41,7 +40,6 @@
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class VolumeNavigatorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallet/controller/WalletContextualLocationsServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallet/controller/WalletContextualLocationsServiceTest.kt
index 6f99cd9..eaf42ac 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallet/controller/WalletContextualLocationsServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallet/controller/WalletContextualLocationsServiceTest.kt
@@ -33,7 +33,6 @@
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 class WalletContextualLocationsServiceTest : SysuiTestCase() {
     @Mock private lateinit var controller: WalletContextualSuggestionsController
     private var featureFlags = FakeFeatureFlags()
@@ -49,7 +48,6 @@
         }
 
     @Before
-    @kotlinx.coroutines.ExperimentalCoroutinesApi
     fun setUp() {
         MockitoAnnotations.initMocks(this)
         doReturn(fakeWalletCards).whenever(controller).allWalletCards
@@ -70,7 +68,6 @@
     }
 
     @Test
-    @kotlinx.coroutines.ExperimentalCoroutinesApi
     fun addListener() =
         testScope.runTest {
             underTest.addWalletCardsUpdatedListenerInternal(listener)
@@ -78,7 +75,6 @@
         }
 
     @Test
-    @kotlinx.coroutines.ExperimentalCoroutinesApi
     fun addStoreLocations() =
         testScope.runTest {
             underTest.onWalletContextualLocationsStateUpdatedInternal(ArrayList<String>())
@@ -86,7 +82,6 @@
         }
 
     @Test
-    @kotlinx.coroutines.ExperimentalCoroutinesApi
     fun updateListenerAndLocationsState() =
         testScope.runTest {
             // binds to the service and adds a listener
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallet/controller/WalletContextualSuggestionsControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallet/controller/WalletContextualSuggestionsControllerTest.kt
index 4e44c4a..e5d7f59 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallet/controller/WalletContextualSuggestionsControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallet/controller/WalletContextualSuggestionsControllerTest.kt
@@ -37,7 +37,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -51,7 +50,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class WalletContextualSuggestionsControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt
index 115edd0..1f5e7ca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt
@@ -25,18 +25,16 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.R
-import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.keyguard.data.repository.FakeKeyguardClockRepository
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.res.R as SysUIR
 import com.android.systemui.shared.Flags as SharedFlags
 import com.android.systemui.user.data.model.SelectedUserModel
 import com.android.systemui.user.data.model.SelectionStatus
 import com.android.systemui.user.data.repository.FakeUserRepository
-import com.android.systemui.wallpapers.data.repository.WallpaperRepositoryImpl.Companion.MAGIC_PORTRAIT_CLASSNAME
 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
@@ -49,7 +47,6 @@
 import org.mockito.kotlin.whenever
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidJUnit4::class)
 class WallpaperRepositoryImplTest : SysuiTestCase() {
 
@@ -72,9 +69,12 @@
         )
     }
 
+    lateinit var focalAreaTarget: String
+
     @Before
     fun setUp() {
         whenever(wallpaperManager.isWallpaperSupported).thenReturn(true)
+        focalAreaTarget = context.resources.getString(SysUIR.string.focal_area_target)
     }
 
     @Test
@@ -248,17 +248,17 @@
         }
 
     @Test
-    @EnableFlags(Flags.FLAG_MAGIC_PORTRAIT_WALLPAPERS)
-    fun shouldSendNotificationLayout_setMagicPortraitWallpaper_launchSendLayoutJob() =
+    @EnableFlags(SharedFlags.FLAG_EXTENDED_WALLPAPER_EFFECTS)
+    fun shouldSendNotificationLayout_setExtendedEffectsWallpaper_launchSendLayoutJob() =
         testScope.runTest {
             val latest by collectLastValue(underTest.shouldSendFocalArea)
-            val magicPortraitWallpaper =
+            val extedendEffectsWallpaper =
                 mock<WallpaperInfo>().apply {
-                    whenever(this.component)
-                        .thenReturn(ComponentName(context, MAGIC_PORTRAIT_CLASSNAME))
+                    whenever(this.component).thenReturn(ComponentName(context, focalAreaTarget))
                 }
+
             whenever(wallpaperManager.getWallpaperInfoForUser(any()))
-                .thenReturn(magicPortraitWallpaper)
+                .thenReturn(extedendEffectsWallpaper)
             fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
                 context,
                 Intent(Intent.ACTION_WALLPAPER_CHANGED),
@@ -269,13 +269,16 @@
         }
 
     @Test
-    @EnableFlags(Flags.FLAG_MAGIC_PORTRAIT_WALLPAPERS)
-    fun shouldSendNotificationLayout_setNotMagicPortraitWallpaper_cancelSendLayoutJob() =
+    @EnableFlags(SharedFlags.FLAG_EXTENDED_WALLPAPER_EFFECTS)
+    fun shouldSendNotificationLayout_setNotExtendedEffectsWallpaper_cancelSendLayoutJob() =
         testScope.runTest {
             val latest by collectLastValue(underTest.shouldSendFocalArea)
-            val magicPortraitWallpaper = MAGIC_PORTRAIT_WP
+            val extendedEffectsWallpaper =
+                mock<WallpaperInfo>().apply {
+                    whenever(this.component).thenReturn(ComponentName("", focalAreaTarget))
+                }
             whenever(wallpaperManager.getWallpaperInfoForUser(any()))
-                .thenReturn(magicPortraitWallpaper)
+                .thenReturn(extendedEffectsWallpaper)
             fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
                 context,
                 Intent(Intent.ACTION_WALLPAPER_CHANGED),
@@ -284,9 +287,7 @@
             assertThat(underTest.sendLockscreenLayoutJob).isNotNull()
             assertThat(underTest.sendLockscreenLayoutJob!!.isActive).isEqualTo(true)
 
-            val nonMagicPortraitWallpaper = UNSUPPORTED_WP
-            whenever(wallpaperManager.getWallpaperInfoForUser(any()))
-                .thenReturn(nonMagicPortraitWallpaper)
+            whenever(wallpaperManager.getWallpaperInfoForUser(any())).thenReturn(UNSUPPORTED_WP)
             fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
                 context,
                 Intent(Intent.ACTION_WALLPAPER_CHANGED),
@@ -303,10 +304,5 @@
         val USER_WITH_SUPPORTED_WP = UserInfo(/* id= */ 4, /* name= */ "user4", /* flags= */ 0)
         val SUPPORTED_WP =
             mock<WallpaperInfo>().apply { whenever(this.supportsAmbientMode()).thenReturn(true) }
-
-        val MAGIC_PORTRAIT_WP =
-            mock<WallpaperInfo>().apply {
-                whenever(this.component).thenReturn(ComponentName("", MAGIC_PORTRAIT_CLASSNAME))
-            }
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractorTest.kt
index bc16bec..79edc22 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractorTest.kt
@@ -24,12 +24,10 @@
 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.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class WindowRootViewBlurInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelTest.kt
index b97fe57..3c4e361 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelTest.kt
@@ -24,14 +24,12 @@
 import com.android.systemui.lifecycle.activateIn
 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.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class WindowRootViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/TestableBubbleController.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/TestableBubbleController.java
index 75c1742..ab6fbc3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/TestableBubbleController.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/TestableBubbleController.java
@@ -30,7 +30,7 @@
 import com.android.wm.shell.bubbles.BubbleDataRepository;
 import com.android.wm.shell.bubbles.BubbleLogger;
 import com.android.wm.shell.bubbles.BubblePositioner;
-import com.android.wm.shell.bubbles.properties.BubbleProperties;
+import com.android.wm.shell.bubbles.ResizabilityChecker;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayImeController;
 import com.android.wm.shell.common.DisplayInsetsController;
@@ -82,14 +82,14 @@
             Transitions transitions,
             SyncTransactionQueue syncQueue,
             IWindowManager wmService,
-            BubbleProperties bubbleProperties) {
+            ResizabilityChecker resizabilityChecker) {
         super(context, shellInit, shellCommandHandler, shellController, data, Runnable::run,
                 floatingContentCoordinator, dataRepository, statusBarService, windowManager,
                 displayInsetsController, displayImeController, userManager, launcherApps,
                 bubbleLogger, taskStackListener, shellTaskOrganizer, positioner, displayController,
                 oneHandedOptional, dragAndDropController, shellMainExecutor, shellMainHandler,
                 new SyncExecutor(), taskViewRepository, taskViewTransitions, transitions,
-                syncQueue, wmService, bubbleProperties);
+                syncQueue, wmService, resizabilityChecker);
         setInflateSynchronously(true);
         onInit();
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/WMShellTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/WMShellTest.kt
index 6113657..f362d80 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/WMShellTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/WMShellTest.kt
@@ -65,7 +65,6 @@
 import com.android.wm.shell.sysui.ShellInterface
 import java.util.Optional
 import java.util.concurrent.Executor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -82,7 +81,6 @@
  *
  * Build/Install/Run: atest SystemUITests:WMShellTest
  */
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class WMShellTest : SysuiTestCase() {
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 ca98cbf..18891db 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
@@ -25,6 +25,8 @@
 import com.android.systemui.animation.ActivityTransitionAnimator;
 import com.android.systemui.plugins.annotations.ProvidesInterface;
 
+import kotlinx.coroutines.CoroutineScope;
+
 /**
  * An interface to start activities. This is used as a callback from the views to
  * {@link PhoneStatusBar} to allow custom handling for starting the activity, i.e. dismissing the
@@ -37,11 +39,12 @@
     /**
      * Registers the given {@link ActivityTransitionAnimator.ControllerFactory} for launching and
      * closing transitions matching the {@link ActivityTransitionAnimator.TransitionCookie} and the
-     * {@link ComponentName} that it contains.
+     * {@link ComponentName} that it contains, within the given {@link CoroutineScope}.
      */
     void registerTransition(
             ActivityTransitionAnimator.TransitionCookie cookie,
-            ActivityTransitionAnimator.ControllerFactory controllerFactory);
+            ActivityTransitionAnimator.ControllerFactory controllerFactory,
+            CoroutineScope scope);
 
     /**
      * Unregisters the {@link ActivityTransitionAnimator.ControllerFactory} previously registered
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt
index 1bc9367..6e4dc14 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt
@@ -62,12 +62,11 @@
     fun toSetting() = ClockFontAxisSetting(key, currentValue)
 
     companion object {
-        fun merge(
-            fontAxes: List<ClockFontAxis>,
-            axisSettings: List<ClockFontAxisSetting>,
+        fun List<ClockFontAxis>.merge(
+            axisSettings: List<ClockFontAxisSetting>
         ): List<ClockFontAxis> {
             val result = mutableListOf<ClockFontAxis>()
-            for (axis in fontAxes) {
+            for (axis in this) {
                 val setting = axisSettings.firstOrNull { axis.key == it.key }
                 val output = setting?.let { axis.copy(currentValue = it.value) } ?: axis
                 result.add(output)
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt
index 6128c00..e7b3662 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt
@@ -98,13 +98,20 @@
             return result
         }
 
-        fun toFVar(settings: List<ClockFontAxisSetting>): String {
+        fun List<ClockFontAxisSetting>.toFVar(): String {
             val sb = StringBuilder()
-            for (axis in settings) {
+            for (axis in this) {
                 if (sb.length > 0) sb.append(", ")
                 sb.append("'${axis.key}' ${axis.value.toInt()}")
             }
             return sb.toString()
         }
+
+        fun List<ClockFontAxisSetting>.replace(
+            replacements: List<ClockFontAxisSetting>
+        ): List<ClockFontAxisSetting> {
+            var remaining = this.filterNot { lhs -> replacements.any { rhs -> lhs.key == rhs.key } }
+            return remaining + replacements
+        }
     }
 }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/TileDetailsViewModel.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/TileDetailsViewModel.kt
index eab7d79..be0362f 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/TileDetailsViewModel.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/TileDetailsViewModel.kt
@@ -16,17 +16,10 @@
 
 package com.android.systemui.plugins.qs
 
-import androidx.compose.runtime.Composable
-
 /**
  * The base view model class for rendering the Tile's TileDetailsView.
  */
 abstract class TileDetailsViewModel {
-
-    // The view content of this tile details view.
-    @Composable
-    abstract fun GetContentView()
-
     // The callback when the settings button is clicked. Currently this is the same as the on tile
     // long press callback
     abstract fun clickOnSettingsButton()
diff --git a/packages/SystemUI/pods/com/android/systemui/util/settings/UserSettingsProxy.kt b/packages/SystemUI/pods/com/android/systemui/util/settings/UserSettingsProxy.kt
index 1a55170..68ad11e 100644
--- a/packages/SystemUI/pods/com/android/systemui/util/settings/UserSettingsProxy.kt
+++ b/packages/SystemUI/pods/com/android/systemui/util/settings/UserSettingsProxy.kt
@@ -157,7 +157,11 @@
         userHandle: Int,
     ) =
         settingsScope.launch("registerContentObserverForUserAsync-A") {
-            registerContentObserverForUserSync(getUriFor(name), settingsObserver, userHandle)
+            try {
+                registerContentObserverForUserSync(getUriFor(name), settingsObserver, userHandle)
+            } catch (e: SecurityException) {
+                throw SecurityException("registerContentObserverForUserAsync-A, name: $name", e)
+            }
         }
 
     /** Convenience wrapper around [ContentResolver.registerContentObserver] */
@@ -198,7 +202,11 @@
         userHandle: Int,
     ) =
         settingsScope.launch("registerContentObserverForUserAsync-B") {
-            registerContentObserverForUserSync(uri, settingsObserver, userHandle)
+            try {
+                registerContentObserverForUserSync(uri, settingsObserver, userHandle)
+            } catch (e: SecurityException) {
+                throw SecurityException("registerContentObserverForUserAsync-B, uri: $uri", e)
+            }
         }
 
     /**
@@ -215,7 +223,11 @@
         @WorkerThread registered: Runnable,
     ) =
         settingsScope.launch("registerContentObserverForUserAsync-C") {
-            registerContentObserverForUserSync(uri, settingsObserver, userHandle)
+            try {
+                registerContentObserverForUserSync(uri, settingsObserver, userHandle)
+            } catch (e: SecurityException) {
+                throw SecurityException("registerContentObserverForUserAsync-C, uri: $uri", e)
+            }
             registered.run()
         }
 
@@ -274,12 +286,16 @@
         userHandle: Int,
     ) {
         settingsScope.launch("registerContentObserverForUserAsync-D") {
-            registerContentObserverForUserSync(
-                getUriFor(name),
-                notifyForDescendants,
-                settingsObserver,
-                userHandle,
-            )
+            try {
+                registerContentObserverForUserSync(
+                    getUriFor(name),
+                    notifyForDescendants,
+                    settingsObserver,
+                    userHandle,
+                )
+            } catch (e: SecurityException) {
+                throw SecurityException("registerContentObserverForUserAsync-D, name: $name", e)
+            }
         }
     }
 
@@ -338,12 +354,16 @@
         userHandle: Int,
     ) =
         settingsScope.launch("registerContentObserverForUserAsync-E") {
-            registerContentObserverForUserSync(
-                uri,
-                notifyForDescendants,
-                settingsObserver,
-                userHandle,
-            )
+            try {
+                registerContentObserverForUserSync(
+                    uri,
+                    notifyForDescendants,
+                    settingsObserver,
+                    userHandle,
+                )
+            } catch (e: SecurityException) {
+                throw SecurityException("registerContentObserverForUserAsync-E, uri: $uri", e)
+            }
         }
 
     /**
diff --git a/packages/SystemUI/res/drawable/notif_footer_btn_settings.xml b/packages/SystemUI/res/drawable/notif_footer_btn_settings.xml
index 800060d..6533460 100644
--- a/packages/SystemUI/res/drawable/notif_footer_btn_settings.xml
+++ b/packages/SystemUI/res/drawable/notif_footer_btn_settings.xml
@@ -6,5 +6,5 @@
     android:tint="?attr/colorControlNormal">
   <path
       android:fillColor="@android:color/white"
-      android:pathData="M370,880L354,752Q341,747 329.5,740Q318,733 307,725L188,775L78,585L181,507Q180,500 180,493.5Q180,487 180,480Q180,473 180,466.5Q180,460 181,453L78,375L188,185L307,235Q318,227 330,220Q342,213 354,208L370,80L590,80L606,208Q619,213 630.5,220Q642,227 653,235L772,185L882,375L779,453Q780,460 780,466.5Q780,473 780,480Q780,487 780,493.5Q780,500 778,507L881,585L771,775L653,725Q642,733 630,740Q618,747 606,752L590,880L370,880ZM440,800L519,800L533,694Q564,686 590.5,670.5Q617,655 639,633L738,674L777,606L691,541Q696,527 698,511.5Q700,496 700,480Q700,464 698,448.5Q696,433 691,419L777,354L738,286L639,328Q617,305 590.5,289.5Q564,274 533,266L520,160L441,160L427,266Q396,274 369.5,289.5Q343,305 321,327L222,286L183,354L269,418Q264,433 262,448Q260,463 260,480Q260,496 262,511Q264,526 269,541L183,606L222,674L321,632Q343,655 369.5,670.5Q396,686 427,694L440,800ZM482,620Q540,620 581,579Q622,538 622,480Q622,422 581,381Q540,340 482,340Q423,340 382.5,381Q342,422 342,480Q342,538 382.5,579Q423,620 482,620ZM480,480L480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Z"/>
+      android:pathData="M480,864q-30,0 -51,-21t-21,-51h144q0,30 -21,51t-51,21ZM192,744v-72h48v-240q0,-88 55.5,-155T439,196q-5,17 -7,34t-2,34q0,59 23.5,109.5T517,461q40,37 92,56t111,14v141h48v72L192,744ZM664,456 L652,400q-14,-5 -26.5,-11.5T602,372l-55,17 -32,-55 41,-40q-3,-14 -3,-29t3,-29l-41,-39 32,-56 54,16q11,-11 24,-18t27,-11l13,-56h64l13,56q14,5 27.5,11.5T793,157l54,-15 32,55 -40,38q3,14 2.5,29.5T838,294l41,39 -32,55 -55,-16q-11,10 -23.5,16.5T742,400l-14,56h-64ZM697,336q30,0 51,-21t21,-51q0,-30 -21,-51t-51,-21q-30,0 -51,21t-21,51q0,30 21,51t51,21Z"/>
 </vector>
diff --git a/packages/SystemUI/res/layout/bundle_notification_info.xml b/packages/SystemUI/res/layout/bundle_notification_info.xml
deleted file mode 100644
index 745066a..0000000
--- a/packages/SystemUI/res/layout/bundle_notification_info.xml
+++ /dev/null
@@ -1,366 +0,0 @@
-<?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.
--->
-
-<com.android.systemui.statusbar.notification.row.BundleNotificationInfo
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-    android:id="@+id/notification_guts"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:focusable="true"
-    android:clipChildren="false"
-    android:clipToPadding="true"
-    android:orientation="vertical"
-    android:paddingStart="@dimen/notification_shade_content_margin_horizontal">
-
-    <!-- Package Info -->
-    <LinearLayout
-        android:id="@+id/header"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center_vertical"
-        android:clipChildren="false"
-        android:paddingTop="@dimen/notification_guts_header_top_padding"
-        android:clipToPadding="true">
-        <ImageView
-            android:id="@+id/pkg_icon"
-            android:layout_width="@dimen/notification_guts_conversation_icon_size"
-            android:layout_height="@dimen/notification_guts_conversation_icon_size"
-            android:layout_centerVertical="true"
-            android:layout_alignParentStart="true"
-            android:layout_marginEnd="15dp" />
-        <LinearLayout
-            android:id="@+id/names"
-            android:layout_weight="1"
-            android:layout_width="0dp"
-            android:orientation="vertical"
-            android:layout_height="wrap_content"
-            android:minHeight="@dimen/notification_guts_conversation_icon_size"
-            android:layout_centerVertical="true"
-            android:gravity="center_vertical"
-            android:layout_alignEnd="@id/pkg_icon"
-            android:layout_toEndOf="@id/pkg_icon">
-            <TextView
-                android:id="@+id/channel_name"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:textDirection="locale"
-                style="@style/TextAppearance.NotificationImportanceChannel"/>
-            <TextView
-                android:id="@+id/group_name"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:textDirection="locale"
-                android:ellipsize="end"
-                style="@style/TextAppearance.NotificationImportanceChannelGroup"/>
-            <TextView
-                android:id="@+id/pkg_name"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                style="@style/TextAppearance.NotificationImportanceApp"
-                android:ellipsize="end"
-                android:textDirection="locale"
-                android:maxLines="1"/>
-            <TextView
-                android:id="@+id/delegate_name"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_centerVertical="true"
-                style="@style/TextAppearance.NotificationImportanceHeader"
-                android:layout_marginStart="2dp"
-                android:layout_marginEnd="2dp"
-                android:ellipsize="end"
-                android:textDirection="locale"
-                android:text="@string/notification_delegate_header"
-                android:maxLines="1" />
-
-        </LinearLayout>
-
-        <!-- end aligned fields -->
-        <!-- Optional link to app. Only appears if the channel is not disabled and the app
-asked for it -->
-        <ImageButton
-            android:id="@+id/app_settings"
-            android:layout_width="@dimen/notification_importance_toggle_size"
-            android:layout_height="@dimen/notification_importance_toggle_size"
-            android:layout_centerVertical="true"
-            android:visibility="gone"
-            android:background="@drawable/ripple_drawable"
-            android:contentDescription="@string/notification_app_settings"
-            android:src="@drawable/ic_info"
-            android:layout_toStartOf="@id/info"
-            android:tint="@androidprv:color/materialColorPrimary"/>
-        <ImageButton
-            android:id="@+id/info"
-            android:layout_width="@dimen/notification_importance_toggle_size"
-            android:layout_height="@dimen/notification_importance_toggle_size"
-            android:layout_centerVertical="true"
-            android:contentDescription="@string/notification_more_settings"
-            android:background="@drawable/ripple_drawable_20dp"
-            android:src="@drawable/ic_settings"
-            android:tint="@androidprv:color/materialColorPrimary"
-            android:layout_alignParentEnd="true" />
-
-    </LinearLayout>
-
-    <LinearLayout
-        android:id="@+id/inline_controls"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingEnd="@dimen/notification_shade_content_margin_horizontal"
-        android:layout_marginTop="@dimen/notification_guts_option_vertical_padding"
-        android:clipChildren="false"
-        android:clipToPadding="false"
-        android:orientation="vertical">
-
-        <!-- Non configurable app/channel text. appears instead of @+id/interruptiveness_settings-->
-        <TextView
-            android:id="@+id/non_configurable_text"
-            android:text="@string/notification_unblockable_desc"
-            android:visibility="gone"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            style="@*android:style/TextAppearance.DeviceDefault.Notification" />
-
-        <!-- Non configurable app/channel text. appears instead of @+id/interruptiveness_settings-->
-        <TextView
-            android:id="@+id/non_configurable_call_text"
-            android:text="@string/notification_unblockable_call_desc"
-            android:visibility="gone"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            style="@*android:style/TextAppearance.DeviceDefault.Notification" />
-
-        <!-- Non configurable multichannel text. appears instead of @+id/interruptiveness_settings-->
-        <TextView
-            android:id="@+id/non_configurable_multichannel_text"
-            android:text="@string/notification_multichannel_desc"
-            android:visibility="gone"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            style="@*android:style/TextAppearance.DeviceDefault.Notification" />
-
-        <LinearLayout
-            android:id="@+id/interruptiveness_settings"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            android:orientation="vertical">
-            <com.android.systemui.statusbar.notification.row.ButtonLinearLayout
-                android:id="@+id/automatic"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginBottom="@dimen/notification_importance_button_separation"
-                android:padding="@dimen/notification_importance_button_padding"
-                android:clickable="true"
-                android:focusable="true"
-                android:background="@drawable/notification_guts_priority_button_bg"
-                android:orientation="vertical"
-                android:visibility="gone">
-                <LinearLayout
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:orientation="horizontal"
-                    android:gravity="center"
-                    >
-                    <ImageView
-                        android:id="@+id/automatic_icon"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:src="@drawable/ic_notifications_automatic"
-                        android:background="@android:color/transparent"
-                        android:tint="@color/notification_guts_priority_contents"
-                        android:clickable="false"
-                        android:focusable="false"/>
-                    <TextView
-                        android:id="@+id/automatic_label"
-                        android:layout_width="0dp"
-                        android:layout_height="wrap_content"
-                        android:layout_marginStart="@dimen/notification_importance_drawable_padding"
-                        android:layout_weight="1"
-                        android:ellipsize="end"
-                        android:maxLines="1"
-                        android:clickable="false"
-                        android:focusable="false"
-                        android:textAppearance="@style/TextAppearance.NotificationImportanceButton"
-                        android:text="@string/notification_automatic_title"/>
-                </LinearLayout>
-                <TextView
-                    android:id="@+id/automatic_summary"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="@dimen/notification_importance_button_description_top_margin"
-                    android:visibility="gone"
-                    android:text="@string/notification_channel_summary_automatic"
-                    android:clickable="false"
-                    android:focusable="false"
-                    android:ellipsize="end"
-                    android:maxLines="2"
-                    android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"/>
-            </com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
-
-            <com.android.systemui.statusbar.notification.row.ButtonLinearLayout
-                android:id="@+id/alert"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:padding="@dimen/notification_importance_button_padding"
-                android:clickable="true"
-                android:focusable="true"
-                android:background="@drawable/notification_guts_priority_button_bg"
-                android:orientation="vertical">
-                <LinearLayout
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:orientation="horizontal"
-                    android:gravity="center"
-                    >
-                    <ImageView
-                        android:id="@+id/alert_icon"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:src="@drawable/ic_notifications_alert"
-                        android:background="@android:color/transparent"
-                        android:tint="@color/notification_guts_priority_contents"
-                        android:clickable="false"
-                        android:focusable="false"/>
-                    <TextView
-                        android:id="@+id/alert_label"
-                        android:layout_width="0dp"
-                        android:layout_height="wrap_content"
-                        android:layout_marginStart="@dimen/notification_importance_drawable_padding"
-                        android:layout_weight="1"
-                        android:ellipsize="end"
-                        android:maxLines="1"
-                        android:clickable="false"
-                        android:focusable="false"
-                        android:textAppearance="@style/TextAppearance.NotificationImportanceButton"
-                        android:text="@string/notification_alert_title"/>
-                </LinearLayout>
-                <TextView
-                    android:id="@+id/alert_summary"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="@dimen/notification_importance_button_description_top_margin"
-                    android:visibility="gone"
-                    android:text="@string/notification_channel_summary_default"
-                    android:clickable="false"
-                    android:focusable="false"
-                    android:ellipsize="end"
-                    android:maxLines="2"
-                    android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"/>
-            </com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
-
-            <com.android.systemui.statusbar.notification.row.ButtonLinearLayout
-                android:id="@+id/silence"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/notification_importance_button_separation"
-                android:padding="@dimen/notification_importance_button_padding"
-                android:clickable="true"
-                android:focusable="true"
-                android:background="@drawable/notification_guts_priority_button_bg"
-                android:orientation="vertical">
-                <LinearLayout
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:orientation="horizontal"
-                    android:gravity="center"
-                    >
-                    <ImageView
-                        android:id="@+id/silence_icon"
-                        android:src="@drawable/ic_notifications_silence"
-                        android:background="@android:color/transparent"
-                        android:tint="@color/notification_guts_priority_contents"
-                        android:layout_gravity="center"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:clickable="false"
-                        android:focusable="false"/>
-                    <TextView
-                        android:id="@+id/silence_label"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:ellipsize="end"
-                        android:maxLines="1"
-                        android:clickable="false"
-                        android:focusable="false"
-                        android:layout_toEndOf="@id/silence_icon"
-                        android:layout_marginStart="@dimen/notification_importance_drawable_padding"
-                        android:textAppearance="@style/TextAppearance.NotificationImportanceButton"
-                        android:text="@string/notification_silence_title"/>
-                </LinearLayout>
-                <TextView
-                    android:id="@+id/silence_summary"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="@dimen/notification_importance_button_description_top_margin"
-                    android:visibility="gone"
-                    android:text="@string/notification_channel_summary_low"
-                    android:clickable="false"
-                    android:focusable="false"
-                    android:ellipsize="end"
-                    android:maxLines="2"
-                    android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"/>
-            </com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
-
-        </LinearLayout>
-
-        <TextView
-            android:id="@+id/notification_guts_bundle_feedback"
-            android:text="@string/notification_guts_bundle_feedback"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="start|center_vertical"
-            android:minWidth="@dimen/notification_guts_bundle_feedback_size"
-            android:minHeight="@dimen/notification_guts_bundle_feedback_size"
-            android:maxWidth="200dp"
-            style="@style/TextAppearance.NotificationInfo.Button"/>
-
-        <RelativeLayout
-            android:id="@+id/bottom_buttons"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:minHeight="60dp"
-            android:gravity="center_vertical"
-            android:paddingStart="4dp"
-            android:paddingEnd="4dp"
-            >
-            <TextView
-                android:id="@+id/turn_off_notifications"
-                android:text="@string/inline_turn_off_notifications"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentStart="true"
-                android:gravity="start|center_vertical"
-                android:minWidth="@dimen/notification_importance_toggle_size"
-                android:minHeight="@dimen/notification_importance_toggle_size"
-                android:maxWidth="200dp"
-                style="@style/TextAppearance.NotificationInfo.Button"/>
-            <TextView
-                android:id="@+id/done"
-                android:text="@string/inline_ok_button"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentEnd="true"
-                android:gravity="end|center_vertical"
-                android:minWidth="@dimen/notification_importance_toggle_size"
-                android:minHeight="@dimen/notification_importance_toggle_size"
-                android:maxWidth="125dp"
-                style="@style/TextAppearance.NotificationInfo.Button"/>
-        </RelativeLayout>
-    </LinearLayout>
-</com.android.systemui.statusbar.notification.row.BundleNotificationInfo>
diff --git a/packages/SystemUI/res/layout/media_output_list_group_divider.xml b/packages/SystemUI/res/layout/media_output_list_group_divider.xml
index 5e96866..c351912 100644
--- a/packages/SystemUI/res/layout/media_output_list_group_divider.xml
+++ b/packages/SystemUI/res/layout/media_output_list_group_divider.xml
@@ -26,7 +26,7 @@
         android:layout_width="wrap_content"
         android:layout_height="36dp"
         android:layout_gravity="center_vertical|start"
-        android:layout_marginStart="16dp"
+        android:layout_marginStart="@dimen/media_output_dialog_margin_horizontal"
         android:layout_marginEnd="56dp"
         android:ellipsize="end"
         android:maxLines="1"
diff --git a/packages/SystemUI/res/layout/media_output_list_item_advanced.xml b/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
index 69117cf..d297ec4 100644
--- a/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
+++ b/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
@@ -15,18 +15,19 @@
   ~ limitations under the License.
   -->
 
-<FrameLayout
+<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:layout_height="wrap_content"
+    android:paddingHorizontal="@dimen/media_output_dialog_margin_horizontal"
+    android:baselineAligned="false">
     <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="64dp"
+        android:layout_weight="1"
+        android:layout_width="0dp"
+        android:layout_height="@dimen/media_output_dialog_item_height"
         android:id="@+id/item_layout"
         android:background="@drawable/media_output_item_background"
-        android:layout_marginStart="16dp"
-        android:layout_marginEnd="80dp"
         android:layout_marginBottom="12dp">
         <FrameLayout
             android:layout_width="match_parent"
@@ -36,7 +37,7 @@
                 android:id="@+id/volume_seekbar"
                 android:splitTrack="false"
                 android:visibility="gone"
-                android:paddingStart="64dp"
+                android:paddingStart="@dimen/media_output_dialog_item_height"
                 android:paddingEnd="0dp"
                 android:background="@null"
                 android:contentDescription="@string/media_output_dialog_accessibility_seekbar"
@@ -48,8 +49,8 @@
 
         <FrameLayout
             android:id="@+id/icon_area"
-            android:layout_width="64dp"
-            android:layout_height="64dp"
+            android:layout_width="@dimen/media_output_dialog_item_height"
+            android:layout_height="@dimen/media_output_dialog_item_height"
             android:focusable="false"
             android:importantForAccessibility="no"
             android:layout_gravity="center_vertical|start">
@@ -131,11 +132,11 @@
     </FrameLayout>
     <FrameLayout
         android:id="@+id/end_action_area"
-        android:layout_width="64dp"
-        android:layout_height="64dp"
+        android:layout_width="@dimen/media_output_dialog_item_height"
+        android:layout_height="@dimen/media_output_dialog_item_height"
         android:visibility="gone"
         android:layout_marginBottom="6dp"
-        android:layout_marginEnd="8dp"
+        android:layout_marginStart="7dp"
         android:layout_gravity="end|center"
         android:gravity="center"
         android:background="@drawable/media_output_item_background_active">
@@ -160,4 +161,4 @@
             android:indeterminateOnly="true"
             android:visibility="gone"/>
     </FrameLayout>
-</FrameLayout>
\ No newline at end of file
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/notification_conversation_info.xml b/packages/SystemUI/res/layout/notification_conversation_info.xml
index cb9d8115d..9560be0 100644
--- a/packages/SystemUI/res/layout/notification_conversation_info.xml
+++ b/packages/SystemUI/res/layout/notification_conversation_info.xml
@@ -167,6 +167,17 @@
 
         <!-- end aligned fields -->
         <ImageButton
+            android:id="@+id/feedback"
+            android:layout_width="@dimen/notification_importance_toggle_size"
+            android:layout_height="@dimen/notification_importance_toggle_size"
+            android:layout_centerVertical="true"
+            android:visibility="gone"
+            android:background="@drawable/ripple_drawable"
+            android:contentDescription="@string/notification_guts_bundle_feedback"
+            android:src="@*android:drawable/ic_feedback"
+            android:layout_alignParentEnd="true"
+            android:tint="@androidprv:color/materialColorPrimary"/>
+        <ImageButton
             android:id="@+id/info"
             android:layout_width="@dimen/notification_importance_toggle_size"
             android:layout_height="@dimen/notification_importance_toggle_size"
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index edca7e3..089ceae 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -91,6 +91,18 @@
         </LinearLayout>
 
         <!-- end aligned fields -->
+        <!-- feedback for notificationassistantservice -->
+        <ImageButton
+            android:id="@+id/feedback"
+            android:layout_width="@dimen/notification_importance_toggle_size"
+            android:layout_height="@dimen/notification_importance_toggle_size"
+            android:layout_centerVertical="true"
+            android:visibility="gone"
+            android:background="@drawable/ripple_drawable"
+            android:contentDescription="@string/notification_guts_bundle_feedback"
+            android:src="@*android:drawable/ic_feedback"
+            android:layout_toStartOf="@id/info"
+            android:tint="@androidprv:color/materialColorPrimary"/>
         <!-- Optional link to app. Only appears if the channel is not disabled and the app
 asked for it -->
         <ImageButton
@@ -102,7 +114,7 @@
             android:background="@drawable/ripple_drawable"
             android:contentDescription="@string/notification_app_settings"
             android:src="@drawable/ic_info"
-            android:layout_toStartOf="@id/info"
+            android:layout_toStartOf="@id/feedback"
             android:tint="@androidprv:color/materialColorPrimary"/>
         <ImageButton
             android:id="@+id/info"
diff --git a/packages/SystemUI/res/layout/notification_stack_scroll_layout.xml b/packages/SystemUI/res/layout/notification_stack_scroll_layout.xml
index 65cf81e..5954de4 100644
--- a/packages/SystemUI/res/layout/notification_stack_scroll_layout.xml
+++ b/packages/SystemUI/res/layout/notification_stack_scroll_layout.xml
@@ -16,6 +16,7 @@
 -->
 
 <!-- This XML is served to be overridden by other OEMs/device types. -->
+<!-- Note: The margins may be overridden in code, see NotificationStackScrollLayout#getBottomMargin -->
 <com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
diff --git a/packages/SystemUI/res/layout/window_magnification_settings_view.xml b/packages/SystemUI/res/layout/window_magnification_settings_view.xml
index 7f735047..cb7bd17 100644
--- a/packages/SystemUI/res/layout/window_magnification_settings_view.xml
+++ b/packages/SystemUI/res/layout/window_magnification_settings_view.xml
@@ -23,6 +23,7 @@
     android:orientation="vertical"
     android:padding="@dimen/magnification_setting_background_padding"
     android:focusable="true"
+    android:accessibilityPaneTitle="@string/accessibility_magnification_settings_panel_description"
     android:contentDescription="@string/accessibility_magnification_settings_panel_description">
     <LinearLayout
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index e7efdba..6c86200 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batterypersentasie is onbekend."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Gekoppel aan <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Gekoppel aan <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Nie gekoppel nie."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Swerwing"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Af"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Om ’n app met ’n legstuk oop te maak, sal jy moet verifieer dat dit jy is. Hou ook in gedagte dat enigeen dit kan bekyk, selfs wanneer jou tablet gesluit is. Sommige legstukke is moontlik nie vir jou sluitskerm bedoel nie en dit kan onveilig wees om dit hier by te voeg."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Het dit"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Wys sluimerskermknoppie"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Verken sentrummodus"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Kry toegang tot jou gunstelinglegstukke en -skermbeskermers terwyl jy laai."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Kom ons begin"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Wissel gebruiker"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"aftrekkieslys"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Word aan die bokant van gesprekskennisgewings en as \'n profielfoto op sluitskerm gewys, verskyn as \'n borrel, onderbreek Moenie Steur Nie"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioriteit"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> steun nie gesprekskenmerke nie"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Maak toe"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Moenie weer wys nie"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Hierdie kennisgewings kan nie gewysig word nie."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Oproepkennisgewings kan nie gewysig word nie."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Hierdie groep kennisgewings kan nie hier opgestel word nie"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Sakrekenaar"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Wissel bonssleutels"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Wissel muissleutels"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Wissel taaisleutels"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Wissel stadige sleutels"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Wissel stemtoegang"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Moenie Steur Nie"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Volumeknoppieskortpad"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Gebruik vingerafdruk om oop te maak"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Stawing word vereis. Raak die vingerafdruksensor om te staaf."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Oproep aan die gang"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobiele data"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Gekoppel"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Tydelik gekoppel"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Jy het die Bekyk Onlangse Apps-gebaar voltooi."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Swiep op en hou met drie vingers op jou raakpaneel om onlangse apps te bekyk"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Wissel apps"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Swiep regs met vier vingers op jou raakpaneel"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Uitstekende werk!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Jy het die “wissel tussen apps”-gebaar voltooi."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Swiep regs met vier vingers op jou raakpaneel om apps te wissel"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Bekyk alle apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Druk die handelingsleutel op jou sleutelbord"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Welgedaan!"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 76a38c9..fc92f4b 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"የባትሪ መቶኛ አይታወቅም።"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"ከ<xliff:g id="BLUETOOTH">%s</xliff:g> ጋር ተገናኝቷል።"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"ከ<xliff:g id="CAST">%s</xliff:g> ጋር ተገናኝቷል።"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"አልተገናኘም።"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"በማዛወር ላይ"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"ጠፍቷል"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ምግብር በመጠቀም መተግበሪያ ለመክፈት እርስዎ መሆንዎን ማረጋገጥ አለብዎት። እንዲሁም የእርስዎ ጡባዊ በተቆለፈበት ጊዜ እንኳን ማንኛውም ሰው እነሱን ማየት እንደሚችል ከግምት ውስጥ ያስገቡ። አንዳንድ ምግብሮች ለማያ ገፅ ቁልፍዎ የታሰቡ ላይሆኑ ይችላሉ እና እዚህ ለማከል አስተማማኝ ላይሆኑ ይችላሉ።"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ገባኝ"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"የገፀ ማያ አሳራፊ አዝራርን አሳይ"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"የመገናኛ ሁነታን ያስሱ"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"ኃይል በሚሞሉበት ወቅት የእርስዎን ተወዳጅ ምግብሮች እና ማያ ገፅ ቆጣቢዎችን ይድረሱ።"</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"እንሂድ"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ተጠቃሚ ቀይር"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ወደታች ተጎታች ምናሌ"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"በውይይት ማሳወቂያዎች አናት ላይ እና በማያ ገፅ መቆለፊያ ላይ እንደ መገለጫ ምስል ይታያል፣ እንደ አረፋ ሆኖ ይታያል፣ አትረብሽን ያቋርጣል"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ቅድሚያ"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> የውይይት ባህሪያትን አይደግፍም"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"አሰናብት"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"ዳግም አታሳይ"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"እነዚህ ማሳወቂያዎች ሊሻሻሉ አይችሉም።"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"የጥሪ ማሳወቂያዎች ሊቀየሩ አይችሉም።"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"የማሳወቂያዎች ይህ ቡድን እዚህ ላይ ሊዋቀር አይችልም"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"የቀን መቁጠሪያ"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"ሒሳብ ማስያ"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"ካርታዎች"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"የወጡ ቁልፎችን ይቀያይሩ"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"የመዳፊት ቁልፎችን ይቀያይሩ"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"ተጣባቂ ቁልፎችን ይቀያይሩ"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"ቀርፋፋ ቁልፎችን ይቀያይሩ"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"የድምፅ መዳረሻን ይቀያይሩ"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"አትረብሽ"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"የድምፅ አዝራሮች አቋራጭ"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ለመክፈት የጣት አሻራ ይጠቀሙ"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ማረጋገጥ ያስፈልጋል። ለማረጋገጥ የጣት አሻራ ዳሳሹን ይንኩ።"</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"እየተካሄደ ያለ ጥሪ"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"የተንቀሳቃሽ ስልክ ውሂብ"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"ተገናኝቷል"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"በጊዜያዊነት ተገናኝቷል"</string>
@@ -1457,7 +1461,7 @@
     <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"አቋራጮችን ያብጁ"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"አቋራጭ ይወገድ?"</string>
     <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ወደ ነባሪ ዳግም ይጀመር?"</string>
-    <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"ይህን አቋራጭ ለመፍጠር የእርምጃ ቁልፉን እና ላይ አንድ ወይም ከዚያ በላይ ሌሎቹ ቁልፎችን አንድ ላይ ይጫኑ"</string>
+    <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"ይህን አቋራጭ ለመፍጠር የእርምጃ ቁልፉን እና አንድ ወይም ከዚያ በላይ ሌሎቹ ቁልፎችን አንድ ላይ ይጫኑ"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"ይህ ብጁ አቋራጭዎን በቋሚነት ይሰርዛል።"</string>
     <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"ይህ ሁሉንም ብጁ አቋራጮችዎን በቋሚነት ይሰርዛል።"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"የፍለጋ አቋራጮች"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"የቅርብ ጊዜ መተግበሪያዎች አሳይ ምልክትን አጠናቅቀዋል።"</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"የቅርብ ጊዜ መተግበሪያዎችን ለማየት የመዳሰሻ ሰሌዳዎ ላይ ሦስት ጣቶችን በመጠቀም ወደላይ ያንሸራትቱ እና ይያዙ"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"መተግበሪያዎችን ይቀያይሩ"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"የመዳሰሻ ሰሌዳዎ ላይ አራት ጣቶችን በመጠቀም ወደ ቀኝ ያንሸራትቱ"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"ጥሩ ሠርተዋል!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"የመተግበሪያ ምልክቶችን ይቀይሩ የሚለወን አጠናቅቀዋል።"</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"መተግበሪያዎችን ለመቀያየር የመዳሰሻ ሰሌዳዎ ላይ አራት ጣቶችን በመጠቀም ወደ ቀኝ ያንሸራትቱ"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"ሁሉንም መተግበሪያዎች ይመልከቱ"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"በቁልፍ ሰሌዳዎ ላይ ያለውን የተግባር ቁልፍ ይጫኑ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ጥሩ ሠርተዋል!"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 7db9a0d..7245e93 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"نسبة شحن البطارية غير معروفة."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"متصل بـ <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"تم الاتصال بـ <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"غير متصل."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"التجوال"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"غير مفعّلة"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"لفتح تطبيق باستخدام تطبيق مصغَّر، عليك إثبات هويتك. يُرجى ملاحظة أنّ أي شخص يمكنه الاطّلاع محتوى التطبيقات المصغَّرة، حتى وإن كان جهازك اللوحي مُقفلاً. بعض التطبيقات المصغّرة قد لا تكون مُصمَّمة لإضافتها إلى شاشة القفل، وقد يكون هذا الإجراء غير آمن."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"حسنًا"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"زر \"إظهار شاشة الاستراحة\""</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"التعرُّف على \"وضع الإرساء\""</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"يمكنك الاطّلاع على التطبيقات المصغّرة وشاشات الاستراحة المفضَّلة لديك أثناء شحن الجهاز."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"لنبدأ"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تبديل المستخدم"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"القائمة المنسدلة"</string>
@@ -753,8 +756,7 @@
     <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"جارٍ تعديل الحالة"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"ملف العمل"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"وضع الطيران"</string>
-    <!-- no translation found for status_bar_supervision (6735015942701134125) -->
-    <skip />
+    <string name="status_bar_supervision" msgid="6735015942701134125">"أدوات رقابة الأهل"</string>
     <string name="zen_alarm_warning" msgid="7844303238486849503">"لن تسمع المنبّه القادم في <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template" msgid="2234991538018805736">"في <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="3561752195856839456">"يوم <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -805,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"تظهر في أعلى إشعارات المحادثات وكصورة ملف شخصي على شاشة القفل وتظهر على شكل فقاعة لمقاطعة ميزة \"عدم الإزعاج\"."</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"الأولوية"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"لا يدعم تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> ميزات المحادثات."</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"إغلاق"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"عدم الإظهار مرة أخرى"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"يتعذّر تعديل هذه الإشعارات."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"لا يمكن تعديل إشعارات المكالمات."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"يتعذّر ضبط مجموعة الإشعارات هذه هنا."</string>
@@ -919,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"‏تقويم Google"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"الآلة الحاسبة"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"‏خرائط Google"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"تفعيل ميزة \"تجاهُل النقرات المتكرّرة\" أو إيقافها"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"تفعيل ميزة \"مفاتيح الماوس\" أو إيقافها"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"تفعيل ميزة \"تثبيت المفاتيح\" أو إيقافها"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"تفعيل ميزة \"المفاتيح البطيئة\" أو إيقافها"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"‏تفعيل تطبيق Voice Access أو إيقافه"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"‏تفعيل ميزة TalkBack أو إيقافها"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"تفعيل ميزة \"التكبير\" أو إيقافها"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"تفعيل ميزة \"سماع الاختيار\""</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"عدم الإزعاج"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"اختصار أزرار مستوى الصوت"</string>
     <string name="battery" msgid="769686279459897127">"البطارية"</string>
@@ -1308,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"يمكنك استخدام بصمة الإصبع للفتح"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"المصادقة مطلوبة. المس مستشعر بصمات الإصبع للمصادقة."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"مكالمة جارية"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"بيانات الجوّال"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"متصلة بالإنترنت"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"متصلة مؤقتًا"</string>
@@ -1449,8 +1449,7 @@
     <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"تطبيقات النظام"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"تعدُّد المهام"</string>
     <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"تقسيم الشاشة"</string>
-    <!-- no translation found for shortcutHelper_category_accessibility (8068337792277570938) -->
-    <skip />
+    <string name="shortcutHelper_category_accessibility" msgid="8068337792277570938">"خدمات تسهيل الاستخدام"</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_current_app_shortcuts" msgid="4017840565974573628">"التطبيق الحالي"</string>
@@ -1514,12 +1513,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"لقد أكملْت التدريب على إيماءة عرض التطبيقات المستخدَمة مؤخرًا."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"لعرض التطبيقات المستخدَمة مؤخرًا، يُرجى التمرير سريعًا للأعلى مع الاستمرار باستخدام ثلاثة أصابع على لوحة اللمس"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"التبديل بين التطبيقات"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"يُرجى التمرير سريعًا لليمين باستخدام أربعة أصابع على لوحة اللمس"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"أحسنت صنعًا."</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"أكملت التدريب على إيماءة التبديل بين التطبيقات."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"يُرجى التمرير سريعًا لليمين باستخدام أربعة أصابع على لوحة اللمس للتبديل بين التطبيقات"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"عرض جميع التطبيقات"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"اضغط على مفتاح الإجراء في لوحة المفاتيح"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"أحسنت!"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 297b410..407897a 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"বেটাৰীৰ চাৰ্জৰ শতাংশ অজ্ঞাত।"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>ৰ লগত সংযোগ কৰা হ’ল।"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>ত সংযোগ হ’ল।"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"সংযোগ হৈ থকা নাই।"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"ৰ\'মিং"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"অফ অৱস্থাত আছে"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"এটা ৱিজেট ব্যৱহাৰ কৰি কোনো এপ্ খুলিবলৈ, এয়া আপুনিয়েই বুলি সত্যাপন পৰীক্ষা কৰিব লাগিব। লগতে, মনত ৰাখিব যে যিকোনো লোকেই সেইবোৰ চাব পাৰে, আনকি আপোনাৰ টেবলেটটো লক হৈ থাকিলেও। কিছুমান ৱিজেট হয়তো আপোনাৰ লক স্ক্ৰীনৰ বাবে কৰা হোৱা নাই আৰু ইয়াত যোগ কৰাটো অসুৰক্ষিত হ’ব পাৰে।"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"বুজি পালোঁ"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"স্ক্ৰীনছেভাৰৰ বুটাম দেখুৱাওক"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"হাব ম’ড অন্বেষণ কৰক"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"চাৰ্জ কৰি থাকোঁতে আপোনাৰ প্ৰিয় ৱিজেট আৰু স্ক্ৰীন ছেভাৰসমূহ এক্সেছ কৰক।"</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"আৰম্ভ কৰোঁ আহক"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যৱহাৰকাৰী সলনি কৰক"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"পুল-ডাউনৰ মেনু"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"বাৰ্তালাপৰ জাননীৰ শীৰ্ষত আৰু প্ৰ’ফাইল চিত্ৰ হিচাপে লক স্ক্ৰীনত দেখুৱায়, এটা বাবল হিচাপে দেখা পোৱা যায়, অসুবিধা নিদিব ম’ডত ব্যাঘাত জন্মায়"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"অগ্ৰাধিকাৰ"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ বাৰ্তালাপৰ সুবিধাসমূহ সমৰ্থন নকৰে"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"অগ্ৰাহ্য কৰক"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"পুনৰাই নেদেখুৱাব"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"এই জাননীসমূহ সংশোধন কৰিব নোৱাৰি।"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"কলৰ জাননীসমূহ সংশোধন কৰিব নোৱাৰি।"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"এই ধৰণৰ জাননীবোৰ ইয়াত কনফিগাৰ কৰিব পৰা নাযায়"</string>
@@ -918,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"কেলকুলেটৰ"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"মেপ"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"বাউন্স কী ট’গল কৰক"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"মাউছ কীসমূহ ট’গল কৰক"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"ষ্টিকী কীসমূহ ট’গল কৰক"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"ধীৰ গতিৰ কী ট’গল কৰক"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Access ট’গল কৰক"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"TalkBack ট’গল কৰক"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"বিবৰ্ধন ট’গল কৰক"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"কথা ক’বলৈ বাছনি কৰাৰ সুবিধা সক্ৰিয় কৰক"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"অসুবিধা নিদিব"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ভলিউম বুটামসমূহৰ শ্বৰ্টকাট"</string>
     <string name="battery" msgid="769686279459897127">"বেটাৰী"</string>
@@ -1307,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"খুলিবলৈ ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণৰ আৱশ্যক। বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰিবলৈ ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো স্পৰ্শ কৰক।"</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"চলি থকা কল"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"ম’বাইল ডেটা"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"সংযোজিত হৈ আছে"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"অস্থায়ীভাৱে সংযোগ কৰা হৈছে"</string>
@@ -1512,12 +1513,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"আপুনি শেহতীয়া এপ্ চোৱাৰ নিৰ্দেশনাটো সম্পূৰ্ণ কৰিছে।"</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"শেহতীয়া এপ্‌সমূহ চাবলৈ, আপোনাৰ টাচ্চপেডত তিনিটা আঙুলি ব্যৱহাৰ কৰি ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"এপ্‌সমূহ সলনি কৰক"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"আপোনাৰ টাচ্চপেডত চাৰিটা আঙুলি ব্যৱহাৰ কৰি সোঁফাললৈ ছোৱাইপ কৰক"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"বঢ়িয়া!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"আপুনি এপ্‌ সলনি কৰাৰ নিৰ্দেশটো সম্পূৰ্ণ কৰিলে।"</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"এপ্‌সমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ আপোনাৰ টাচ্চপেডত চাৰিটা আঙুলি ব্যৱহাৰ কৰি সোঁফাললৈ ছোৱাইপ কৰক"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"আটাইবোৰ এপ্ চাওক"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"আপোনাৰ কীব’ৰ্ডৰ কাৰ্য কীটোত টিপক"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"বঢ়িয়া!"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index fb13ac4..13c82e8 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batareyanın faizi naməlumdur."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> üzərindən qoşuldu."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> cihazına qoşulub."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Qoşulu deyil."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Rouminq"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Deaktiv"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Vidcetdən istifadə edərək tətbiqi açmaq üçün kimliyi doğrulamalısınız. Planşet kilidli olsa da, hər kəs vidcetlərə baxa bilər. Bəzi vidcetlər kilid ekranı üçün nəzərdə tutulmayıb və bura əlavə etmək təhlükəli ola bilər."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Anladım"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Ekran qoruyucu düyməsini göstərin"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Hab rejimini araşdırın"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Şarj edərkən sevimli vidcet və ekran qoruyucularınıza daxil olun."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Başlayaq"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Söhbət bildirişlərinin yuxarısında və kilid ekranında profil şəkli kimi göstərilir, baloncuq kimi görünür, Narahat Etməyin rejimini kəsir"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> söhbət funksiyalarını dəstəkləmir"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Rədd edin"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Yenidən göstərməyin"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirişlər dəyişdirilə bilməz."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Zəng bildirişləri dəyişdirilə bilməz."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Bu bildiriş qrupunu burada konfiqurasiya etmək olmaz"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Təqvim"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kalkulyator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Xəritə"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Sıçrayan klavişləri aktiv/deaktiv edin"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Maus klavişlərini aktiv/deaktiv edin"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Əvəzedici düymələri aktiv/deaktiv edin"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Asta düymələri aktiv/deaktiv edin"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Səs girişini aktiv/deaktiv edin"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Narahat Etməyin"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Səs düymələri qısayolu"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Açmaq üçün barmaq izindən istifadə edin"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Doğrulanma tələb olunur. Doğrulamaq üçün barmaq izi sensoruna toxunun."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Davam edən zəng"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobil data"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Qoşulub"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Müvəqqəti qoşulub"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Son tətbiqlərə baxmaq jestini tamamladınız."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Ən son tətbiqlərə baxmaq üçün taçpeddə üç barmağınızla yuxarı çəkin və saxlayın"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Başqa tətbiqə keçin"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Taçpeddə dörd barmaqla sağa çəkin"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Əla!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Tətbiqlərarası keçid jestini tamamladınız."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Tətbiqlər arasında keçid etmək üçün taçpeddə dörd barmaqla sağa çəkin"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Bütün tətbiqlərə baxın"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Klaviaturada fəaliyyət açarına basın"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Əla!"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index be65e9e..b63e553 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Procenat napunjenosti baterije nije poznat."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Povezani ste sa <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Povezani smo sa uređajem <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Nije povezano."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Isključeno"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Istražite režim centra"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Pristupajte omiljenim vidžetima i čuvarima ekrana tokom punjenja."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Idemo"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikazuje se u vrhu obaveštenja o konverzacijama i kao slika profila na zaključanom ekranu, pojavljuje se kao oblačić, prekida režim Ne uznemiravaj"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritetno"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava funkcije konverzacije"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Odbaci"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ne prikazuj ponovo"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ova obaveštenja ne mogu da se menjaju."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Obaveštenja o pozivima ne mogu da se menjaju."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ova grupa obaveštenja ne može da se konfiguriše ovde"</string>
@@ -915,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kalkulator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Mape"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Uključi ili isključi duži odziv tastera"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Uključi ili isključi tastere miša"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Uključi ili isključi lepljive tastere"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Uključi ili isključi spore tastere"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Uključi ili isključi Pristup glasom"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Uključi ili isključi Talkback"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Uključi ili isključi Uvećanje"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"Aktiviraj Izaberite za govor"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne uznemiravaj"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Prečica za dugmad za jačinu zvuka"</string>
     <string name="battery" msgid="769686279459897127">"Baterija"</string>
@@ -1304,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Otvorite pomoću otiska prsta"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Potrebna je potvrda identiteta. Dodirnite senzor za otisak prsta da biste potvrdili identitet."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Poziv je u toku"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobilni podaci"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Povezano"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Privremeno povezano"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index ae73144..cbb8268 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Працэнт зараду акумулятара невядомы."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Падлучаны да <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Ёсць падключэнне да <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Няма падключэння."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Роўмінг"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Выключана"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Каб адкрыць праграму з дапамогай віджэта, вам неабходна будзе пацвердзіць сваю асобу. Таксама памятайце, што такія віджэты могуць пабачыць іншыя людзі, нават калі экран планшэта заблакіраваны. Некаторыя віджэты могуць не падыходзіць для выкарыстання на экране блакіроўкі, і дадаваць іх сюды можа быць небяспечна."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Зразумела"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Кнопка \"Паказаць застаўку\""</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Паспрабуйце рэжым хаба"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Доступ да любімых віджэтаў і заставак падчас зарадкі."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Пачаць"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Перайсці да іншага карыстальніка"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"высоўнае меню"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"З’яўляецца ўверсе раздзела размоў як усплывальнае апавяшчэнне, якое перарывае рэжым \"Не турбаваць\" і паказвае на экране блакіроўкі відарыс профілю"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Прыярытэт"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не падтрымлівае функцыі размовы"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Закрыць"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Больш не паказваць"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Гэтыя апавяшчэнні нельга змяніць."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Апавяшчэнні пра выклікі нельга змяніць."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Тут канфігурыраваць гэту групу апавяшчэнняў забаронена"</string>
@@ -918,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Каляндар"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Калькулятар"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Карты"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Уключыць/выключыць ігнараванне паўторнага націскання"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Уключыць/выключыць клавішы кіравання мышшу"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Уключыць/выключыць заліпанне клавіш"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Уключыць/выключыць запавольванне рэакцыі на націсканне"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Уключыць/выключыць Галасавы доступ"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Уключыць/выключыць TalkBack"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Уключыць/выключыць павелічэнне"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"Актываваць функцыю \"Чытаць уголас\""</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не турбаваць"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Доступ праз кнопкі рэгулявання гучнасці"</string>
     <string name="battery" msgid="769686279459897127">"Акумулятар"</string>
@@ -1307,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Каб адкрыць, скарыстайце адбітак пальца"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Патрабуецца аўтэнтыфікацыя. Дакраніцеся да сканера адбіткаў пальцаў."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Актыўны выклік"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мабільная перадача даных"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Падключана"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Падключана часова"</string>
@@ -1448,8 +1449,7 @@
     <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Сістэмныя праграмы"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Шматзадачнасць"</string>
     <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Падзелены экран"</string>
-    <!-- no translation found for shortcutHelper_category_accessibility (8068337792277570938) -->
-    <skip />
+    <string name="shortcutHelper_category_accessibility" msgid="8068337792277570938">"Спецыяльныя магчымасці"</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_current_app_shortcuts" msgid="4017840565974573628">"Бягучая праграма"</string>
@@ -1513,12 +1513,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Вы скончылі вывучэнне жэсту для прагляду нядаўніх праграм."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Каб праглядзець нядаўнія праграмы, правядзіце трыма пальцамі ўверх па сэнсарным экране і затрымайце пальцы"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Пераключэнне праграм"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Правядзіце па сэнсарнай панэлі чатырма пальцамі ўправа"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Выдатная праца!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Вы навучыліся рабіць жэст пераключэння праграм."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Каб пераключыцца паміж праграмамі, правядзіце па сэнсарнай панэлі чатырма пальцамі ўправа"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Глядзець усе праграмы"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Націсніце клавішу дзеяння на клавіятуры"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Выдатна!"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index db253db..31e4d33 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Процентът на батерията е неизвестен."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Има връзка с <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Установена е връзка с/ъс <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Няма връзка."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Роуминг"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Изключени"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"За да отворите дадено приложение посредством приспособление, ще трябва да потвърдите, че това сте вие. Също така имайте предвид, че всеки ще вижда приспособленията дори когато таблетът ви е заключен. Възможно е някои от тях да не са предназначени за заключения екран и добавянето им на него може да е опасно."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Разбрах"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Бутон за показване на скрийнсейвъра"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Разглеждане на режима „Контролен център“"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Използвайте любимите си приспособления и скрийнсейвъри по време на зареждане."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Начало"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Превключване между потребителите"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"падащо меню"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Показва се в горната част на известията за разговори и като снимка на потребителския профил на заключения екран, изглежда като балонче, прекъсва режима „Не безпокойте“"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Приоритет"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не поддържа функциите за разговор"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Отхвърляне"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Да не се показва отново"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Тези известия не могат да бъдат променяни."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Известията за обаждания не могат да бъдат променяни."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Тази група от известия не може да бъде конфигурирана тук"</string>
@@ -918,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Калкулатор"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Карти"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Превключване на функцията за игнориране на многократното натискане"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Превключване на функцията за клавиши за мишката"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Превключване на функцията за фиксирани клавиши"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Превключване на функцията за забавяне на сигнала от клавишите"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Превключване на Voice Access"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Превключване на TalkBack"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Превключване на функцията за увеличение"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"Активиране на „Прочитане на глас“"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не безпокойте"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Пряк път към бутоните за силата на звука"</string>
     <string name="battery" msgid="769686279459897127">"Батерия"</string>
@@ -1307,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Използвайте отпечатък за отваряне"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Изисква се удостоверяване на самоличността. За целта докоснете сензора за отпечатъци."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Текущо обаждане"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобилни данни"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Свързано"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Установена е временна връзка"</string>
@@ -1450,16 +1451,16 @@
     <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Разделен екран"</string>
     <string name="shortcutHelper_category_accessibility" msgid="8068337792277570938">"Достъпност"</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_app_shortcuts" msgid="8010249408308587117">"Клавишни комбинации за приложения"</string>
     <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Текущо приложение"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Достъпност"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Клавишни комбинации"</string>
-    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Персонализиране на преките пътища"</string>
+    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Персонализиране на клавишните комбинации"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Да се премахне ли клавишната комбинация?"</string>
     <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Да се възстановят ли стандартните настройки?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"За да създадете тази клавишна комбинация, натиснете клавиша за действия заедно с един или повече други клавиши"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Това ще изтрие персонализираната клавишна комбинация за постоянно."</string>
-    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Това ще изтрие всичките ви персонализирани преки пътища за постоянно."</string>
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Това ще изтрие всичките ви персонализирани клавишни комбинации за постоянно."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Търсете клавишни комбинации"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Няма резултати от търсенето"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за свиване"</string>
@@ -1474,7 +1475,7 @@
     <string name="shortcut_helper_key_combinations_forward_slash" msgid="1238652537199346970">"наклонена черта"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Манипулатор за преместване с плъзгане"</string>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Настройки на клавиатурата"</string>
-    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Задаване на клавишна комбинация"</string>
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Клавишна комбинация"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Премахване"</string>
     <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Да, нулиране"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Отказ"</string>
@@ -1512,12 +1513,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Изпълнихте жеста за преглед на скорошните приложения."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"За да прегледате скорошните приложения, плъзнете три пръста нагоре по сензорния панел и задръжте"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Превключване на приложенията"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Прекарайте четири пръста надясно по сензорния панел"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Отлично!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Изпълнихте жеста за превключване между приложения."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Прекарайте четири пръста надясно по сензорния панел, за да превключите приложенията"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Преглед на всички приложения"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Натиснете клавиша за действия на клавиатурата си"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Браво!"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 5e9860d..e9b6cf3c 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ব্যাটারি কত শতাংশ আছে তা জানা যায়নি।"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>এ সংযুক্ত হয়ে আছে।"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> এর সাথে সংযুক্ত৷"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"সংযুক্ত নয়৷"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"রোমিং"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"বন্ধ"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"উইজেট ব্যবহার করে কোনও অ্যাপ খুলতে, আপনাকে নিজের পরিচয় যাচাই করতে হবে। এছাড়াও, মনে রাখবেন, আপনার ট্যাবলেট লক থাকলেও যেকেউ তা দেখতে পারবেন। কিছু উইজেট আপনার লক স্ক্রিনের উদ্দেশ্যে তৈরি করা হয়নি এবং এখানে যোগ করা নিরাপদ নাও হতে পারে।"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"বুঝেছি"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"স্ক্রিন সেভার বোতাম দেখুন"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"হাব মোড ঘুরে দেখুন"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"চার্জ করার সময় আপনার পছন্দের উইজেট এবং স্ক্রিন সেভার অ্যাক্সেস করুন।"</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"শুরু করা যাক"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যবহারকারী পাল্টে দিন"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"পুলডাউন মেনু"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"কথোপকথনের বিজ্ঞপ্তির উপরের দিকে এবং প্রোফাইল ছবি হিসেবে লক স্ক্রিনে দেখানো হয়, বাবল হিসেবেও এটি দেখা যায় এবং এর ফলে \'বিরক্ত করবে না\' মোডে কাজ করতে অসুবিধা হয়"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"অগ্রাধিকার"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>-এ কথোপকথন ফিচার কাজ করে না"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"বাতিল করুন"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"আর দেখতে চাই না"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"এই বিজ্ঞপ্তিগুলি পরিবর্তন করা যাবে না।"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"কল বিজ্ঞপ্তি পরিবর্তন করা যাবে না।"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"এই সমস্ত বিজ্ঞপ্তিকে এখানে কনফিগার করা যাবে না"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"ক্যালকুলেটর"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"ম্যাপ"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"বাউন্স \'কী\' টগল করুন"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"মাউস \'কী\' টগল করুন"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"স্টিকি \'কী\' টগল করুন"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"স্লো \'কী\' টগল করুন"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Access টগল করুন"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"বিরক্ত করবে না"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ভলিউম বোতামের শর্টকাট"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"খুলতে ফিঙ্গারপ্রিন্ট ব্যবহার করুন"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"যাচাইকরণ করতে হবে। যাচাইকরণ করতে আঙুলের ছাপের সেন্সরে টাচ করুন।"</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"চালু থাকা কল"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"মোবাইল ডেটা"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"কানেক্ট করা আছে"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"সাময়িকভাবে কানেক্ট করা হয়েছে"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"সম্প্রতি ব্যবহার করা হয়েছে এমন অ্যাপের জেসচার দেখা সম্পূর্ণ করেছেন।"</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"সাম্প্রতিক অ্যাপ দেখতে, নিজের টাচপ্যাডে তিনটি আঙুল ব্যবহার করে উপরের দিকে সোয়াইপ করে হোল্ড করুন"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"অ্যাপ পরিবর্তন করুন"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"আপনার টাচপ্যাডে চারটি আঙুল ব্যবহার করে ডানদিকে সোয়াইপ করুন"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"অসাধারণ!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"আপনি অ্যাপ পরিবর্তন করার জেসচার সম্পূর্ণ করেছেন।"</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"অ্যাপ পরিবর্তন করতে, আপনার টাচপ্যাডে চারটি আঙুল ব্যবহার করে ডানদিকে সোয়াইপ করুন"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"সব অ্যাপ দেখুন"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"আপনার কীবোর্ডে অ্যাকশন কী প্রেস করুন"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"দারুণ!"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 1b79810..53b0e78 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Postotak napunjenosti baterije nije poznat"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Povezan na <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Povezan na <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Nije povezano."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Isključeno"</string>
@@ -536,9 +540,11 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da otvorite aplikaciju pomoću vidžeta, morat ćete potvrditi identitet. Također imajte na umu da ih svako može pregledati, čak i ako je tablet zaključan. Neki vidžeti možda nisu namijenjeni za vaš zaključani ekran i njihovo dodavanje ovdje možda nije sigurno."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Razumijem"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Dugme za prikaz čuvara ekrana"</string>
-    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Istraži način Huba"</string>
-    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Pristupite omiljenim widgetima i čuvarima zaslona tijekom punjenja."</string>
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Istražite način rada središta"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Pristupajte svojim omiljenim vidžetima i čuvarima ekrana tokom punjenja."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Započnimo"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikazuje se na vrhu obavještenja u razgovorima i kao slika profila na zaključanom ekranu, izgleda kao oblačić, prekida funkciju Ne ometaj"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritetno"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava funkcije razgovora"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Odbaci"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ne prikazuj ponovo"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ta obavještenja se ne mogu izmijeniti."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Nije moguće izmijeniti obavještenja o pozivima."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ovu grupu obavještenja nije moguće konfigurirati ovdje"</string>
@@ -876,7 +880,7 @@
     <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Prikazivanje prečica koje otvaraju aplikacije"</string>
     <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Prikazivanje prečica za trenutnu aplikaciju"</string>
     <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Prikaz obavještenja"</string>
-    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Pravljenje snimka ekrana"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Izrada snimka ekrana"</string>
     <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Prikaz prečica"</string>
     <string name="group_system_go_back" msgid="2730322046244918816">"Nazad"</string>
     <string name="group_system_access_home_screen" msgid="4130366993484706483">"Odlazak na početni ekran"</string>
@@ -915,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kalkulator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Mape"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Uključivanje/isključivanje zanemarivanja slučajnih pritisaka tipki"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Uključivanje/isključivanje tipki za miš"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Uključivanje/isključivanje ljepljivih tipki"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Uključivanje/isključivanje sporog reagiranja tipki"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Uključivanje/isključivanje Pristupa glasom"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Uključi/isključi TalkBack"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Uključi/isključi povećavanje"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"Aktiviraj Odabir za govor"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne ometaj"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Prečica za dugmad za Jačinu zvuka"</string>
     <string name="battery" msgid="769686279459897127">"Baterija"</string>
@@ -1304,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Otvorite pomoću otiska prsta"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Potrebna je autentifikacija. Dodirnite senzor za otisak prsta da autentificirate."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Poziv u toku"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Prijenos podataka na mobilnoj mreži"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Povezano"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Privremeno povezano"</string>
@@ -1509,10 +1513,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Izvršili ste pokret za prikaz nedavnih aplikacija."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Da pogledate nedavne aplikacije, prevucite nagore i zadržite s tri prsta na dodirnoj podlozi"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Promijenite aplikaciju"</string>
-    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Prijeđite udesno četirima prstima na dodirnoj podlozi"</string>
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Prevucite udesno s četiri prsta na dodirnoj podlozi"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Sjajno!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Izvršili ste pokret za promjenu aplikacije."</string>
-    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Prijeđite udesno četirima prstima na dodirnoj podlozi za prebacivanje između aplikacija"</string>
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Prevucite udesno s četiri prsta na dodirnoj podlozi da promijenite aplikaciju"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Pogledajte sve aplikacije"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pritisnite tipku radnji na tastaturi"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Odlično!"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index eae1b34..4490513 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Es desconeix el percentatge de bateria."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"S\'ha connectat a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Està connectat amb <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Sense connexió."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Itinerància"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Desactivades"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Per obrir una aplicació utilitzant un widget, necessitaràs verificar la teva identitat. També has de tenir en compte que qualsevol persona pot veure els widgets, fins i tot quan la tauleta està bloquejada. És possible que alguns widgets no estiguin pensats per a la pantalla de bloqueig i que no sigui segur afegir-los-hi."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entesos"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Botó Mostra l\'estalvi de pantalla"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Explora el mode Hub"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Accedeix als teus widgets i estalvis de pantalla preferits mentre es carrega."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Som-hi"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Es mostra a la part superior de les notificacions de les converses i com a foto de perfil a la pantalla de bloqueig, apareix com una bombolla, interromp el mode No molestis"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritat"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admet les funcions de converses"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Ignora"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"No ho tornis a mostrar"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Aquestes notificacions no es poden modificar."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Les notificacions de trucades no es poden modificar."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Aquest grup de notificacions no es pot configurar aquí"</string>
@@ -918,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculadora"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Commuta les tecles de rebot"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Commuta les tecles del ratolí"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Commuta les tecles permanents"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Commuta les tecles lentes"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Commuta Voice Access"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Commuta TalkBack"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Commuta l\'ampliació"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"Activa Escolta la selecció"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"No molestis"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Drecera per als botons de volum"</string>
     <string name="battery" msgid="769686279459897127">"Bateria"</string>
@@ -1307,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Utilitza l\'empremta digital per obrir"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autenticació necessària. Toca el sensor d\'empremtes digitals per autenticar-te."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Trucada en curs"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Dades mòbils"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Connectat"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Connexió temporal"</string>
@@ -1512,12 +1513,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Has completat el gest per veure les aplicacions recents."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Per veure les aplicacions recents, llisca cap amunt amb tres dits i mantén-los premuts al ratolí tàctil"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Canviar d\'aplicació"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Llisca cap a la dreta amb quatre dits al ratolí tàctil"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Ben fet!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Has completat el gest per canviar d\'aplicació."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Llisca cap a la dreta amb quatre dits al ratolí tàctil per canviar d\'aplicació"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Mostra totes les aplicacions"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Prem la tecla d\'acció al teclat"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Enhorabona!"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 9422804..ce66f83 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Procento baterie není známé."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Připojeno k zařízení <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Jste připojeni k zařízení <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Nepřipojeno."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Vypnuto"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Prozkoumejte Režim centra"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Mějte po ruce oblíbené widgety a spořiče obrazovky při nabíjení."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Jdeme na to"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -750,8 +756,7 @@
     <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"Probíhá aktualizace"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Pracovní profil"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Režim Letadlo"</string>
-    <!-- no translation found for status_bar_supervision (6735015942701134125) -->
-    <skip />
+    <string name="status_bar_supervision" msgid="6735015942701134125">"Rodičovská kontrola"</string>
     <string name="zen_alarm_warning" msgid="7844303238486849503">"Svůj další budík <xliff:g id="WHEN">%1$s</xliff:g> neuslyšíte"</string>
     <string name="alarm_template" msgid="2234991538018805736">"v <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -802,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Zobrazuje se v horní části sekce konverzací a na obrazovce uzamčení se objevuje jako profilová fotka, má podobu bubliny a deaktivuje režim Nerušit"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritní"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> funkce konverzace nepodporuje"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Zavřít"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Už nezobrazovat"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Tato oznámení nelze upravit."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Upozornění na hovor nelze upravit."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Tuto skupinu oznámení tady nelze nakonfigurovat"</string>
@@ -916,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendář"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kalkulačka"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Mapy"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Přepnout opakovaná stisknutí"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Přepnout klávesy myši"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Přepnout funkci Jedním prstem"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Přepnout zpomalení kláves"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Přepnout ovládání hlasem"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Přepnout TalkBack"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Přepnout přiblížení"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"Aktivovat poslech vybraného textu"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Nerušit"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Zkratka tlačítek hlasitosti"</string>
     <string name="battery" msgid="769686279459897127">"Baterie"</string>
@@ -1305,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"K otevření použijte otisk prstu"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Je vyžadováno ověření. Dotkněte se snímače otisků prstů."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Probíhající hovor"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobilní data"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Připojeno"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Dočasně připojeno"</string>
@@ -1446,8 +1449,7 @@
     <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_split_screen" msgid="1159669813444812244">"Rozdělená obrazovka"</string>
-    <!-- no translation found for shortcutHelper_category_accessibility (8068337792277570938) -->
-    <skip />
+    <string name="shortcutHelper_category_accessibility" msgid="8068337792277570938">"Přístupnost"</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_current_app_shortcuts" msgid="4017840565974573628">"Aktuální aplikace"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index cb70b9a..251b38a 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batteriniveauet er ukendt."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Forbundet med <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Forbundet til <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Ikke tilsluttet."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Fra"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Hvis du vil åbne en app ved hjælp af en widget, skal du verificere din identitet. Husk også, at alle kan se dem, også når din tablet er låst. Nogle widgets er muligvis ikke beregnet til låseskærmen, og det kan være usikkert at tilføje dem her."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Knappen Vis pauseskærm"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Udforsk i Hub-tilstand"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Få adgang til dine foretrukne widgets og pauseskærme under opladning."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Kom i gang"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skift bruger"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullemenu"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Vises øverst i samtalenotifikationer og som et profilbillede på låseskærmen. Vises som en boble, der afbryder Forstyr ikke"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> understøtter ikke samtalefunktioner"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Luk"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Vis ikke igen"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Disse notifikationer kan ikke redigeres."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Opkaldsnotifikationer kan ikke redigeres."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Du kan ikke konfigurere denne gruppe notifikationer her"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Lomme­regner"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Slå elastiktaster til/fra"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Slå musetaster til/fra"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Slå træge taster til/fra"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Slå langsomtaster til/fra"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Slå Stemmeadgang til/fra"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Forstyr ikke"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Genvej til lydstyrkeknapper"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Brug fingeraftryk for at åbne"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Godkendelse er påkrævet. Sæt fingeren på fingeraftrykssensoren for at godkende."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Igangværende opkald"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobildata"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Forbundet"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Midlertidigt forbundet"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Du har udført bevægelsen for at se de seneste apps."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Du kan se nyligt brugte apps ved at stryge opad og holde tre fingre nede på touchpladen"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Skift mellem apps"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Stryg til højre med fire fingre på touchpladen"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Godt klaret!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Du har fuldført bevægelsen for at skifte mellem apps."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Stryg til højre med fire fingre på touchpladen for at skifte mellem apps"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Se alle apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tryk på handlingstasten på dit tastatur"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Flot klaret!"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 09c7067..c550750 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akkustand unbekannt."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Mit <xliff:g id="BLUETOOTH">%s</xliff:g> verbunden"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Verbunden mit <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Nicht verbunden"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Aus"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Wenn du eine App mit einem Widget öffnen möchtest, musst du deine Identität bestätigen. Beachte auch, dass jeder die Widgets sehen kann, auch wenn dein Tablet gesperrt ist. Einige Widgets sind möglicherweise nicht für den Sperrbildschirm vorgesehen, sodass es unsicher sein kann, sie hier hinzuzufügen."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ok"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Schaltfläche „Bildschirmschoner anzeigen“"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Hub-Modus entdecken"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Du kannst während des Ladevorgangs auf deine bevorzugten Widgets und Bildschirmschoner zugreifen."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Los gehts"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wird oben im Bereich „Unterhaltungen“ sowie als Profilbild auf dem Sperrbildschirm angezeigt, erscheint als Bubble, unterbricht „Bitte nicht stören“"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priorität"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> unterstützt keine Funktionen für Unterhaltungen"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Schließen"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Nicht mehr anzeigen"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Diese Benachrichtigungen können nicht geändert werden."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Anrufbenachrichtigungen können nicht geändert werden."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Die Benachrichtigungsgruppe kann hier nicht konfiguriert werden"</string>
@@ -918,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Rechner"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Bounce-Tasten aktivieren/deaktivieren"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Tastaturmaus aktivieren/deaktivieren"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Einfingerbedienung aktivieren/deaktivieren"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Anschlagverzögerung aktivieren/deaktivieren"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Access aktivieren/deaktivieren"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"TalkBack aktivieren/deaktivieren"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"„Vergrößerung“ aktivieren/deaktivieren"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"„Vorlesen“ aktivieren"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Bitte nicht stören"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Tastenkombination für Lautstärketasten"</string>
     <string name="battery" msgid="769686279459897127">"Akku"</string>
@@ -1307,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Mit Fingerabdruck öffnen"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentifizierung erforderlich. Tippe dazu einfach auf den Fingerabdrucksensor."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Aktiver Anruf"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobile Daten"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Verbunden"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Vorübergehend verbunden"</string>
@@ -1512,12 +1513,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Du hast das Tutorial für die Touch-Geste zum Aufrufen der zuletzt verwendeten Apps abgeschlossen."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Wenn du zuletzt verwendete Apps aufrufen möchtest, wische mit drei Fingern nach oben und halte das Touchpad gedrückt"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Zwischen Apps wechseln"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Wische mit vier Fingern auf dem Touchpad nach rechts"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Gut gemacht!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Du hast die Touch-Geste „Zwischen Apps wechseln\" abgeschlossen."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Wische mit vier Fingern auf dem Touchpad nach rechts, um zwischen Apps zu wechseln"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Alle Apps anzeigen"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Drücke die Aktionstaste auf deiner Tastatur"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Perfekt!"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index cc4ce17..ae16cc0 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Άγνωστο ποσοστό μπαταρίας."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Συνδέθηκε στο <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Συνδέθηκε σε <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Μη συνδεδεμένο"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Περιαγωγή"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Ανενεργά"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Εξερεύνηση της λειτουργίας Hub"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Αποκτήστε πρόσβαση στα αγαπημένα σας γραφικά στοιχεία και τις προφυλάξεις οθόνης κατά τη φόρτιση."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Ας ξεκινήσουμε"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Εμφανίζεται στην κορυφή των ειδοποιήσεων συζήτησης και ως φωτογραφία προφίλ στην οθόνη κλειδώματος, εμφανίζεται ως συννεφάκι, διακόπτει τη λειτουργία Μην ενοχλείτε"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Προτεραιότητα"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> δεν υποστηρίζει τις λειτουργίες συζήτησης"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Παράβλεψη"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Να μην εμφανιστεί ξανά"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Δεν είναι δυνατή η τροποποίηση αυτών των ειδοποιήσεων"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Δεν είναι δυνατή η τροποποίηση των ειδοποιήσεων κλήσεων."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Δεν είναι δυνατή η διαμόρφωση αυτής της ομάδας ειδοποιήσεων εδώ"</string>
@@ -915,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Ημερολόγιο"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Αριθμομηχανή"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Χάρτες"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Εναλλαγή ελαστικών πλήκτρων"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Εναλλαγή πλήκτρων ελέγχου ποντικιού"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Εναλλαγή ασύγχρονων πλήκτρων"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Εναλλαγή αργών πλήκτρων"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Εναλλαγή Voice Access"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Μην ενοχλείτε"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Συντόμευση κουμπιών έντασης ήχου"</string>
@@ -1304,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Χρήση δακτυλικού αποτυπώματος για άνοιγμα"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Απαιτείται έλεγχος ταυτότητας. Αγγίξτε τον αισθητήρα δακτυλικών αποτυπωμάτων για έλεγχο ταυτότητας."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Κλήση σε εξέλιξη"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Δεδομένα κινητής τηλεφωνίας"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Συνδέθηκε"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Προσωρινή σύνδεση"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index c7ee5c5..13fdb0b 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connected to <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Connected to <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Not connected."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Off"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you\'ll need to verify that it\'s you. Also, bear 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_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Show screensaver button"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Explore Hub Mode"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Access your favourite widgets and screen savers while charging."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Let\'s go"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Dismiss"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Don\'t show again"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Call notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"This group of notifications cannot be configured here"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Toggle bounce keys"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Toggle mouse keys"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Toggle sticky keys"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Toggle slow keys"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Toggle Voice Access"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Do Not Disturb"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Volume buttons shortcut"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use fingerprint to open"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentication required. Touch the fingerprint sensor to authenticate."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Ongoing call"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobile data"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Connected"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Temporarily connected"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"You completed the view recent apps gesture."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"To view recent apps, swipe up and hold using three fingers on your touchpad"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Switch apps"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Swipe right using four fingers on your touchpad"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Well done!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"You completed the switch apps gesture."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Swipe right using four fingers on your touchpad to switch apps"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"View all apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Press the action key on your keyboard"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Well done!"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index c26bee1..ab418b5 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -250,6 +250,8 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connected to <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Connected to <xliff:g id="CAST">%s</xliff:g>."</string>
+    <string name="accessibility_expand_group" msgid="521237935987978624">"Expand group."</string>
+    <string name="accessibility_open_application" msgid="1749126077501259712">"Open application."</string>
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Not connected."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Off"</string>
@@ -539,6 +541,7 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Explore hub mode"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Access your favorite widgets and screen savers while charging."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Let’s go"</string>
+    <string name="glanceable_hub_to_dream_button_tooltip" msgid="9018287673822335829">"Show your favorite screensavers while charging"</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>
@@ -913,16 +916,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Toggle bounce keys"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Toggle mouse keys"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Toggle sticky keys"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Toggle slow keys"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Toggle Voice Access"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Toggle Talkback"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Toggle Magnification"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"Activate Select to Speak"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Do Not Disturb"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Volume buttons shortcut"</string>
     <string name="battery" msgid="769686279459897127">"Battery"</string>
@@ -1302,6 +1303,7 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use fingerprint to open"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentication required. Touch the fingerprint sensor to authenticate."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Ongoing call"</string>
+    <string name="ongoing_notification_extra_content_description" msgid="2098752668861351265">"Ongoing"</string>
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobile data"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Connected"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Temporarily connected"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index c7ee5c5..13fdb0b 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connected to <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Connected to <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Not connected."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Off"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you\'ll need to verify that it\'s you. Also, bear 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_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Show screensaver button"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Explore Hub Mode"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Access your favourite widgets and screen savers while charging."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Let\'s go"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Dismiss"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Don\'t show again"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Call notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"This group of notifications cannot be configured here"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Toggle bounce keys"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Toggle mouse keys"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Toggle sticky keys"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Toggle slow keys"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Toggle Voice Access"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Do Not Disturb"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Volume buttons shortcut"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use fingerprint to open"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentication required. Touch the fingerprint sensor to authenticate."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Ongoing call"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobile data"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Connected"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Temporarily connected"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"You completed the view recent apps gesture."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"To view recent apps, swipe up and hold using three fingers on your touchpad"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Switch apps"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Swipe right using four fingers on your touchpad"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Well done!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"You completed the switch apps gesture."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Swipe right using four fingers on your touchpad to switch apps"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"View all apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Press the action key on your keyboard"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Well done!"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index c7ee5c5..13fdb0b 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connected to <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Connected to <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Not connected."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Off"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you\'ll need to verify that it\'s you. Also, bear 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_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Show screensaver button"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Explore Hub Mode"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Access your favourite widgets and screen savers while charging."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Let\'s go"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priority"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> doesn’t support conversation features"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Dismiss"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Don\'t show again"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"These notifications can\'t be modified."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Call notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"This group of notifications cannot be configured here"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Toggle bounce keys"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Toggle mouse keys"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Toggle sticky keys"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Toggle slow keys"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Toggle Voice Access"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Do Not Disturb"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Volume buttons shortcut"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use fingerprint to open"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentication required. Touch the fingerprint sensor to authenticate."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Ongoing call"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobile data"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Connected"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Temporarily connected"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"You completed the view recent apps gesture."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"To view recent apps, swipe up and hold using three fingers on your touchpad"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Switch apps"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Swipe right using four fingers on your touchpad"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Well done!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"You completed the switch apps gesture."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Swipe right using four fingers on your touchpad to switch apps"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"View all apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Press the action key on your keyboard"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Well done!"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 95ebbb2..793207d 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Se desconoce el porcentaje de la batería."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Conectado a <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"No conectado"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Desactivados"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir una app usando un widget, debes verificar tu identidad. Además, ten en cuenta que cualquier persona podrá verlo, incluso cuando la tablet esté bloqueada. Es posible que algunos widgets no se hayan diseñados para la pantalla de bloqueo y podría ser peligroso agregarlos allí."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendido"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Botón para mostrar el protector de pantalla"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Explora el modo Hub"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Accede a tus widgets y protectores de pantalla favoritos mientras se carga el dispositivo."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Comenzar"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparece en forma de burbuja y como foto de perfil en la parte superior de las notificaciones de conversación, en la pantalla de bloqueo, y detiene el modo No interrumpir"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritaria"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admite funciones de conversación"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Descartar"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"No volver a mostrar"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"No se pueden modificar estas notificaciones."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"No se pueden modificar las notificaciones de llamada."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"No se puede configurar aquí este grupo de notificaciones"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendario"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculadora"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Activar o desactivar el rechazo de teclas"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Activar o desactivar las teclas del mouse"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Activar o desactivar las teclas especiales"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Activar o desactivar las teclas lentas"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Activar o desactivar el Acceso por voz"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"No interrumpir"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Combinación de teclas de botones de volumen"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Usa la huella dactilar para abrir"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Se requiere de una autenticación. Toca el sensor de huellas dactilares para autenticarte."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Llamada en curso"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Datos móviles"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Conexión establecida"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Conectado temporalmente"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Completaste el gesto para ver las apps recientes."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Para ver las apps recientes, desliza tres dedos hacia arriba y mantenlos presionados en el panel táctil"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Cambia de app"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Desliza hacia la derecha con cuatro dedos en el panel táctil"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"¡Bien hecho!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Completaste el gesto para cambiar de app."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Desliza hacia la derecha con cuatro dedos en el panel táctil para cambiar de app"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todas las apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Presiona la tecla de acción en el teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"¡Bien hecho!"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 2c88f8e..d5ace64 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Porcentaje de batería desconocido."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Conectado a <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"No conectado."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Desactivados"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir una aplicación usando un widget, deberás verificar que eres tú. Además, ten en cuenta que cualquier persona podrá verlos, incluso aunque tu tablet esté bloqueada. Es posible que algunos widgets no estén pensados para la pantalla de bloqueo y no sea seguro añadirlos aquí."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendido"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Botón para mostrar el salvapantallas"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Descubre el modo Base"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Accede a tus widgets y salvapantallas favoritos mientras se carga."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Vamos allá"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Se muestra encima de las notificaciones de conversaciones y como imagen de perfil en la pantalla de bloqueo, aparece como burbuja e interrumpe el modo No molestar"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioridad"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> no admite funciones de conversación"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Cerrar"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"No volver a mostrar"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Estas notificaciones no se pueden modificar."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Las notificaciones de llamada no se pueden modificar."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Este grupo de notificaciones no se puede configurar aquí"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendario"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculadora"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Activar/Desactivar teclas de rebote"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Activar/Desactivar teclas del ratón"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Activar/Desactivar teclas persistentes"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Activar/Desactivar teclas lentas"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Activar/Desactivar Voice Access"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"No molestar"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Acceso directo de los botones de volumen"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Usa la huella digital para abrir"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autenticación obligatoria. Toca el sensor de huellas digitales para autenticarte."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Llamada en curso"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Datos móviles"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Conectado"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Conectada temporalmente"</string>
@@ -1454,7 +1458,7 @@
     <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplicación en uso"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string>
-    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Personalizar combinaciones de teclas"</string>
+    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Personalizar combinaciones"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"¿Eliminar combinación de teclas?"</string>
     <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"¿Restablecer valores predeterminados?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"Para crear esta combinación de teclas, pulsa la tecla de acción y una o varias teclas a la vez"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Has completado el gesto para ver las aplicaciones recientes."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Para ver las aplicaciones recientes, desliza tres dedos hacia arriba y mantén pulsado en el panel táctil"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Cambiar de aplicación"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Desliza hacia la derecha con cuatro dedos en el panel táctil"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"¡Bien hecho!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Has completado el gesto para cambiar de aplicación."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Desliza hacia la derecha con cuatro dedos en el panel táctil para cambiar de aplicación"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todas las aplicaciones"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pulsa la tecla de acción de tu teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"¡Muy bien!"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index c96cc04..77fe2e7 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Aku laetuse protsent on teadmata."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Ühendatud: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Ühendatud ülekandega <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Ühendus puudub."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Rändlus"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Väljas"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Rakenduse avamiseks vidina abil peate kinnitama, et see olete teie. Samuti pidage meeles, et kõik saavad vidinaid vaadata, isegi kui teie tahvelarvuti on lukus. Mõni vidin ei pruugi olla ette nähtud teie lukustuskuva jaoks ja seda pole turvaline siia lisada."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Selge"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Nupp Kuva ekraanisäästja"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Tutvuge dokirežiimiga"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Saate laadimise ajal juurdepääsu oma lemmikumatele vidinatele ja ekraanisäästjatele."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Alustame"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kasutaja vahetamine"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rippmenüü"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Kuvatakse mullina vestluste märguannete ülaosas ja profiilipildina lukustuskuval ning katkestab režiimi Mitte segada"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioriteetne"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei toeta vestlusfunktsioone"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Loobu"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ära enam näita"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Neid märguandeid ei saa muuta."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Kõnemärguandeid ei saa muuta."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Seda märguannete rühma ei saa siin seadistada"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kalkulaator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Põrkeklahvide vahetamine"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Hiireklahvide vahetamine"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Nakkeklahvide vahetamine"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Aeglaste klahvide vahetamine"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Accessi vahetamine"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Mitte segada"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Helitugevuse nuppude otsetee"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Kasutage avamiseks sõrmejälge"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Vajalik on autentimine. Puudutage autentimiseks sõrmejäljeandurit."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Käimasolev kõne"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobiilne andmeside"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Ühendatud"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Ajutiselt ühendatud"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Tegite hiljutiste rakenduste vaatamise liigutuse."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Hiljutiste rakenduste kuvamiseks pühkige puuteplaadil kolme sõrmega üles ja hoidke sõrmi puuteplaadil"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Rakenduste vahetamine"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Pühkige puuteplaadil nelja sõrmega paremale"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Väga hea!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Tegite rakenduste vahetamise liigutuse."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Rakenduste vahetamiseks pühkige puuteplaadil nelja sõrmega paremale"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Kõigi rakenduste kuvamine"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Vajutage klaviatuuril toiminguklahvi"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Hästi tehtud!"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index b8643a2..c4545f8 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Bateriaren ehunekoa ezezaguna da."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> gailura konektatuta."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Hona konektatuta: <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Konektatu gabe."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Ibiltaritza"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Desaktibatuta"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Aplikazio bat widget baten bidez irekitzeko, zeu zarela egiaztatu beharko duzu. Gainera, kontuan izan edonork ikusi ahalko dituela halako widgetak, tableta blokeatuta badago ere. Baliteke widget batzuk pantaila blokeaturako egokiak ez izatea, eta agian ez da segurua haiek bertan gehitzea."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ados"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Erakutsi pantaila-babeslearen botoia"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Arakatu kontrol-zentro modua"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Erabili gogoko dituzun widgetak eta pantaila-babesleak gailua kargatu bitartean."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Has gaitezen"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Elkarrizketen jakinarazpenen goialdean eta profileko argazki gisa agertzen da pantaila blokeatuan, burbuila batean, eta ez molestatzeko modua eteten du"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Lehentasuna"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak ez ditu onartzen elkarrizketetarako eginbideak"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Baztertu"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ez erakutsi berriro"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Jakinarazpen horiek ezin dira aldatu."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Deien jakinarazpenak ezin dira aldatu."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Jakinarazpen talde hau ezin da konfiguratu hemen"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kalkulagailua"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Aktibatu/Desaktibatu tekla-sakatze errepikatuak"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Aktibatu/Desaktibatu saguaren teklak"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Aktibatu/Desaktibatu tekla itsaskorrak"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Aktibatu/Desaktibatu tekla motelak"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Aktibatu/Desaktibatu Voice Access"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ez molestatzeko modua"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Bolumen-botoietarako lasterbidea"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Erabili hatz-marka irekitzeko"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autentifikazioa behar da. Autentifikatzeko, ukitu hatz-marken sentsorea."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Deia abian"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Datu-konexioa"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Konektatuta"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Aldi baterako konektatuta"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Osatu duzu azkenaldiko aplikazioak ikusteko keinua."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Azkenaldiko aplikazioak ikusteko, pasatu 3 hatz gora eta eduki sakatuta ukipen-panelean"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Aldatu aplikazioa"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Pasatu 4 hatz eskuinera ukipen-panelean"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Bikain!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Ikasi duzu aplikazio batetik bestera aldatzeko keinua."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Pasatu 4 hatz eskuinera ukipen-panelean, aplikazioz aldatzeko"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ikusi aplikazio guztiak"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Sakatu teklatuko ekintza-tekla"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bikain!"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 2a3c3c0..1521914 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"درصد شارژ باتری مشخص نیست."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"به <xliff:g id="BLUETOOTH">%s</xliff:g> متصل شد."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"به <xliff:g id="CAST">%s</xliff:g> متصل شد."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"متصل نیست."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"فراگردی"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"خاموش"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"کاوش کردن حالت متصل"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"در حین شارژ، به ابزاره‌ها و محافظ‌های صفحه‌نمایش دلخواهتان دسترسی داشته باشید."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"بیایید شروع کنیم"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"در بالای اعلان‌های مکالمه و به‌صورت عکس نمایه در صفحه قفل نشان داده می‌شود، به‌صورت حبابک ظاهر می‌شود، در حالت «مزاحم نشوید» وقفه ایجاد می‌کند"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"اولویت"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> از ویژگی‌های مکالمه پشتیبانی نمی‌کند"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"بستن"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"دیگر نشان داده نشود"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"این اعلان‌ها قابل اصلاح نیستند."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"این اعلان‌ها قابل‌اصلاح نیستند."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"نمی‌توانید این گروه اعلان‌ها را در اینجا پیکربندی کنید"</string>
@@ -915,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"تقویم"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"ماشین‌حساب"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"تغییر وضعیت کلیدهای ضدتکرار"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"تغییر وضعیت کلیدهای موشواره"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"تغییر وضعیت کلیدهای چسبان"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"تغییر وضعیت کلیدهای آهسته"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"تغییر وضعیت «دسترسی صوتی»"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"مزاحم نشوید"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"میان‌بر دکمه‌های صدا"</string>
@@ -1304,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"از اثر انگشت برای باز کردن قفل استفاده کنید"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"اصالت‌سنجی لازم است. برای اصالت‌سنجی، حسگر اثر انگشت را لمس کنید."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"تماس درحال انجام"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"داده تلفن همراه"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"متصل است"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"موقتاً متصل است"</string>
@@ -1452,7 +1459,7 @@
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"دسترس‌پذیری"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"میان‌برهای صفحه‌کلید"</string>
     <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"سفارشی‌سازی میان‌برها"</string>
-    <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"میان‌بر حذف شود؟"</string>
+    <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"میان‌بر برداشته شود؟"</string>
     <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"به تنظیم پیش‌فرض بازنشانی می‌کنید؟"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"برای ایجاد این میان‌بر، دکمه «کنش» و یک یا چند دکمه دیگر را هم‌زمان فشار دهید."</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"با این کار، میان‌بر سفارشی شما برای همیشه حذف می‌شود."</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 67e0c28..caf8f29 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -252,6 +252,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akun varaustaso ei tiedossa."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Yhteys: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Yhdistetty kohteeseen <xliff:g id="CAST">%s</xliff:g>"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Ei yhteyttä."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Pois päältä"</string>
@@ -538,11 +542,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Jos haluat avata sovelluksen käyttämällä widgetiä, sinun täytyy vahvistaa henkilöllisyytesi. Muista myös, että widgetit näkyvät kaikille, vaikka tabletti olisi lukittuna. Jotkin widgetit on ehkä tarkoitettu lukitusnäytölle, ja niiden lisääminen tänne ei välttämättä ole turvallista."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Selvä"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Näytä näytönsäästäjän painike"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Tutustu hubitilaan"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Käytä suosikkiwidgetejä ja -näytönsäästäjiä latauksen aikana."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Aloitetaan"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -806,10 +809,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Näkyy keskusteluilmoitusten yläosassa ja profiilikuvana lukitusnäytöllä, näkyy kuplana, keskeyttää Älä häiritse ‑tilan"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Tärkeä"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei tue keskusteluominaisuuksia"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Hylkää"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Älä näytä uudelleen"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Näitä ilmoituksia ei voi muokata"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Puheluilmoituksia ei voi muokata."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Tätä ilmoitusryhmää ei voi määrittää tässä"</string>
@@ -920,15 +921,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalenteri"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Laskin"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Laita toistuvien painallusten ohitus päälle/pois"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Laita hiiren painikkeet päälle/pois"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Laita päälle jäävät näppäimet päälle/pois"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Laita hitaat näppäimet päälle/pois"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Access päälle/pois"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Älä häiritse"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Äänenvoimakkuuspainikkeiden pikanäppäin"</string>
@@ -1309,6 +1311,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Avaa sormenjäljellä"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Todennus vaaditaan. Todenna koskettamalla sormenjälkitunnistinta."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Käynnissä oleva puhelu"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobiilidata"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Yhdistetty"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Väliaikaisesti yhdistetty"</string>
@@ -1514,12 +1518,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Olet oppinut Katso viimeisimmät sovellukset ‑eleen."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Näet äskeiset sovellukset, kun pyyhkäiset ylös ja pidät kosketuslevyä painettuna kolmella sormella."</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Vaihda sovellusta"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Pyyhkäise kosketuslevyllä oikealle neljällä sormella"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Hienoa!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Olet oppinut sovelluksenvaihtoeleen."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Vaihda sovellusta pyyhkäisemällä kosketuslevyllä oikealle neljällä sormella"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Näytä kaikki sovellukset"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Paina näppäimistön toimintonäppäintä"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Hienoa!"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 5d0c67b..4595e10 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Pourcentage de la pile inconnu."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connecté à : <xliff:g id="BLUETOOTH">%s</xliff:g>"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Connecté à <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Non connecté"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Itinérance"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Désactivé"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Explorer le mode Console"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Accéder à vos widgets et écrans de veille préférés pendant le chargement."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Allons-y"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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 applis et les données de cette session seront supprimées."</string>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"S\'affiche dans le haut des notifications de conversation et comme photo de profil à l\'écran de verrouillage, s\'affiche comme bulle, interrompt le mode Ne pas déranger"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritaire"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ne prend pas en charge les fonctionnalités de conversation"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Fermer"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ne plus afficher"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ces notifications ne peuvent pas être modifiées"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Les notifications d\'appel ne peuvent pas être modifiées."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ce groupe de notifications ne peut pas être configuré ici"</string>
@@ -915,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculatrice"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Activer/Désactiver les touches non répétées"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Activer/Désactiver les touches de souris"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Activer/Désactiver les touches rémanentes"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Activer/Désactiver les touches lentes"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Activer/Désactiver l\'Accès vocal"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne pas déranger"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Raccourci des boutons de volume"</string>
@@ -1304,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Servez-vous de votre empreinte digitale pour ouvrir"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentification requise. Touchez le capteur d\'empreintes digitales pour vous authentifier."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Appel en cours"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Données cellulaires"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Connexion active"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Connectée temporairement"</string>
@@ -1475,7 +1482,7 @@
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Supprimer"</string>
     <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Oui, réinitialiser"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annuler"</string>
-    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Appuyez sur la touche"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Appuyez sur une ou des touches"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="3325858369539848162">"La combinaison de touches est déjà utilisée. Essayez une autre combinaison."</string>
     <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Le raccourci ne peut pas être défini."</string>
     <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 3899576..b2e0edc 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -225,7 +225,7 @@
     <string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"Ceci est obligatoire pour améliorer la sécurité et les performances"</string>
     <string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"Reconfigurer le déverrouillage par empreinte digitale"</string>
     <string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"Empreinte digitale"</string>
-    <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Configurer le déverrouillage par empreinte digitale"</string>
+    <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Configurez déverr. par empreinte digitale"</string>
     <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"Pour reconfigurer le déverrouillage par empreinte digitale, les images et modèles actuels de votre empreinte digitale seront supprimés.\n\nAprès leur suppression, vous devrez reconfigurer le déverrouillage par empreinte digitale pour déverrouiller votre téléphone ou confirmer votre identité avec votre empreinte digitale."</string>
     <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"Pour reconfigurer le déverrouillage par empreinte digitale, les images et le modèle actuels de votre empreinte digitale seront supprimés.\n\nAprès leur suppression, vous devrez reconfigurer le déverrouillage par empreinte digitale pour déverrouiller votre téléphone ou confirmer votre identité avec votre empreinte digitale."</string>
     <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Impossible de configurer le déverrouillage par empreinte digitale. Accédez aux paramètres pour réessayer."</string>
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Pourcentage de la batterie inconnu."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connecté à : <xliff:g id="BLUETOOTH">%s</xliff:g>"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Connecté à <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Non connecté"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Itinérance"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Désactivées"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Découvrir le mode Hub"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Accédez à vos widgets et économiseurs d\'écran préférés lorsque l\'appareil est en charge."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"C\'est parti"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -880,7 +886,7 @@
     <string name="group_system_access_home_screen" msgid="4130366993484706483">"Accéder à l\'écran d\'accueil"</string>
     <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Afficher les applis récentes"</string>
     <string name="group_system_cycle_forward" msgid="5478663965957647805">"Faire défiler les applications récentes"</string>
-    <string name="group_system_cycle_back" msgid="8194102916946802902">"Faire défiler les applications récentes à l\'envers"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Revenir en arrière dans les applications récentes"</string>
     <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Ouvrir la liste d\'applications"</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>
@@ -913,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculatrice"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Activer/Désactiver les touches filtres"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Activer/Désactiver les touches pour la souris"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Activer/Désactiver les touches rémanentes"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Activer/Désactiver les touches lentes"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Activer/Désactiver Voice Access"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne pas déranger"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Raccourci des boutons de volume"</string>
@@ -1302,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Utilisez votre empreinte pour ouvrir"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentification requise. Appuyez sur le lecteur d\'empreintes digitales pour vous authentifier."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Appel en cours"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Données mobiles"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Connecté"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Connexion temporaire"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 5632327..eef5c91 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Descoñécese a porcentaxe da batería."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Dispositivo conectado: <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Non conectada"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Itinerancia"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Desactivados"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir unha aplicación mediante un widget, tes que verificar a túa identidade. Ten en conta que pode velos calquera persoa, mesmo coa tableta bloqueada. Pode ser que algúns widgets non estean pensados para a túa pantalla de bloqueo, polo que talvez non sexa seguro engadilos aquí."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendido"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Botón para mostrar o protector de pantalla"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Explorar o modo Hub"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Accede aos teus widgets e protectores de pantalla favoritos durante a carga."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Comezar"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Móstrase na parte superior das notificacións das conversas e como imaxe do perfil na pantalla de bloqueo, aparece como unha burbulla e interrompe o modo Non molestar"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> non admite funcións de conversa"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Pechar"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Non volver mostrar"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Estas notificacións non se poden modificar."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"As notificacións de chamadas non se poden modificar."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Aquí non se pode configurar este grupo de notificacións"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculadora"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Activar ou desactivar as teclas de rebote"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Activar ou desactivar as teclas do rato"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Activar ou desactivar as teclas presas"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Activar ou desactivar as teclas lentas"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Activar ou desactivar Voice Access"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Non molestar"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Atallo dos botóns de volume"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Usa a impresión dixital para abrir"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Requírese autenticación. Para autenticarte, toca o sensor de impresión dixital."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Chamada en curso"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Datos móbiles"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Conectada"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Conectada temporalmente"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Completaches o titorial do xesto de consultar aplicacións recentes."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Para ver as aplicacións recentes, pasa tres dedos cara arriba e mantenos premidos no panel táctil"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Cambiar de aplicación"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Pasa catro dedos cara á dereita no panel táctil"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Bravo!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Completaches o xesto para cambiar de aplicación."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Pasa catro dedos cara á dereita no panel táctil para cambiar de aplicación"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todas as aplicacións"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Preme a tecla de acción do teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Ben feito!"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 5c41423..0ba9cf4 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"બૅટરીની ટકાવારી અજાણ છે."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> થી કનેક્ટ થયાં."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> થી કનેક્ટ કરેલ."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"કનેક્ટ થયેલું નથી."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"રોમિંગ"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"બંધ કરો"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"વિજેટનો ઉપયોગ કરીને ઍપ ખોલવા માટે, તમારે એ ચકાસણી કરવાની જરૂર રહેશે કે આ તમે જ છો. તે ઉપરાંત, ધ્યાનમાં રાખો કે તમારું ટૅબ્લેટ લૉક કરેલું હોય તો પણ કોઈપણ વ્યક્તિ તેમને જોઈ શકે છે. અમુક વિજેટ કદાચ તમારી લૉક સ્ક્રીન માટે બનાવવામાં આવ્યા ન હોઈ શકે છે અને તેમને અહીં ઉમેરવાનું અસલામત હોઈ શકે છે."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"સમજાઈ ગયું"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"સ્ક્રીનસેવર બટન બતાવો"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"હબ મોડ શોધખોળ કરો"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"ચાર્જ કરતી વખતે તમારા મનપસંદ વિજેટ અને સ્ક્રીન સેવર ઍક્સેસ કરો."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"ચાલો પ્રારંભ કરીએ"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"વપરાશકર્તા સ્વિચ કરો"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"પુલડાઉન મેનૂ"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"વાતચીતના નોટિફિકેશન વિભાગની ટોચ પર અને લૉક કરેલી સ્ક્રીન પર પ્રોફાઇલ ફોટો તરીકે બતાવે છે, બબલ તરીકે દેખાય છે, ખલેલ પાડશો નહીં મોડમાં વિક્ષેપ ઊભો કરે છે"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"પ્રાધાન્યતા"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> વાતચીતની સુવિધાઓને સપોર્ટ આપતી નથી"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"છોડી દો"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"ફરી બતાવશો નહીં"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"આ નોટિફિકેશનમાં કોઈ ફેરફાર થઈ શકશે નહીં."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"કૉલના નોટિફિકેશનમાં કોઈ ફેરફાર કરી શકાતો નથી."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"નોટિફિકેશનના આ ગ્રૂપની ગોઠવણી અહીં કરી શકાશે નહીં"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"કેલ્ક્યુલેટર"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"બાઉન્સ કીને ટૉગલ કરો"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"માઉસ કીને ટૉગલ કરો"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"સ્ટીકી કીને ટૉગલ કરો"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"ધીમી કીને ટૉગલ કરો"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Accessને ટૉગલ કરો"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ખલેલ પાડશો નહીં"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"વૉલ્યૂમ બટન્સ શૉર્ટકટ"</string>
@@ -973,12 +975,12 @@
     <string name="tuner_time" msgid="2450785840990529997">"સમય"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"કલાક, મિનિટ અને સેકન્ડ બતાવો"</item>
-    <item msgid="1271006222031257266">"કલાક અને મિનિટ બતાવો (ડિફોલ્ટ)"</item>
+    <item msgid="1271006222031257266">"કલાક અને મિનિટ બતાવો (ડિફૉલ્ટ)"</item>
     <item msgid="6135970080453877218">"આ આઇકન બતાવશો નહીં"</item>
   </string-array>
   <string-array name="battery_options">
     <item msgid="7714004721411852551">"હંમેશાં ટકાવારી બતાવો"</item>
-    <item msgid="3805744470661798712">"ચાર્જ થાય ત્યારે ટકાવારી બતાવો (ડિફોલ્ટ)"</item>
+    <item msgid="3805744470661798712">"ચાર્જ થાય ત્યારે ટકાવારી બતાવો (ડિફૉલ્ટ)"</item>
     <item msgid="8619482474544321778">"આ આઇકન બતાવશો નહીં"</item>
   </string-array>
     <string name="tuner_low_priority" msgid="8412666814123009820">"ઓછી પ્રાધાન્યતાનું નોટિફિકેશન આઇકન બતાવો"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ખોલવા માટે ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"પ્રમાણીકરણ આવશ્યક છે. પ્રમાણિત કરવા માટે ફિંગરપ્રિન્ટ સેન્સરને ટચ કરો."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"ચાલુ કૉલ"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"મોબાઇલ ડેટા"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"કનેક્ટ કરેલું"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"હંગામી રીતે કનેક્ટ કર્યું"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"તમે \'તાજેતરની ઍપ જુઓ\' સંકેત પૂર્ણ કર્યો."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"તાજેતરની ઍપ જોવા માટે, તમારા ટચપૅડ પર ત્રણ આંગળી વડે ઉપરની તરફ સ્વાઇપ કરો અને દબાવી રાખો"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"ઍપ સ્વિચ કરો"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"તમારા ટચપૅડ પર ચાર આંગળીઓનો ઉપયોગ કરીને જમણે સ્વાઇપ કરો"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"ખૂબ સરસ કામ!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"તમે ઍપ સ્વિચ કરવાનો સંકેત પૂર્ણ કર્યો છે."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"ઍપ સ્વિચ કરવા માટે, તમારા ટચપૅડ પર ચાર આંગળીઓનો ઉપયોગ કરીને જમણે સ્વાઇપ કરો"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"બધી ઍપ જુઓ"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"તમારા કીબોર્ડ પરની ઍક્શન કી દબાવો"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"વાહ!"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 221327c..8b301fd 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"इस बारे में जानकारी नहीं है कि अभी बैटरी कितने प्रतिशत चार्ज है."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> से कनेक्ट किया गया."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> से कनेक्ट है."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"कनेक्ट नहीं है."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"रोमिंग"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"बंद है"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"किसी विजेट से कोई ऐप्लिकेशन खोलने के लिए, आपको अपनी पहचान की पुष्टि करनी होगी. ध्यान रखें कि आपके टैबलेट के लॉक होने पर भी, कोई व्यक्ति विजेट देख सकता है. ऐसा हो सकता है कि कुछ विजेट, लॉक स्क्रीन पर दिखाने के लिए न बने हों. इन्हें लॉक स्क्रीन पर जोड़ना असुरक्षित हो सकता है."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ठीक है"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"स्क्रीन सेवर दिखाने का बटन"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"हब मोड को एक्सप्लोर करें"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"चार्जिंग के दौरान, अपने पसंदीदा विजेट और स्क्रीन सेवर को ऐक्सेस करें."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"आइए शुरू करें"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"उपयोगकर्ता बदलें"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेन्यू"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"यह कई तरीकों से दिखती है, जैसे कि बातचीत वाली सूचनाओं में सबसे ऊपर, बबल के तौर पर, और लॉक स्क्रीन पर प्रोफ़ाइल फ़ोटो के तौर पर. साथ ही, यह \'परेशान न करें\' मोड को बायपास कर सकती है"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"प्राथमिकता"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> पर बातचीत की सुविधाएं काम नहीं करतीं"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"खारिज करें"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"फिर से न दिखाएं"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ये सूचनाएं नहीं बदली जा सकती हैं."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"कॉल से जुड़ी सूचनाओं को ब्लॉक नहीं किया जा सकता."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"सूचनाओं के इस समूह को यहां कॉन्फ़िगर नहीं किया जा सकता"</string>
@@ -918,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"कैलकुलेटर"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"मैप"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"बाउंस बटन को टॉगल करें"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"कीबोर्ड पर माउस के बटन को टॉगल करें"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"स्टिकी बटन को टॉगल करें"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"स्लो बटन को टॉगल करें"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Access को टॉगल करें"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"TalkBack को टॉगल करें"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"ज़ूम करने की सुविधा टॉगल करें"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"\'चुनें और सुनें\' सुविधा चालू करें"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"परेशान न करें"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"वॉल्यूम बटन का शॉर्टकट"</string>
     <string name="battery" msgid="769686279459897127">"बैटरी"</string>
@@ -1307,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"खोलने के लिए, फ़िंगरप्रिंट का इस्तेमाल करें"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"पुष्टि करना ज़रूरी है. पुष्टि करने के लिए, फ़िंगरप्रिंट सेंसर को छुएं."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"पहले से जारी कॉल"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"मोबाइल डेटा"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"कनेक्ट हो गया"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"इंटरनेट कनेक्शन कुछ समय के लिए है"</string>
@@ -1454,9 +1455,9 @@
     <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"मौजूदा ऐप्लिकेशन"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सुलभता"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string>
-    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"पसंद के मुताबिक शॉर्टकट बनाएं"</string>
+    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"शॉर्टकट पसंद के मुताबिक बनाएं"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"क्या आपको शॉर्टकट हटाना है?"</string>
-    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"क्या आपको फिर से डिफ़ॉल्ट सेटिंग चालू करनी है?"</string>
+    <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"क्या आपको फिर से डिफ़ॉल्ट शॉर्टकट चालू करने हैं?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"यह शॉर्टकट बनाने के लिए, ऐक्शन बटन और एक या उससे ज़्यादा अन्य बटन एक साथ दबाएं"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"ऐसा करने पर, पसंद के मुताबिक बनाया गया आपका शॉर्टकट हमेशा के लिए मिट जाएगा."</string>
     <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"ऐसा करने पर, पसंद के मुताबिक बनाए गए आपके सभी शॉर्टकट हमेशा के लिए मिट जाएंगे."</string>
@@ -1512,12 +1513,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"अब आपको हाथ के जेस्चर का इस्तेमाल करके, हाल ही में इस्तेमाल किए गए ऐप्लिकेशन देखने का तरीका पता चल गया है."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"हाल ही में इस्तेमाल किए गए ऐप्लिकेशन देखने के लिए, अपने टचपैड पर तीन उंगलियों से ऊपर की ओर स्वाइप करें और दबाकर रखें"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"ऐप्लिकेशन के बीच स्विच करें"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"अपने टचपैड पर चार उंगलियों से दाईं ओर स्वाइप करें"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"बहुत बढ़िया!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"आपने जान लिया है कि हाथ का जेस्चर इस्तेमाल करके ऐप्लिकेशन के बीच स्विच कैसे करें."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"ऐप्लिकेशन स्विच करने के लिए, अपने टचपैड पर चार उंगलियों से दाईं ओर स्वाइप करें"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"सभी ऐप्लिकेशन देखें"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"अपने कीबोर्ड पर ऐक्शन बटन दबाएं"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"बहुत खूब!"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 60b39a4..86e5098 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Postotak baterije nije poznat."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Spojen na <xliff:g id="BLUETOOTH">%s</xliff:g> ."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Povezani ste sa sljedećim uređajem: <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Nije povezano."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Isključeno"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Istraži način Huba"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Pristupite omiljenim widgetima i čuvarima zaslona tijekom punjenja."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Započnimo"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Prikazuje se pri vrhu obavijesti razgovora i kao profilna slika na zaključanom zaslonu, izgleda kao oblačić, prekida Ne uznemiravaj"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritetno"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava značajke razgovora"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Odbaci"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ne prikazuj ponovo"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Te se obavijesti ne mogu izmijeniti."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Obavijesti o pozivima ne mogu se izmijeniti."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ta se grupa obavijesti ne može konfigurirati ovdje"</string>
@@ -915,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kalkulator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Karte"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Uključivanje/isključivanje zanemarivanja slučajnih pritisaka tipki"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Uključivanje/isključivanje tipki za pokrete mišem"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Uključivanje/isključivanje ljepljivih tipki"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Uključivanje/isključivanje sporih tipki"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Uključivanje/isključivanje Glasovnog pristupa"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Uključi/isključi TalkBack"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Uključi/isključi povećavanje"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"Aktiviraj Odabir za govor"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne uznemiravaj"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Prečac tipki za glasnoću"</string>
     <string name="battery" msgid="769686279459897127">"Baterija"</string>
@@ -1304,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Otvorite pomoću otiska prsta"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Potrebna je autentifikacija. Dodirnite senzor otiska prsta da biste se autentificirali."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Poziv u tijeku"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobilni podaci"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Povezano"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Privremeno povezano"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 568c872..bbe5b65 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Az akkumulátor töltöttségi szintje ismeretlen."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Csatlakoztatva a következőhöz: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Csatlakozva a következőhöz: <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Nincs csatlakozva."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Ki"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"A Hub mód felfedezése"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Töltés közben hozzáférhet kedvenc moduljaihoz és képernyőkímélőihez."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Kezdés"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"A beszélgetésekre vonatkozó értesítések tetején, lebegő buborékként látható, megjeleníti a profilképet a lezárási képernyőn, és megszakítja a Ne zavarjanak funkciót"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritás"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> nem támogatja a beszélgetési funkciókat"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Elvetés"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ne jelenjen meg újra"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ezeket az értesítéseket nem lehet módosítani."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"A hívásértesítéseket nem lehet módosítani."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Az értesítések jelen csoportját itt nem lehet beállítani"</string>
@@ -915,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Naptár"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Számológép"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Térkép"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Billentyűblokkolás be- és kikapcsolása"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Egérgombok be- és kikapcsolása"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Beragadó billentyűk be- és kikapcsolása"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Lassú billentyűk be- és kikapcsolása"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Hangalapú hozzáférés be- és kikapcsolása"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"TalkBack be- vagy kikapcsolása"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Nagyítás bekapcsolása"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"Felolvasás aktiválása"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne zavarjanak"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"A hangerőgombok gyorsbillentyűk"</string>
     <string name="battery" msgid="769686279459897127">"Akkumulátor"</string>
@@ -1304,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Ujjlenyomat használata a megnyitáshoz"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Hitelesítés szükséges. Érintse meg az ujjlenyomat-érzékelőt a hitelesítéshez."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Hívás folyamatban"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobiladat"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Csatlakozva"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Ideiglenesen csatlakoztatva"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 60b445f..6d179c0d 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Մարտկոցի լիցքի մակարդակն անհայտ է։"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Միացված է <xliff:g id="BLUETOOTH">%s</xliff:g>-ին:"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Միացված է <xliff:g id="CAST">%s</xliff:g>-ին:"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Միացված չէ:"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Ռոումինգ"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Անջատված է"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Վիջեթի միջոցով հավելված բացելու համար դուք պետք է հաստատեք ձեր ինքնությունը։ Նաև նկատի ունեցեք, որ ցանկացած ոք կարող է դիտել վիջեթները, նույնիսկ երբ ձեր պլանշետը կողպված է։ Որոշ վիջեթներ կարող են նախատեսված չլինել ձեր կողպէկրանի համար, և այստեղ դրանց ավելացնելը կարող է վտանգավոր լինել։"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Եղավ"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"«Ցույց տալ էկրանապահը» կոճակ"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Բացահայտեք հանգույցի ռեժիմը"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Օգտագործեք ձեր սիրած վիջեթները և էկրանապահները, մինչ ձեր սարքը լիցքավորվում է։"</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Սկսել"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Անջատել օգտվողին"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"իջնող ընտրացանկ"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Ցուցադրվում է զրույցների ծանուցումների վերևում, ինչպես նաև կողպէկրանին որպես պրոֆիլի նկար, հայտնվում է ամպիկի տեսքով, ընդհատում է «Չանհանգստացնել» ռեժիմը"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Կարևոր"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը զրույցի գործառույթներ չի աջակցում"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Փակել"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Այլևս ցույց չտալ"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Այս ծանուցումները չեն կարող փոփոխվել:"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Զանգերի մասին ծանուցումները հնարավոր չէ փոփոխել։"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ծանուցումների տվյալ խումբը հնարավոր չէ կարգավորել այստեղ"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Օրացույց"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Հաշվիչ"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Քարտեզներ"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Միացնել/անջատել կրկնվող սեղմումների անտեսումը"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Միացնել/անջատել մկնիկի ստեղները"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Միացնել/անջատել կպչուն ստեղները"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Միացնել/անջատել ստեղների երկար սեղմումը"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Միացնել/անջատել Voice Access-ը"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Չանհանգստացնել"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Ձայնի կոճակների դյուրանցում"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Բացելու համար օգտագործեք մատնահետքը"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Պահանջվում է նույնականացում։ Դրա համար մատը հպեք մատնահետքի սկաներին։"</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Ընթացիկ զանգ"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Բջջային ինտերնետ"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Միացած է"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Ժամանակավոր կապ"</string>
@@ -1448,8 +1452,7 @@
     <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Համակարգային հավելվածներ"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Բազմա­խնդրու­թ­յուն"</string>
     <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Տրոհված էկրան"</string>
-    <!-- no translation found for shortcutHelper_category_accessibility (8068337792277570938) -->
-    <skip />
+    <string name="shortcutHelper_category_accessibility" msgid="8068337792277570938">"Հատուկ գործառույթներ"</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_current_app_shortcuts" msgid="4017840565974573628">"Այս հավելվածը"</string>
@@ -1513,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Դուք կատարեցիք վերջին օգտագործված հավելվածների դիտման ժեստը։"</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Վերջին հավելվածները տեսնելու համար երեք մատը սահեցրեք վերև և սեղմած պահեք հպահարթակին"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Անցում մեկ հավելվածից մյուսին"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Հպահարթակի վրա չորս մատով սահեցրեք աջ"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Կեցցե՛ք։"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Դուք սովորեցիք ուրիշ հավելված անցնելու ժեստը։"</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Մեկ հավելվածից մյուսին անցնելու համար հպահարթակի վրա չորս մատով սահեցրեք աջ"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ինչպես դիտել բոլոր հավելվածները"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Սեղմեք գործողության ստեղնը ստեղնաշարի վրա"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Հիանալի՛ է"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 0a6baca..e6695bd 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Persentase baterai tidak diketahui."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Terhubung ke <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Terhubung ke <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Tidak terhubung."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Nonaktif"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Untuk membuka aplikasi menggunakan widget, Anda perlu memverifikasi diri Anda. Selain itu, harap ingat bahwa siapa saja dapat melihatnya, bahkan saat tablet Anda terkunci. Beberapa widget mungkin tidak dirancang untuk layar kunci Anda dan mungkin tidak aman untuk ditambahkan di sini."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Oke"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Tampilkan tombol screensaver"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Jelajahi mode hub"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Akses widget dan screensaver favorit Anda saat mengisi daya."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Mulai"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Muncul teratas di notifikasi percakapan dan sebagai foto profil di layar kunci, ditampilkan sebagai balon, menimpa mode Jangan Ganggu"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritas"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak mendukung fitur percakapan"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Tutup"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Jangan tampilkan lagi"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Notifikasi ini tidak dapat diubah."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Notifikasi panggilan tidak dapat diubah."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Grup notifikasi ini tidak dapat dikonfigurasi di sini"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kalkulator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Aktifkan/nonaktifkan tombol pantul"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Aktifkan/nonaktifkan tombol mouse"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Aktifkan/nonaktifkan tombol lekat"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Aktifkan/nonaktifkan tombol lambat"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Aktifkan/nonaktifkan Voice Access"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Jangan Ganggu"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Pintasan tombol volume"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Gunakan sidik jari untuk membuka"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Perlu autentikasi. Sentuh sensor sidik jari untuk melakukan autentikasi."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Panggilan sedang berlangsung"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Data seluler"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Terhubung"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Terhubung sementara"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Anda telah menyelesaikan gestur untuk melihat aplikasi terbaru."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Untuk melihat aplikasi terbaru, geser ke atas dan tahan menggunakan tiga jari di touchpad"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Beralih aplikasi"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Geser ke kanan menggunakan empat jari di touchpad"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Bagus!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Anda telah menyelesaikan gestur beralih aplikasi."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Geser ke kanan menggunakan empat jari di touchpad untuk beralih aplikasi"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Lihat semua aplikasi"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tekan tombol tindakan di keyboard"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Oke!"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 46c8452..fd2d666 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Staða rafhlöðu óþekkt."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Tengt við <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Tengt við <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Engin tenging."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Reiki"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Slökkt"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Þú þarft að staðfesta að þetta sért þú til að geta opnað forrit með græju. Hafðu einnig í huga að hver sem er getur skoðað þær, jafnvel þótt spjaldtölvan sé læst. Sumar græjur eru hugsanlega ekki ætlaðar fyrir lásskjá og því gæti verið óöruggt að bæta þeim við hér."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ég skil"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Hnappurinn „Sýna skjávara“"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Kynntu þér dokkustillingu"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Hafðu aðgang að uppáhaldsgræjunum og -skjávörunum þínum á meðan tækið er í hleðslu."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Kýlum á þetta"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Birtist efst í samtalstilkynningum og sem prófílmynd á lásskjánum. Birtist sem blaðra sem truflar „Ónáðið ekki“"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Forgangur"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> styður ekki samtalseiginleika"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Loka"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ekki sýna aftur"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ekki er hægt að breyta þessum tilkynningum."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Ekki er hægt að breyta tilkynningum um símtöl."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ekki er hægt að stilla þessar tilkynningar hér"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Dagatal"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Reiknivél"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Kort"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Velja/afvelja endurkastslykla"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Velja/afvelja músarlykla"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Velja/afvelja festilykla"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Velja/afvelja hæga lykla"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Velja/afvelja Raddskipanir"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ónáðið ekki"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Flýtihnappar fyrir hljóðstyrk"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Opna með fingrafari"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Auðkenningar krafist. Auðkenndu með því að snerta fingrafaralesarann."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Símtal í gangi"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Farsímagögn"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Tengt"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Tímabundin tenging"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Þú framkvæmdir bendinguna til að sjá nýleg forrit."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Strjúktu upp og haltu þremur fingrum inni á snertifletinum til að sjá nýleg forrit"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Að skipta á milli forrita"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Strjúktu til hægri á snertifletinum með fjórum fingrum"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Vel gert!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Þú framkvæmdir bendinguna til að skipta á milli forrita."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Strjúktu til hægri á snertifletinum með fjórum fingrum til að skipta á milli forrita"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Sjá öll forrit"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Ýttu á aðgerðalykilinn á lyklaborðinu"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Vel gert!"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 30ad41f6..8754612 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Percentuale della batteria sconosciuta."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connesso a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Connesso a: <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Non connesso."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Off"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Per aprire un\'app utilizzando un widget, dovrai verificare la tua identità. Inoltre tieni presente che chiunque può vederlo, anche quando il tablet è bloccato. Alcuni widget potrebbero non essere stati progettati per la schermata di blocco e potrebbe non essere sicuro aggiungerli qui."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ok"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Pulsante Mostra salvaschermo"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Esplora la modalità Hub"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Accedi ai tuoi widget e salvaschermo preferiti durante la ricarica."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Iniziamo"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Appare in cima alle notifiche delle conversazioni, come immagine del profilo nella schermata di blocco e sotto forma di bolla, inoltre interrompe la modalità Non disturbare"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priorità"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> non supporta le funzionalità delle conversazioni"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Ignora"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Non mostrare più"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Impossibile modificare queste notifiche."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Impossibile modificare gli avvisi di chiamata."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Qui non è possibile configurare questo gruppo di notifiche"</string>
@@ -881,7 +882,7 @@
     <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Visualizza notifiche"</string>
     <string name="group_system_full_screenshot" msgid="5742204844232667785">"Acquisisci screenshot"</string>
     <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Mostra scorciatoie"</string>
-    <string name="group_system_go_back" msgid="2730322046244918816">"Indietro"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Torna indietro"</string>
     <string name="group_system_access_home_screen" msgid="4130366993484706483">"Vai alla schermata Home"</string>
     <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Visualizza app recenti"</string>
     <string name="group_system_cycle_forward" msgid="5478663965957647805">"Spostati avanti tra le app recenti"</string>
@@ -918,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendario"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calcolatrice"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Attiva/disattiva antirimbalzo dei tasti"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Attiva/disattiva tasti mouse"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Attiva/disattiva tasti permanenti"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Attiva/disattiva tasti lenti"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Attiva/disattiva Voice Access"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Attiva/disattiva TalkBack"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Attiva/disattiva ingrandimento"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"Attiva Seleziona per ascoltare"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Non disturbare"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Pulsanti del volume come scorciatoia"</string>
     <string name="battery" msgid="769686279459897127">"Batteria"</string>
@@ -1307,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Usa l\'impronta per aprire"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autenticazione obbligatoria. Eseguila toccando il sensore di impronte digitali."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Chiamata in corso"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Dati mobili"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Connessa"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Connessa temporaneamente"</string>
@@ -1512,12 +1513,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Hai completato il gesto Visualizza app recenti."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Per visualizzare le app recenti, scorri verso l\'alto e tieni premuto con tre dita sul touchpad"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Cambia app"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Scorri verso destra con quattro dita sul touchpad"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Ottimo lavoro."</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Hai completato il gesto Cambia app."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Scorri verso destra con quattro dita sul touchpad per cambiare app"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Visualizza tutte le app"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Premi il tasto azione sulla tastiera"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Ben fatto!"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index df56148..8828079 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -231,7 +231,7 @@
     <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"לא ניתן להגדיר ביטול נעילה בטביעת אצבע. יש לעבור להגדרות כדי לנסות שוב."</string>
     <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"הגדרה חוזרת של \'פתיחה ע\"י זיהוי הפנים\'"</string>
     <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"פתיחה בזיהוי פנים"</string>
-    <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"להגדרת התכונה \'פתיחה ע\"י זיהוי הפנים\'"</string>
+    <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"הגדרת \"פתיחה בזיהוי פנים\""</string>
     <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"כדי להגדיר שוב את התכונה \'פתיחה ע\"י זיהוי הפנים\', עליך למחוק את התבנית הנוכחית לזיהוי הפנים.\n\nיהיה צורך להגדיר את התכונה הזו שוב כדי להשתמש בזיהוי הפנים לביטול הנעילה של הטלפון."</string>
     <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"לא ניתן להגדיר פתיחה ע\"י זיהוי הפנים. צריך לעבור להגדרות כדי לנסות שוב."</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"צריך לגעת בחיישן טביעות האצבע"</string>
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"אחוז טעינת הסוללה לא ידוע."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"התבצע חיבור אל <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"מחובר אל <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"אין חיבור."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"נדידה"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"כבוי"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"כדי לפתוח אפליקציה באמצעות ווידג\'ט, עליך לאמת את זהותך. בנוסף, כדאי לזכור שכל אחד יכול לראות את הווידג\'טים גם כשהטאבלט שלך נעול. יכול להיות שחלק מהווידג\'טים לא נועדו למסך הנעילה ושלא בטוח להוסיף אותם לכאן."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"הבנתי"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"כפתור להצגת שומר המסך"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"‏האפשרויות במצב Hub"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"אפשר לגשת לווידג\'טים ולשומרי המסך בזמן הטעינה."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"שנתחיל?"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"החלפת משתמש"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"תפריט במשיכה למטה"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"מוצגת בחלק העליון של קטע התראות השיחה וכתמונת פרופיל במסך הנעילה, מופיעה בבועה צפה ומפריעה במצב \'נא לא להפריע\'"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"בעדיפות גבוהה"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> לא תומכת בתכונות השיחה"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"סגירה"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"לא להציג את זה שוב"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"לא ניתן לשנות את ההתראות האלה."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"לא ניתן לשנות את התראות השיחה."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"לא ניתן להגדיר כאן את קבוצת ההתראות הזו"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"יומן"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"מחשבון"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"מפות"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"הפעלה או השבתה של סינון הקשות חוזרות"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"הפעלה או השבתה של שליטה בעכבר מהמקלדת"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"הפעלה או השבתה של מקשים \"דביקים\""</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"הפעלה או השבתה של מקשים איטיים"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"‏הפעלה או השבתה של Voice Access"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"נא לא להפריע"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"קיצור דרך לכפתורי עוצמת קול"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"שימוש בטביעת אצבע כדי לפתוח"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"נדרש אימות. יש לגעת בחיישן טביעות האצבע כדי לבצע אימות."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"שיחה פעילה"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"חבילת גלישה"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"מחובר"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"מחובר באופן זמני"</string>
@@ -1474,11 +1478,11 @@
     <string name="shortcut_helper_key_combinations_forward_slash" msgid="1238652537199346970">"קו נטוי"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"נקודת האחיזה לגרירה"</string>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"הגדרות המקלדת"</string>
-    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"הגדרה של מקש קיצור"</string>
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"הגדרת מקש קיצור"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"הסרה"</string>
     <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"כן, לאפס"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ביטול"</string>
-    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"יש ללחוץ על מקש"</string>
+    <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"צריך ללחוץ על מקש"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="3325858369539848162">"שילוב המקשים הזה תפוס. צריך לנסות שילוב אחר."</string>
     <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"לא ניתן להגדיר את קיצור הדרך."</string>
     <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"סיימת לתרגל את התנועה להצגת האפליקציות האחרונות."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"כדי לראות את האפליקציות האחרונות, צריך להחליק למעלה וללחוץ לחיצה ארוכה עם שלוש אצבעות על לוח המגע"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"מעבר בין אפליקציות"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"מחליקים ימינה עם ארבע אצבעות על לוח המגע"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"מעולה!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"השלמת את תנועת המעבר בין האפליקציות."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"כדי לעבור בין אפליקציות, מחליקים ימינה עם ארבע אצבעות על לוח המגע"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"צפייה בכל האפליקציות"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"צריך להקיש על מקש הפעולה במקלדת"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"כל הכבוד!"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index d588590..c760827 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"バッテリー残量は不明です。"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>に接続しました。"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>に接続されています。"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"接続されていません。"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"ローミング"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"OFF"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"ハブモードの詳細を見る"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"充電中にお気に入りのウィジェットやスクリーン セーバーにアクセスできます。"</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"使ってみる"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"会話通知の一番上に表示されると同時に、ロック画面にプロフィール写真として表示されるほか、バブルとして表示され、サイレント モードが中断されます"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"優先"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>は会話機能に対応していません"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"閉じる"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"次回から表示しない"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"これらの通知は変更できません。"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"着信通知は変更できません。"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"このグループの通知はここでは設定できません"</string>
@@ -882,7 +886,7 @@
     <string name="group_system_access_home_screen" msgid="4130366993484706483">"ホーム画面に移動する"</string>
     <string name="group_system_overview_open_apps" msgid="5659958952937994104">"最近使ったアプリを表示する"</string>
     <string name="group_system_cycle_forward" msgid="5478663965957647805">"最近使ったアプリを確認する"</string>
-    <string name="group_system_cycle_back" msgid="8194102916946802902">"最近使ったアプリを確認する(逆方向)"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"最近使ったアプリをさかのぼって確認する"</string>
     <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"アプリの一覧を開く"</string>
     <string name="group_system_access_system_settings" msgid="8731721963449070017">"設定を開く"</string>
     <string name="group_system_access_google_assistant" msgid="7210074957915968110">"アシスタントを開く"</string>
@@ -915,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"カレンダー"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"電卓"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"マップ"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"バウンスキーを切り替える"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"マウスキーを切り替える"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"固定キーを切り替える"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"スローキーを切り替える"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Access を切り替える"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"TalkBack を切り替える"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"拡大を切り替える"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"「選択して読み上げ」を有効にする"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"サイレント モード"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"音量ボタンのショートカット"</string>
     <string name="battery" msgid="769686279459897127">"バッテリー"</string>
@@ -1304,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"指紋を使って開いてください"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"認証が必要です。指紋認証センサーをタッチして認証してください。"</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"通話中"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"モバイルデータ"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"接続済み"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"一時的に接続されています"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 1a2d2be..0b700df 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ბატარეის პროცენტული მაჩვენებელი უცნობია."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"დაკავშირებულია <xliff:g id="BLUETOOTH">%s</xliff:g>-თან."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"დაკავშირებულია მოწყობილობასთან: <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"არ არის დაკავშირებული."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"როუმინგი"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"გამორთული"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"ჰაბის რეჟიმის დათვალიერება"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"დატენის დროს შეგიძლიათ თქვენს რჩეულ ვიჯეტებზე და ეკრანმზოგებზე წვდომა."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"დავიწყოთ"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"გამოჩნდება საუბრის შეტყობინებების თავში და პროფილის სურათის სახით ჩაკეტილ ეკრანზე, ჩნდება ბუშტის სახით, წყვეტს ფუნქციას „არ შემაწუხოთ“"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"პრიორიტეტი"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ს არ აქვს მიმოწერის ფუნქციების მხარდაჭერა"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"დახურვა"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"აღარ მაჩვენო"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ამ შეტყობინებების შეცვლა შეუძლებელია."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ზარის შეტყობინებების შეცვლა შეუძლებელია."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"შეტყობინებების ამ ჯგუფის კონფიგურირება აქ შეუძლებელია"</string>
@@ -915,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"კალენდარი"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"კალკულატორი"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"კლავიშების ასხლეტის გადართვა"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"მაუსის კლავიშების გადართვა"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"კლავიშების ფიქსაციის გადართვა"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"ნელი კლავიშების გადართვა"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"ხმოვანი წვდომის გადართვა"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Talkback-ის გადართვა"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"გადიდების გადართვა"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"წარმოსათქმელად მონიშვნის გააქტიურება"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"არ შემაწუხოთ"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ხმის ღილაკების მალსახმობი"</string>
     <string name="battery" msgid="769686279459897127">"ბატარეა"</string>
@@ -1304,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"გასახსნელად გამოიყენეთ თითის ანაბეჭდი"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"საჭიროა ავტორიზაცია. ავტორიზაციისთვის შეეხეთ თითის ანაბეჭდის სენსორს."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"მიმდინარე ზარი"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"მობილური ინტერნეტი"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"დაკავშირებული"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"დროებით დაკავშირებული"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 54fb72a7..9413dd0 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Батарея зарядының мөлшері белгісіз."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> қосылған."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> трансляциясына қосылды."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Жалғанбаған."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Роуминг"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Өшірулі"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Қолданбаны виджет көмегімен ашу үшін жеке басыңызды растауыңыз керек. Сондай-ақ басқалар оларды планшетіңіз құлыптаулы кезде де көре алатынын ескеріңіз. Кейбір виджеттер құлып экранына арналмаған болады, сондықтан оларды мұнда қосу қауіпсіз болмауы мүмкін."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Түсінікті"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Скринсейвер түймесін көрсету"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Хаб режимін шолу"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Зарядтау кезінде өзіңіз ұнататын виджеттер мен скринсейверлерді пайдаланыңыз."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Бастайық"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Пайдаланушыны ауыстыру"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ашылмалы мәзір"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Әңгіме туралы хабарландырулардың жоғарғы жағында тұрады және құлыптаулы экранда профиль суреті болып көрсетіледі, қалқыма хабар түрінде шығады, Мазаламау режимін тоқтатады."</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Маңызды"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> әңгіме функцияларын қолдамайды."</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Жабу"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Қайта көрсетілмесін"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Бұл хабарландыруларды өзгерту мүмкін емес."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Қоңырау туралы хабарландыруларды өзгерту мүмкін емес."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Мұндай хабарландырулар бұл жерде конфигурацияланбайды."</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Күнтізбе"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Пернелердің қайта басылуын елемеуді қосу/өшіру"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Тінтуір пернелерін қосу/өшіру"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Жабысқан пернелерді қосу/өшіру"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Баяу пернелерді қосу/өшіру"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Access мүмкіндігін қосу/өшіру"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Мазаламау"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Дыбыс деңгейі түймелерінің төте жолы"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Ашу үшін саусақ ізін пайдаланыңыз."</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Аутентификациядан өту қажет. Ол үшін саусақ ізін оқу сканерін түртіңіз."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Ағымдағы қоңырау"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобильдік интернет"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Жалғанды"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Уақытша байланыс орнатылды."</string>
@@ -1454,7 +1458,7 @@
     <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Қолданыстағы қолданба"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Арнайы мүмкіндіктер"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Перне тіркесімдері"</string>
-    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Пернелер тіркесімін бейімдеу"</string>
+    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Пернелер тіркесімдерін реттеу"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Тіркесімді өшіру керек пе?"</string>
     <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Әдепкі тіркесімге қайтару керек пе?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"Осы тіркесімді жасау үшін әрекет пернесін және басқа бір не бірнеше пернені бірге басыңыз."</string>
@@ -1474,7 +1478,7 @@
     <string name="shortcut_helper_key_combinations_forward_slash" msgid="1238652537199346970">"қиғаш сызық"</string>
     <string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Сүйрейтін тетік"</string>
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Пернетақта параметрлері"</string>
-    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Жылдам пәрменді орнату"</string>
+    <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Пернелер тіркесімін орнату"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Өшіру"</string>
     <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Иә, қайтару"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Бас тарту"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Соңғы қолданбаларды көру қимылын орындадыңыз."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Соңғы қолданбаларды көру үшін сенсорлық тақтада үш саусақпен жоғары сырғытып, ұстап тұрыңыз."</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Қолданба ауыстыру"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Сенсорлық тақтада төрт саусақпен оңға сырғытыңыз."</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Жарайсыз!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Қолданба ауыстыру қимылын аяқтадыңыз."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Қолданбаларды ауыстыру үшін сенсорлық тақтада төрт саусақпен оңға сырғытыңыз."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Барлық қолданбаны көру"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Пернетақтадағы әрекет пернесін басыңыз."</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Жарайсыз!"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index e827fc7..bd3f777 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"មិនដឹងអំពី​ភាគរយថ្មទេ។"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"បាន​ភ្ជាប់​ទៅ <xliff:g id="BLUETOOTH">%s</xliff:g> ។"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"បានភ្ជាប់ទៅ <xliff:g id="CAST">%s</xliff:g>"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"មិន​បាន​តភ្ជាប់​។"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"រ៉ូ​មីង"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"បិទ"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ដើម្បីបើកកម្មវិធីដោយប្រើធាតុ​ក្រាហ្វិក អ្នកនឹងត្រូវផ្ទៀងផ្ទាត់ថាជាអ្នក។ ទន្ទឹមនឹងនេះ សូមចងចាំថា នរណាក៏អាចមើលធាតុក្រាហ្វិកបាន សូម្បីពេលថេប្លេតរបស់អ្នកជាប់សោក៏ដោយ។ ធាតុ​ក្រាហ្វិកមួយចំនួនប្រហែលមិនត្រូវបានរចនាឡើងសម្រាប់អេក្រង់ចាក់សោរបស់អ្នកទេ និងមិនមានសុវត្ថិភាពឡើយ បើបញ្ចូលទៅទីនេះ។"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"យល់ហើយ"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"បង្ហាញប៊ូតុងធាតុ​រក្សា​អេក្រង់"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"រុករកមុខងារមណ្ឌល"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"ចូលប្រើប្រាស់ធាតុ​ក្រាហ្វិក និងធាតុរក្សាអេក្រង់ដែលអ្នកពេញចិត្តពេលសាកថ្ម។"</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"ចាប់ផ្ដើម"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ប្ដូរ​អ្នក​ប្រើ"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ម៉ឺនុយ​ទាញចុះ"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"បង្ហាញនៅខាងលើ​ការជូនដំណឹងអំពីការសន្ទនា និងជារូបភាព​កម្រង​ព័ត៌មាននៅលើអេក្រង់ចាក់សោ បង្ហាញជាពពុះ បង្អាក់មុខងារកុំ​រំខាន"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"អាទិភាព"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> មិនអាចប្រើ​មុខងារ​សន្ទនា​បានទេ"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"ច្រានចោល"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"កុំបង្ហាញម្ដងទៀត"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"មិនអាច​កែប្រែ​ការជូនដំណឹង​ទាំងនេះ​បានទេ។"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"មិនអាច​កែប្រែ​ការជូនដំណឹងអំពីការហៅទូរសព្ទបានទេ។"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"មិនអាច​កំណត់​រចនាសម្ព័ន្ធ​ក្រុមការជូនដំណឹងនេះ​នៅទីនេះ​បានទេ"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ប្រតិទិន"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"ម៉ាស៊ីនគិតលេខ"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"ផែនទី"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"បិទ/បើកគ្រាប់ចុចឡង"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"បិទ/បើកគ្រាប់ចុចម៉ៅស៍"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"បិទ/បើកគ្រាប់ចុចស្អិត"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"បិទ/បើកគ្រាប់ចុចយឺត"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"បិទ/បើកការចូល​ប្រើប្រាស់តាមរយៈ​សំឡេង"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"កុំ​រំខាន"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ផ្លូវកាត់ប៊ូតុងកម្រិតសំឡេង"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ប្រើស្នាមម្រាមដៃ ដើម្បីបើក"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"តម្រូវឱ្យ​មាន​ការផ្ទៀងផ្ទាត់។ សូមចុច​ឧបករណ៍​ចាប់ស្នាមម្រាមដៃ ដើម្បី​ផ្ទៀងផ្ទាត់​។"</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"ការ​ហៅដែលកំពុងដំណើរការ"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"ទិន្នន័យ​ទូរសព្ទចល័ត"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"បានភ្ជាប់"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"បានភ្ជាប់ជាបណ្ដោះអាសន្ន"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"អ្នកបានបញ្ចប់ការមើលចលនាកម្មវិធីថ្មីៗ។"</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"ដើម្បីមើលកម្មវិធីថ្មីៗ សូមអូសឡើងលើ រួចសង្កត់ឱ្យជាប់លើផ្ទាំងប៉ះរបស់អ្នក ដោយប្រើម្រាមដៃបី"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"ប្ដូរ​កម្មវិធី"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"អូសទៅស្ដាំដោយប្រើ​ម្រាមដៃបួននៅលើផ្ទាំងប៉ះរបស់អ្នក"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"ធ្វើបានល្អ!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"អ្នក​បានបញ្ចប់​ចលនា​ប្ដូរកម្មវិធី​ហើយ។"</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"អូសទៅស្ដាំដោយប្រើ​ម្រាមដៃបួននៅលើផ្ទាំងប៉ះរបស់អ្នក ដើម្បីប្ដូរកម្មវិធី"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"មើល​កម្មវិធី​ទាំងអស់"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ចុចគ្រាប់ចុចសកម្មភាពលើក្ដារចុចរបស់អ្នក"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ធ្វើបាន​ល្អ!"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index bfc9d75..032a80a 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ಬ್ಯಾಟರಿ ಶೇಕಡಾವಾರು ತಿಳಿದಿಲ್ಲ."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> ಗೆ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"ಸಂಪರ್ಕಗೊಂಡಿಲ್ಲ."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"ರೋಮಿಂಗ್"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"ಆಫ್"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"ಹಬ್ ಮೋಡ್ ಅನ್ನು ಎಕ್ಸ್‌ಪ್ಲೋರ್ ಮಾಡಿ"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"ಚಾರ್ಜ್ ಮಾಡುವಾಗ ನಿಮ್ಮ ನೆಚ್ಚಿನ ವಿಜೆಟ್‌ಗಳು ಮತ್ತು ಸ್ಕ್ರೀನ್ ಸೇವರ್‌ಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಿ."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"ಪ್ರಾರಂಭಿಸೋಣ"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ಸಂಭಾಷಣೆ ಅಧಿಸೂಚನೆಗಳ ಮೇಲ್ಭಾಗದಲ್ಲಿ ಹಾಗೂ ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ನ ಮೇಲೆ ಪ್ರೊಫೈಲ್ ಚಿತ್ರವಾಗಿ ತೋರಿಸುತ್ತದೆ, ಬಬಲ್‌ನಂತೆ ಗೋಚರಿಸುತ್ತದೆ, ಅಡಚಣೆ ಮಾಡಬೇಡ ಮೋಡ್‌ಗೆ ಅಡ್ಡಿಯುಂಟುಮಾಡುತ್ತದೆ"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ಆದ್ಯತೆ"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"ಸಂವಾದ ಫೀಚರ್‌ಗಳನ್ನು <xliff:g id="APP_NAME">%1$s</xliff:g> ಬೆಂಬಲಿಸುವುದಿಲ್ಲ"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"ವಜಾಗೊಳಿಸಿ"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"ಮತ್ತೊಮ್ಮೆ ತೋರಿಸಬೇಡಿ"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ಕರೆ ಅಧಿಸೂಚನೆಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ಈ ಗುಂಪಿನ ಅಧಿಸೂಚನೆಗಳನ್ನು ಇಲ್ಲಿ ಕಾನ್ಫಿಗರ್‌ ಮಾಡಲಾಗಿರುವುದಿಲ್ಲ"</string>
@@ -915,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"ಕ್ಯಾಲ್ಕ್ಯುಲೇಟರ್"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"ಬೌನ್ಸ್ ಕೀಗಳನ್ನು ಟಾಗಲ್ ಮಾಡಿ"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"ಮೌಸ್ ಕೀಗಳನ್ನು ಟಾಗಲ್ ಮಾಡಿ"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"ಸ್ಟಿಕಿ ಕೀಗಳನ್ನು ಟಾಗಲ್ ಮಾಡಿ"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"ನಿಧಾನ ಕೀಗಳನ್ನು ಟಾಗಲ್ ಮಾಡಿ"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"ಧ್ವನಿ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಟಾಗಲ್ ಮಾಡಿ"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ವಾಲ್ಯೂಮ್ ಬಟನ್‌ಗಳ ಶಾರ್ಟ್‌ಕಟ್‌"</string>
@@ -1304,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ತೆರೆಯುವುದಕ್ಕಾಗಿ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಬಳಸಿ"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ದೃಢೀಕರಣದ ಅವಶ್ಯಕತೆಯಿದೆ. ದೃಢೀಕರಿಸಲು ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಸ್ಪರ್ಶಿಸಿ."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಕರೆ"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"ಮೊಬೈಲ್ ಡೇಟಾ"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"ತಾತ್ಕಾಲಿಕವಾಗಿ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index b4e3c14..4910e8c 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"배터리 잔량을 알 수 없습니다."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>에 연결되었습니다."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>에 연결됨"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"연결되지 않았습니다."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"로밍"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"사용 안함"</string>
@@ -542,6 +546,8 @@
     <skip />
     <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
     <skip />
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -804,10 +810,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"대화 알림 상단에 표시, 잠금 화면에 프로필 사진으로 표시, 대화창으로 표시, 방해 금지 모드를 무시함"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"우선순위"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱은 대화 기능을 지원하지 않습니다."</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"닫기"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"다시 표시하지 않음"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"이 알림은 수정할 수 없습니다."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"전화 알림은 수정할 수 없습니다."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"이 알림 그룹은 여기에서 설정할 수 없습니다."</string>
@@ -918,15 +922,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"계산기"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"지도"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"바운스 키 전환"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"마우스 키 전환"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"고정키 전환"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"느린 키 전환"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"음성 액세스 전환"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"방해 금지 모드"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"볼륨 버튼 단축키"</string>
@@ -1307,6 +1312,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"지문으로 열기"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"인증이 필요합니다. 지문 센서를 터치하여 인증하세요."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"진행 중인 통화"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"모바일 데이터"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"연결됨"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"일시적으로 연결됨"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index a3e20a4..6619ad0 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Батареянын деңгээли белгисиз."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> менен туташкан."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> менен туташты."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Интернет жок."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Роуминг"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Өчүк"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Колдонмону виджет аркылуу ачуу үчүн өзүңүздү ырасташыңыз керек. Алар кулпуланган планшетиңизде да көрүнүп турат. Кээ бир виджеттерди кулпуланган экранда колдоно албайсыз, андыктан аларды ал жерге кошпой эле койгонуңуз оң."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Түшүндүм"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Көшөгө баскычын көрсөтүү"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Түйүн режимин колдонуп көрүңүз"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Кубатталып жатканда жактырган виджеттериңизди жана көшөгөлөрдү колдонуңуз."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Кеттик!"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Колдонуучуну которуу"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ылдый түшүүчү меню"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Cүйлөшүүлөр тууралуу билдирмелердин жогору жагында жана кулпуланган экранда профилдин сүрөтү, ошондой эле калкып чыкма билдирме түрүндө көрүнүп, \"Тынчымды алба\" режимин токтотот"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Маанилүүлүгү"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда оозеки сүйлөшкөнгө болбойт"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Жабуу"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Экинчи көрсөтүлбөсүн"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Бул билдирмелерди өзгөртүүгө болбойт."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Чалуу билдирмелерин өзгөртүүгө болбойт."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Бул билдирмелердин тобун бул жерде конфигурациялоого болбойт"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Жылнаама"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Эсептегич"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Карталар"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Кайтаруу баскычтарын өчүрүү/күйгүзүү"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Чычкандын баскычтарын өчүрүү/күйгүзүү"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Жабышма баскычтарды өчүрүү/күйгүзүү"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Жай баскычтарды өчүрүү/күйгүзүү"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Access\'ти өчүрүү/күйгүзүү"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Тынчымды алба"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Үндү көзөмөлдөөчү баскычтардын кыска жолдору"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Манжаңыздын изи менен ачыңыз"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Аныктыкты текшерүү талап кылынат. Аныктыгын текшерүү үчүн манжа изинин сенсоруна тийип коюңуз."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Учурдагы чалуу"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобилдик трафик"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Туташты"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Убактылуу туташып турат"</string>
@@ -1476,10 +1480,10 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Баскычтоп параметрлери"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ыкчам баскычты тууралоо"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Өчүрүү"</string>
-    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Ооба, баштапкы абалга келтирилсин"</string>
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Ооба"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Баскычты басыңыз"</string>
-    <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="3325858369539848162">"Ачкычтардын айкалышы колдонулууда. Башка айкалышты колдонуп көрүңүз."</string>
+    <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="3325858369539848162">"Баскычтардын мындай айкалышы бар. Башкасын колдонуп көрүңүз."</string>
     <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Ыкчам баскычты коюу мүмкүн эмес."</string>
     <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
     <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Ыкчам баскыч кошуу"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Акыркы колдонмолорду көрүү жаңсоосун аткардыңыз."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Соңку колдонмолорду көрүү үчүн сенсордук тактаны үч манжаңыз менен жогору сүрүп, кармап туруңуз"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Колдонмолорду которуштуруу"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Сенсордук тактаны төрт манжаңыз менен оңго сүрүңүз"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Азаматсыз!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"\"Башка колдонмого которулуу жаңсоосу боюнча үйрөткүчтү бүтүрдүңүз."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Колдонмолорду которуштуруу үчүн сенсордук тактаны төрт манжаңыз менен оңго сүрүңүз"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Бардык колдонмолорду көрүү"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Баскычтобуңуздагы аракет баскычын басыңыз"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Эң жакшы!"</string>
diff --git a/packages/SystemUI/res/values-ldrtl/dimens.xml b/packages/SystemUI/res/values-ldrtl/dimens.xml
index 0d99b61..345f041 100644
--- a/packages/SystemUI/res/values-ldrtl/dimens.xml
+++ b/packages/SystemUI/res/values-ldrtl/dimens.xml
@@ -16,5 +16,5 @@
   -->
 <resources>
     <dimen name="media_output_dialog_icon_left_radius">0dp</dimen>
-    <dimen name="media_output_dialog_icon_right_radius">28dp</dimen>
+    <dimen name="media_output_dialog_icon_right_radius">@dimen/media_output_dialog_active_background_radius</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index eade9f1..0f4ec94 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ບໍ່ຮູ້ເປີເຊັນແບັດເຕີຣີ."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"ເຊື່ອມ​ຕໍ່​ຫາ <xliff:g id="BLUETOOTH">%s</xliff:g> ແລ້ວ."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"ເຊື່ອມຕໍ່ຫາ <xliff:g id="CAST">%s</xliff:g> ແລ້ວ."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"ບໍ່ໄດ້ເຊື່ອມຕໍ່."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"ໂຣມມິງ"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"ປິດ"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"ສຳຫຼວດໂໝດ Hub"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"ເຂົ້າເຖິງວິດເຈັດ ແລະ ພາບພັກໜ້າຈໍທີ່ທ່ານມັກໃນລະຫວ່າງທີ່ສາກ."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"ມາເລີ່ມກັນເລີຍ"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ສະແດງຢູ່ເທິງສຸດຂອງການແຈ້ງເຕືອນການສົນທະນາ ແລະ ເປັນຮູບໂປຣໄຟລ໌ຢູ່ໜ້າຈໍລັອກ, ປາກົດເປັນຟອງ, ສະແດງໃນໂໝດຫ້າມລົບກວນໄດ້"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ສຳຄັນ"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່ຮອງຮັບຄຸນສົມບັດການສົນທະນາ"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"ປິດໄວ້"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"ບໍ່ຕ້ອງສະແດງອີກ"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ບໍ່ສາມາດແກ້ໄຂການແຈ້ງເຕືອນເຫຼົ່ານີ້ໄດ້."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ບໍ່ສາມາດແກ້ໄຂການແຈ້ງເຕືອນການໂທໄດ້."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ບໍ່ສາມາດຕັ້ງຄ່າກຸ່ມການແຈ້ງເຕືອນນີ້ຢູ່ບ່ອນນີ້ໄດ້"</string>
@@ -915,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ປະຕິທິນ"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"ຈັກຄິດໄລ່"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"ແຜນທີ່"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"ສະ​ຫຼັບການຍົກເລີກການກົດປຸ່ມຊໍ້າໆ"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"ສະ​ຫຼັບປຸ່ມເມົ້າ"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"ສະ​ຫຼັບປຸ່ມກົດຄ້າງ"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"ສະ​ຫຼັບປຸ່ມຊ້າ"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"ສະ​ຫຼັບການເຂົ້າເຖິງສຽງ"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"ເປີດ/ປິດ TalkBack"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"ເປີດ/ປິດການຂະຫຍາຍໜ້າຈໍ"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"ເປີດນຳໃຊ້ການເລືອກເພື່ອເວົ້າ"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ຫ້າມລົບກວນ"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ທາງລັດປຸ່ມສຽງ"</string>
     <string name="battery" msgid="769686279459897127">"ແບັດເຕີຣີ"</string>
@@ -1304,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ໃຊ້ລາຍນິ້ວມືເພື່ອເປີດ"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ຕ້ອງພິສູດຢືນຢັນ. ແຕະໃສ່ເຊັນເຊີລາຍນິ້ວມືເພື່ອພິສູດຢືນຢັນ."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"ສາຍທີ່ສົນທະນາຢູ່"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"ອິນເຕີເນັດມືຖື"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"ເຊື່ອມຕໍ່ແລ້ວ"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"ເຊື່ອມຕໍ່ແລ້ວຊົ່ວຄາວ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 77c92d1..1c514c4 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akumuliatoriaus energija procentais nežinoma."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Prisijungta prie „<xliff:g id="BLUETOOTH">%s</xliff:g>“."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Prisijungta prie <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Neprijungta."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Tarptinklinis ryšys"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Išjungta"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Naršymas centro režimu"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Įkraudami pasiekite mėgstamiausius valdiklius ir ekrano užsklandas."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Pirmyn"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -913,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendorius"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Skaičiuotuvas"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Žemėlapiai"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Perjungti peradresavimo klavišus"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Perjungti pelės klavišus"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Perjungti atmeniuosius klavišus"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Perjungti lėtuosius klavišus"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Perjungti „Voice Access“"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Netrukdymo režimas"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Garsumo mygtukų spartusis klavišas"</string>
@@ -1302,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Naudokite kontrolinį kodą, kad atidarytumėte"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Reikia nustatyti tapatybę. Nustatykite tapatybę palietę kontrolinio kodo jutiklį."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Vykstantis skambutis"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobiliojo ryšio duomenys"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Prisijungta"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Laikinai prijungta"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 2443769..633af09 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akumulatora uzlādes līmenis procentos nav zināms."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Ir izveidots savienojum ar <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Savienots ar ierīci <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Savienojums nav izveidots."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Viesabonēšana"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Izslēgti"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Lai atvērtu lietotni, izmantojot logrīku, jums būs jāapstiprina sava identitāte. Turklāt ņemiet vērā, ka ikviens var skatīt logrīkus, pat ja planšetdators ir bloķēts. Iespējams, daži logrīki nav paredzēti izmantošanai bloķēšanas ekrānā, un var nebūt droši tos šeit pievienot."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Labi"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Poga “Rādīt ekrānsaudzētāju”"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Izpētiet centra režīmu"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Piekļūstiet iecienītajiem logrīkiem un ekrānsaudzētājiem uzlādes laikā."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Aiziet!"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Parādās sarunu paziņojumu augšdaļā un kā profila attēls bloķēšanas ekrānā, arī kā burbulis, pārtrauc režīmu “Netraucēt”."</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritārs"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Lietotnē <xliff:g id="APP_NAME">%1$s</xliff:g> netiek atbalstītas sarunu funkcijas."</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Nerādīt"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Vairs nerādīt"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Šos paziņojumus nevar modificēt."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Paziņojumus par zvaniem nevar modificēt."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Šeit nevar konfigurēt šo paziņojumu grupu."</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendārs"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kalkulators"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Kartes"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Pārslēgt atlēcienu taustiņus"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Pārslēgt peles taustiņus"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Pārslēgt taustiņu ķēdi"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Pārslēgt lēnos taustiņus"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Pārslēgt lietotni “Balss piekļuve”"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Režīms “Netraucēt”"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Skaļuma pogu saīsne"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Atvēršanai izmantojiet pirksta nospiedumu"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Nepieciešama autentifikācija. Pieskarieties pirksta nospieduma sensoram, lai veiktu autentificēšanu."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Notiekošs zvans"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobilie dati"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Ir izveidots savienojums"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Īslaicīgi izveidots savienojums"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Jūs sekmīgi veicāt nesen izmantoto lietotņu skatīšanas žestu."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Lai skatītu nesenās lietotnes, skārienpaliktnī ar trīs pirkstiem velciet augšup un turiet"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Pārslēgšanās starp lietotnēm"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Skārienpaliktnī ar četriem pirkstiem velciet pa labi."</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Lieliski!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Jūs sekmīgi veicāt pārslēgšanās starp lietotnēm žestu."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Lai pārslēgtos starp lietotnēm, skārienpaliktnī ar četriem pirkstiem velciet pa labi."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Skatīt visas lietotnes"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tastatūrā nospiediet darbību taustiņu."</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Lieliski!"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index a9aec16..8324cdb 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Процентот на батеријата е непознат."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Поврзано со <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Поврзано со <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Не е поврзана"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Роаминг"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Исклучено"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"За да отворите апликација со помош на виџет, ќе треба да потврдите дека сте вие. Покрај тоа, имајте предвид дека секој може да ги гледа виџетите, дури и кога вашиот таблет е заклучен. Некои виџети можеби не се наменети за вашиот заклучен екран, па можеби не е безбедно да се додадат овде."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Сфатив"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Копче за прикажување на штедачот на екран"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Истражете го режимот Hub"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Пристапувајте до омилените виџети и штедачи на екран при полнење."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Ајде"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Промени го корисникот"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"паѓачко мени"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Се прикажува најгоре во известувањата за разговор и како профилна слика на заклучен екран, се појавува како балонче, го прекинува „Не вознемирувај“"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Приоритетно"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не поддржува функции за разговор"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Отфрли"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Не прикажувај повторно"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Овие известувања не може да се изменат"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Известувањата за повици не може да се изменат."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Оваа група известувања не може да се конфигурира тука"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Калкулатор"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Карти"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Вклучи/исклучи „Игнорирање на повторено притискање“"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Вклучи/исклучи „Копчиња за глувче“"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Вклучи/исклучи „Лепливи копчиња“"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Вклучи/исклучи „Бавни копчиња“"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Вклучи/исклучи „Пристап со глас“"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не вознемирувај"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Кратенка за копчињата за јачина на звук"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Користете отпечаток за да се отвори"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Потребна е проверка. Допрете го сензорот за отпечаток за да автентицирате."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Тековен повик"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобилен интернет"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Поврзано"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Привремено поврзано"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Го завршивте движењето за прегледување на неодамнешните апликации."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Повлечете нагоре со три прста на допирната подлога и задржете за да ги видите неодамнешните апликации"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Сменете ги апликациите"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Повлечете надесно со четири прста на допирната подлога"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Одлично!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Го завршивте движењето за менување апликации."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Повлечете надесно со четири прста на допирната подлога за да ги смените апликациите"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Прегледајте ги сите апликации"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Притиснете го копчето за дејство на тастатурата"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Браво!"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 4c444f0..267d00b 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ബാറ്ററി ശതമാനം അജ്ഞാതമാണ്."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> എന്നതിലേക്ക് കണക്‌റ്റുചെയ്‌തു."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> എന്നതിലേക്ക് കണക്റ്റുചെയ്തു."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"കണക്റ്റുചെയ്‌തിട്ടില്ല."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"റോമിംഗ്"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"ഓഫ്"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"ഹബ് മോഡ് അടുത്തറിയുക"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"ചാർജ് ചെയ്യുമ്പോൾ നിങ്ങളുടെ പ്രിയപ്പെട്ട വിജറ്റുകളും സ്‌ക്രീൻ സേവറുകളും ആക്‌സസ് ചെയ്യുക."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"തുടങ്ങാം"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"സംഭാഷണ അറിയിപ്പുകളുടെ മുകളിലും സ്ക്രീൻ ലോക്കായിരിക്കുമ്പോൾ ഒരു പ്രൊഫൈൽ ചിത്രമായും ബബിൾ രൂപത്തിൽ ദൃശ്യമാകുന്നു, ശല്യപ്പെടുത്തരുത് മോഡ് തടസ്സപ്പെടുത്തുന്നു"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"മുൻഗണന"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"സംഭാഷണ ഫീച്ചറുകളെ <xliff:g id="APP_NAME">%1$s</xliff:g> പിന്തുണയ്‌ക്കുന്നില്ല"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"ഡിസ്‌മിസ് ചെയ്യുക"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"വീണ്ടും കാണിക്കരുത്"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ഈ അറിയിപ്പുകൾ പരിഷ്ക്കരിക്കാനാവില്ല."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"കോൾ അറിയിപ്പുകൾ പരിഷ്‌കരിക്കാനാകുന്നില്ല."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"അറിയിപ്പുകളുടെ ഈ ഗ്രൂപ്പ് ഇവിടെ കോണ്‍ഫിഗര്‍ ചെയ്യാൻ കഴിയില്ല"</string>
@@ -915,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"കാൽക്കുലേറ്റർ"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"ബൗൺസ് കീകൾ ടോഗിൾ ചെയ്യുക"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"മൗസ് കീകൾ ടോഗിൾ ചെയ്യുക"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"സ്‌റ്റിക്കി കീകൾ ടോഗിൾ ചെയ്യുക"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"സ്ലോ കീകൾ ടോഗിൾ ചെയ്യുക"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Access ടോഗിൾ ചെയ്യുക"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ശല്യപ്പെടുത്തരുത്"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"വോളിയം ബട്ടൺ കുറുക്കുവഴി"</string>
@@ -1304,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"തുറക്കുന്നതിന് നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"പരിശോധിച്ചുറപ്പിക്കേണ്ടതുണ്ട്. പരിശോധിച്ചുറപ്പിക്കാൻ, വിരലടയാള സെൻസറിൽ സ്‌പർശിക്കുക."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"കോളിലാണ്"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"മൊബൈൽ ഡാറ്റ"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"കണക്റ്റ് ചെയ്തു"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"താൽക്കാലികമായി കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 3666c0d..e0cd2a6 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Батарейн хувь тодорхойгүй байна."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>-тай холбогдсон."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>-д холбогдсон."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Холбогдоогүй."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Роуминг"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Идэвхгүй"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Виджет ашиглан аппыг нээхийн тулд та өөрийгөө мөн болохыг баталгаажуулах шаардлагатай болно. Мөн таны таблет түгжээтэй байсан ч тэдгээрийг дурын хүн үзэж болохыг санаарай. Зарим виджет таны түгжээтэй дэлгэцэд зориулагдаагүй байж магадгүй ба энд нэмэхэд аюултай байж болзошгүй."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ойлголоо"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Дэлгэц амраагчийг харуулах товч"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Hub горимыг судлах"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Цэнэглэж байхад дуртай виджет, дэлгэц амраагчдаа хандана уу."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"За эхэлцгээе"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Хэрэглэгчийг сэлгэх"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"эвхмэл цэс"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Харилцан ярианы мэдэгдлийн дээд талд болон түгжигдсэн дэлгэц дээр профайл зураг байдлаар харуулах бөгөөд бөмбөлөг хэлбэрээр харагдана. Бүү саад бол горимыг тасалдуулна"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Чухал"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь харилцан ярианы онцлогуудыг дэмждэггүй"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Хаах"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Дахиж бүү харуул"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Эдгээр мэдэгдлийг өөрчлөх боломжгүй."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Дуудлагын мэдэгдлийг өөрчлөх боломжгүй."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Энэ бүлэг мэдэгдлийг энд тохируулах боломжгүй байна"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календарь"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Тооны машин"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Газрын зураг"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Ойх товчийг асаах/унтраах"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Хулганын товчийг асаах/унтраах"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Бэхэлсэн товчийг асаах/унтраах"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Удаан товчийг асаах/унтраах"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Access-г асаах/унтраах"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Бүү саад бол"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Дууны түвшний товчлуурын товчлол"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Нээхийн тулд хурууны хээг ашиглана уу"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Баталгаажуулалт шаардлагатай. Баталгаажуулахын тулд хурууны хээ мэдрэгчид хүрнэ үү."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Үргэлжилж буй дуудлага"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобайл дата"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Холбогдсон"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Түр зуур холбогдсон"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Та саяхны аппуудыг харах зангааг гүйцэтгэсэн."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Саяхны аппуудыг харахын тулд мэдрэгч самбар дээрээ гурван хуруугаараа дээш шудраад, удаан дарна уу"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Апп сэлгэх"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Мэдрэгч самбар дээрээ дөрвөн хуруугаараа баруун тийш шударна уу"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Үнэхээр сайн ажиллалаа!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Та апп хооронд сэлгэх зангааг гүйцэтгэлээ."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Апп сэлгэхийн тулд мэдрэгч самбар дээрээ дөрвөн хуруугаараа баруун тийш шударна уу"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Бүх аппыг харах"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Гар дээрх тусгай товчлуурыг дарна уу"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Сайн байна!"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 73deadb..4adaa29 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"बॅटरीच्या चार्जिंगची टक्केवारी माहित नाही."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> शी कनेक्‍ट केले."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> शी कनेक्ट केले."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"कनेक्ट केले नाही."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"रोमिंग"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"बंद"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"हब मोड एक्सप्लोर करा"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"चार्ज करत असताना तुमचे आवडते विजेट आणि स्क्रीन सेव्हर अ‍ॅक्सेस करा."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"चला सुरू करू या"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"संभाषण सूचनांच्या वरती आणि लॉक स्क्रीनवरील प्रोफाइल फोटो म्हणून दिसते, बबल म्हणून दिसते, व्यत्यय आणू नका यामध्ये अडथळा आणते"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"प्राधान्य"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> हे संभाषण वैशिष्ट्यांना सपोर्ट करत नाही"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"डिसमिस करा"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"पुन्हा दाखवू नका"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"या सूचनांमध्ये सुधारणा केली जाऊ शकत नाही."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"कॉलशी संबंधित सूचनांमध्ये फेरबदल केला जाऊ शकत नाही."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"या सूचनांचा संच येथे कॉन्फिगर केला जाऊ शकत नाही"</string>
@@ -915,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"कॅलेंडर"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"बाउन्स की टॉगल करा"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"माउस की टॉगल करा"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"स्टिकी की टॉगल करा"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"स्लो की टॉगल करा"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Access टॉगल करा"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"व्यत्यय आणू नका"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"आवाजाच्या बटणांचा शार्टकट"</string>
@@ -1304,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"उघडण्यासाठी फिंगरप्रिंट वापरा"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ऑथेंटिकेशन आवश्यक आहे. ऑथेंटिकेट करण्यासाठी फिंगरप्रिंट सेन्सरला स्पर्श करा."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"सुरू असलेला कॉल"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"मोबाइल डेटा"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"कनेक्ट केले आहे"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"तात्पुरते कनेक्ट केलेले"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 77d2d24..8d38af4 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Peratusan kuasa bateri tidak diketahui."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Disambungkan kepada <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Disambungkan ke <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Tidak disambungkan."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Perayauan"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Mati"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Terokai mod hab"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Akses widget dan penyelamat skrin kegemaran anda semasa melakukan pengecasan."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Mari mulakan"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Ditunjukkan di bahagian atas pemberitahuan perbualan dan sebagai gambar profil pada skrin kunci, muncul sebagai gelembung, mengganggu Jangan Ganggu"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Keutamaan"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak menyokong ciri perbualan"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Ketepikan"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Jangan tunjukkan lagi"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Pemberitahuan ini tidak boleh diubah suai."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Pemberitahuan panggilan tidak boleh diubah suai."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Kumpulan pemberitahuan ini tidak boleh dikonfigurasikan di sini"</string>
@@ -915,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kalkulator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Togol kekunci lantun"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Togol kekunci tetikus"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Togol kekunci lekit"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Togol kekunci perlahan"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Togol Voice Access"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Jangan Ganggu"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Pintasan butang kelantangan"</string>
@@ -1304,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Gunakan cap jari untuk membuka"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Pengesahan diperlukan. Sentuh penderia cap jari untuk pengesahan."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Panggilan sedang berlangsung"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Data mudah alih"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Disambungkan"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Disambungkan buat sementara waktu"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 8f44cb0..c971e3a 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ဘက်ထရီရာခိုင်နှုန်းကို မသိပါ။"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>သို့ ချိတ်ဆက်ထား"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> သို့ချိတ်ဆက်ထားပါသည်။"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"ချိတ်ဆက်မထားပါ"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"ပြင်ပကွန်ရက်သုံးခြင်း"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"ပိတ်"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ဝိဂျက်သုံး၍ အက်ပ်ဖွင့်ရန်အတွက် သင်ဖြစ်ကြောင်း အတည်ပြုရန်လိုသည်။ ထို့ပြင် သင့်တက်ဘလက် လော့ခ်ချထားချိန်၌ပင် မည်သူမဆို ၎င်းတို့ကို ကြည့်နိုင်ကြောင်း သတိပြုပါ။ ဝိဂျက်အချို့ကို လော့ခ်မျက်နှာပြင်အတွက် ရည်ရွယ်ထားခြင်း မရှိသဖြင့် ဤနေရာတွင် ထည့်ပါက မလုံခြုံနိုင်ပါ။"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"နားလည်ပြီ"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"စခရင်နားချိန်ပုံ ပြရန်ခလုတ်"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"ထိန်းချုပ်စင်တာမုဒ် လေ့လာခြင်း"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"အားသွင်းနေစဉ် အကြိုက်ဆုံးဝိဂျက်များ၊ စခရင်နားချိန်ပုံများ ကြည့်နိုင်သည်။"</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"စကြစို့"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"အသုံးပြုသူကို ပြောင်းလဲရန်"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ဆွဲချမီနူး"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"စကားဝိုင်း အကြောင်းကြားချက်များ၏ ထိပ်ပိုင်းနှင့် ပရိုဖိုင်ပုံအဖြစ် လော့ခ်မျက်နှာပြင်တွင် ပြသည်။ ပူဖောင်းကွက်အဖြစ် မြင်ရပြီး ‘မနှောင့်ယှက်ရ’ ကို ကြားဖြတ်သည်"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ဦးစားပေး"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> က စကားဝိုင်းဝန်ဆောင်မှုများကို မပံ့ပိုးပါ"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"ပယ်ရန်"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"ထပ်မပြပါနှင့်"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ဤအကြောင်းကြားချက်များကို ပြုပြင်၍ မရပါ။"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ခေါ်ဆိုမှုအကြောင်းကြားချက်များကို ပြင်၍မရပါ။"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ဤအကြောင်းကြားချက်အုပ်စုကို ဤနေရာတွင် စီစဉ်သတ်မှတ်၍ မရပါ"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ပြက္ခဒိန်"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"ဂဏန်းတွက်စက်"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"ကြိမ်ထပ်နှိပ်ခြင်းများ ပြောင်းရန်"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"မောက်စ်ကီးများ ပြောင်းရန်"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"ကပ်ခွာကီးများ ပြောင်းရန်"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"အနှေးကီးများ ပြောင်းရန်"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"အသံဖြင့်ထိန်းချုပ်ခြင်း ပြောင်းရန်"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"မနှောင့်ယှက်ရ"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"အသံထိန်းချုပ်သည့်ခလုတ် ဖြတ်လမ်း"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ဖွင့်ရန် လက်ဗွေကို သုံးပါ"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"အထောက်အထားစိစစ်ခြင်း လိုအပ်သည်။ အထောက်အထားစိစစ်ရန် လက်ဗွေ အာရုံခံကိရိယာကို ထိပါ။"</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"လက်ရှိခေါ်ဆိုမှု"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"မိုဘိုင်းဒေတာ"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"ချိတ်ဆက်ထားသည်"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"ယာယီချိတ်ဆက်ထားသည်"</string>
@@ -1448,8 +1452,7 @@
     <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"စနစ် အက်ပ်များ"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"တစ်ပြိုင်နက် များစွာလုပ်ခြင်း"</string>
     <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"မျက်နှာပြင် ခွဲ၍ပြသခြင်း"</string>
-    <!-- no translation found for shortcutHelper_category_accessibility (8068337792277570938) -->
-    <skip />
+    <string name="shortcutHelper_category_accessibility" msgid="8068337792277570938">"အများသုံးနိုင်မှု"</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_current_app_shortcuts" msgid="4017840565974573628">"လက်ရှိအက်ပ်"</string>
@@ -1513,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"မကြာသေးမီကအက်ပ်များကို ကြည့်ခြင်းလက်ဟန် သင်ခန်းစာပြီးပါပြီ။"</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"လတ်တလောအက်ပ်များကြည့်ရန် တာ့ချ်ပက်တွင် လက်သုံးချောင်းဖြင့် အပေါ်သို့ပွတ်ဆွဲပြီး ဖိထားပါ"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"အက်ပ်များကူးပြောင်းခြင်း"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"တာ့ချ်ပက်တွင် လက်လေးချောင်းဖြင့် ညာပွတ်ဆွဲပါ"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"တော်ပါပေသည်။"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"အက်ပ်ပြောင်းလက်ဟန် လုပ်ပြီးပါပြီ။"</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"အက်ပ်များကူးပြောင်းရန် တာ့ချ်ပက်တွင် လက်လေးချောင်းဖြင့် ညာပွတ်ဆွဲပါ"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"အက်ပ်အားလုံးကို ကြည့်ခြင်း"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ကီးဘုတ်တွင် လုပ်ဆောင်ချက်ကီး နှိပ်ပါ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"အလွန်ကောင်းပါသည်။"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index a264772..44686a4 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batteriprosenten er ukjent."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Koblet til <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Koblet til <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Ikke tilkoblet."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Av"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"For å åpne en app ved hjelp av en modul må du bekrefte at det er deg. Husk også at hvem som helst kan se dem, selv om nettbrettet er låst. Noen moduler er kanskje ikke laget for å være på låseskjermen og kan være utrygge å legge til der."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Greit"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Knapp for å vise skjermspareren"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Utforsk Hub-modus"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Bruk moduler og skjermsparere mens du lader."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Sett i gang"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Bytt bruker"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullegardinmeny"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Vises øverst på samtalevarsler og som et profilbilde på låseskjermen, vises som en boble, avbryter «Ikke forstyrr»"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> støtter ikke samtalefunksjoner"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Lukk"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ikke vis igjen"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Disse varslene kan ikke endres."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Anropsvarsler kan ikke endres."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Denne varselgruppen kan ikke konfigureres her"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kalkulator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Slå filtertaster av eller på"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Slå musetaster av eller på"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Slå trege taster av eller på"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Slå hengende taster av eller på"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Slå taletilgang av eller på"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ikke forstyrr"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Hurtigtast for volumknappene"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Bruk fingeravtrykk for å åpne"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autentisering kreves. Trykk på fingeravtrykkssensoren for å autentisere."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Aktiv samtale"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobildata"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Tilkoblet"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Koblet til midlertidig"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Du har fullført bevegelsen for å se nylige apper."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"For å se nylige apper, sveip opp og hold med tre fingre på styreflaten"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Bytt app"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Sveip til høyre med fire fingre på styreflaten"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Bra jobbet!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Du har fullført bytt-app-bevegelsen."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Sveip til høyre med fire fingre på styreflaten for å bytte app"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Se alle apper"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Trykk på handlingstasten på tastaturet"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bra!"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index ad7ffce..0e479ec 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ब्याट्रीमा कति प्रतिशत चार्ज छ भन्ने कुराको जानाकरी छैन।"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> मा जडित।"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> मा कनेक्ट गरियो।"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"जडान नगरिएको।"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"रोमिङ"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"निष्क्रिय पार्नु"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"विजेट प्रयोग गरी एप खोल्न तपाईंले आफ्नो पहिचान पुष्टि गर्नु पर्ने हुन्छ। साथै, तपाईंको ट्याब्लेट लक भएका बेला पनि सबै जनाले तिनलाई देख्न सक्छन् भन्ने कुरा ख्याल गर्नुहोस्। केही विजेटहरू लक स्क्रिनमा प्रयोग गर्ने उद्देश्यले नबनाइएका हुन सक्छन् र तिनलाई यहाँ हाल्नु सुरक्षित नहुन सक्छ।"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"बुझेँ"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"स्क्रिनसेभर देखाउने बटन"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"हब मोडको अन्वेषण गर्नुहोस्"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"चार्ज गर्दै गर्दा आफूलाई मन पर्ने विजेट तथा स्क्रिन सेभर एक्सेस गर्नुहोस्।"</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"सुरु गरौँ"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"प्रयोगकर्ता फेर्नुहोस्"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेनु"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"यो वार्तालापका सूचनाहरूको सिरानमा, बबलका रूपमा र लक स्क्रिनमा प्रोफाइल फोटोका रूपमा देखिन्छ। साथै, यसले गर्दा \'बाधा नपुऱ्याउनुहोस्\' नामक सुविधामा अवरोध आउँछ"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"प्राथमिकता"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा वार्तालापसम्बन्धी सुविधा प्रयोग गर्न मिल्दैन"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"हटाउनुहोस्"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"फेरि नदेखाउनुहोस्"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"यी सूचनाहरू परिमार्जन गर्न मिल्दैन।"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"कलसम्बन्धी सूचनाहरू परिमार्जन गर्न मिल्दैन।"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"यहाँबाट सूचनाहरूको यो समूह कन्फिगर गर्न सकिँदैन"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"पात्रो"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"क्याल्कुलेटर"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"नक्सा"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"बाउन्स कीहरू टगल गर्नुहोस्"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"माउस कीहरू टगल गर्नुहोस्"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"स्टिकी कीहरू टगल गर्नुहोस्"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"स्लो कीहरू टगल गर्नुहोस्"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Access टगल गर्नुहोस्"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"बाधा नपुऱ्याउनुहोस्"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"भोल्युम बटनका सर्टकट"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"फिंगरप्रिन्ट प्रयोग गरी खोल्नुहोस्"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"पुष्टि गर्नु पर्ने हुन्छ। पुष्टि गर्न फिंगरप्रिन्ट सेन्सर छुनुहोस्।"</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"कल भइरहेको"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"मोबाइल डेटा"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"इन्टरनेटमा कनेक्ट गरिएको छ"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"यसमा केही समयका लागि कनेक्ट गरिएको हो"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"तपाईंले जेस्चर प्रयोग गरी हालसालै चलाइएका एपहरू हेर्ने तरिका सिक्नुभएको छ।"</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"हालसालैका एपहरू हेर्न तीन औँला प्रयोग गरी टचप्याडमा माथितिर स्वाइप गर्नुहोस् र होल्ड गर्नुहोस्"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"एपहरू बदल्नुहोस्"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"चार वटा औँला प्रयोग गरी टचप्याडमा दायाँतिर स्वाइप गर्नुहोस्"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"अद्भुत!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"तपाईंले एपहरू बदल्ने जेस्चर प्रयोग गर्ने तरिका सिक्नुभयो।"</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"एपहरू अदलबदल गर्न चार वटा औँला प्रयोग गरी टचप्याडमा दायाँतिर स्वाइप गर्नुहोस्"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"सबै एपहरू हेर्नुहोस्"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"आफ्नो किबोर्डमा भएको एक्सन की थिच्नुहोस्"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"स्याबास!"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index b9b025a..9e3ed9b 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batterijpercentage onbekend."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Verbonden met <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Verbonden met <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Niet verbonden."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Uit"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Hub-modus verkennen"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Krijg toegang tot je favoriete widgets en screensavers terwijl je apparaat wordt opgeladen."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Aan de slag"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wordt getoond bovenaan gespreksmeldingen en als profielfoto op het vergrendelscherm, verschijnt als bubbel, onderbreekt Niet storen"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioriteit"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ondersteunt geen gespreksfuncties"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Sluiten"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Niet meer tonen"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Deze meldingen kunnen niet worden aangepast."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Gespreksmeldingen kunnen niet worden aangepast."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Deze groep meldingen kan hier niet worden ingesteld"</string>
@@ -915,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Rekenmachine"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Stuitertoetsen aan-/uitzetten"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Muistoetsen aan-/uitzetten"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Plaktoetsen aan-/uitzetten"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Langzame toetsen aan-/uitzetten"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Spraaktoegang aan-/uitzetten"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"TalkBack aan-/uitzetten"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Vergroting aan-/uitzetten"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"\'Selecteer om voor te lezen\' activeren"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Niet storen"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Volumeknoppen als sneltoets"</string>
     <string name="battery" msgid="769686279459897127">"Batterij"</string>
@@ -1304,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Gebruik vingerafdruk om te openen"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Verificatie vereist. Raak de vingerafdruksensor aan om de verificatie uit te voeren."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Actief gesprek"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobiele data"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Verbonden"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Tijdelijk verbonden"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index c0081de..181980b 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ବ୍ୟାଟେରୀ ଶତକଡ଼ା ଅଜଣା ଅଟେ।"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> ସହ ସଂଯୁକ୍ତ"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> ସହିତ ସଂଯୁକ୍ତ।"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"କନେକ୍ଟ ହୋଇନାହିଁ।"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"ରୋମିଙ୍ଗ"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"ବନ୍ଦ ଅଛି"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ଏକ ୱିଜେଟ ବ୍ୟବହାର କରି ଗୋଟିଏ ଆପ ଖୋଲିବା ପାଇଁ ଏହା ଆପଣ ଅଟନ୍ତି ବୋଲି ଆପଣଙ୍କୁ ଯାଞ୍ଚ କରିବାକୁ ହେବ। ଆହୁରି ମଧ୍ୟ, ଆପଣଙ୍କ ଟାବଲେଟ ଲକ ଥିଲେ ମଧ୍ୟ ଯେ କୌଣସି ବ୍ୟକ୍ତି ଏହାକୁ ଭ୍ୟୁ କରିପାରିବେ ବୋଲି ମନେ ରଖନ୍ତୁ। କିଛି ୱିଜେଟ ଆପଣଙ୍କ ଲକ ସ୍କ୍ରିନ ପାଇଁ ଉଦ୍ଦିଷ୍ଟ ହୋଇନଥାଇପାରେ ଏବଂ ଏଠାରେ ଯୋଗ କରିବା ଅସୁରକ୍ଷିତ ହୋଇପାରେ।"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ବୁଝିଗଲି"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"ସ୍କ୍ରିନସେଭର ବଟନ ଦେଖାନ୍ତୁ"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"ହବ ମୋଡକୁ ଏକ୍ସପ୍ଲୋର କରନ୍ତୁ"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"ଚାର୍ଜ କରିବା ସମୟରେ ଆପଣଙ୍କ ପସନ୍ଦର ୱିଜେଟ ଏବଂ ସ୍କ୍ରିନ ସେଭରଗୁଡ଼ିକୁ ଆକ୍ସେସ କରନ୍ତୁ।"</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"ଚାଲନ୍ତୁ ଆରମ୍ଭ କରିବା"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ୟୁଜର୍‍ ବଦଳାନ୍ତୁ"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ପୁଲଡାଉନ ମେନୁ"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ବାର୍ତ୍ତାଳାପ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଶୀର୍ଷରେ ଏବଂ ଲକ୍ ସ୍କ୍ରିନରେ ଏକ ପ୍ରୋଫାଇଲ୍ ଛବି ଭାବେ ଦେଖାଏ, ଏକ ବବଲ୍ ଭାବେ ଦେଖାଯାଏ, \'ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\'କୁ ବାଧା ଦିଏ"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ପ୍ରାଥମିକତା"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବାର୍ତ୍ତାଳାପ ଫିଚରଗୁଡ଼ିକୁ ସମର୍ଥନ କରେ ନାହିଁ"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"ଖାରଜ କରନ୍ତୁ"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"ପୁଣି ଶୋ କରନ୍ତୁ ନାହିଁ"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପରିବର୍ତ୍ତନ କରିହେବ ନାହିଁ।"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"କଲ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ପରିବର୍ତ୍ତନ କରାଯାଇପାରିବ ନାହିଁ।"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ଏଠାରେ ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଗ୍ରୁପ୍ କନଫ୍ୟୁଗର୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"କାଲକୁଲେଟର"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"ବାଉନ୍ସ କୀ ଟୋଗଲ କରନ୍ତୁ"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"ମାଉସ କୀ ଟୋଗଲ କରନ୍ତୁ"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"ଷ୍ଟିକି କୀ ଟୋଗଲ କରନ୍ତୁ"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"ଧିର କୀ ଟୋଗଲ କରନ୍ତୁ"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Access ଟୋଗଲ କରନ୍ତୁ"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ଭଲ୍ୟୁମ ବଟନ୍‍ ଶର୍ଟକଟ୍‍"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ଖୋଲିବାକୁ ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ପ୍ରମାଣୀକରଣ ଆବଶ୍ୟକ। ପ୍ରମାଣୀକରଣ କରିବାକୁ ଟିପଚିହ୍ନ ସେନ୍ସରକୁ ସ୍ପର୍ଶ କରନ୍ତୁ।"</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"ଚାଲିଥିବା କଲ"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"ମୋବାଇଲ ଡାଟା"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"ସଂଯୋଗ କରାଯାଇଛି"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"ଅସ୍ଥାୟୀ ରୂପେ କନେକ୍ଟ କରାଯାଇଛି"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"ଆପଣ ବର୍ତ୍ତମାନର ଆପ୍ସ ଜେଶ୍ଚରକୁ ଭ୍ୟୁ କରିବା ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।"</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"ବର୍ତ୍ତମାନର ଆପ୍ସ ଭ୍ୟୁ କରିବାକୁ, ଆପଣଙ୍କ ଟଚପେଡରେ ତିନୋଟି ଆଙ୍ଗୁଠି ବ୍ୟବହାର କରି ଉପରକୁ ସ୍ୱାଇପ କରି ଧରି ରଖନ୍ତୁ"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"ଆପ୍ସକୁ ସୁଇଚ କରନ୍ତୁ"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"ଆପଣଙ୍କ ଟଚପେଡରେ ଚାରି ଆଙ୍ଗୁଠି ବ୍ୟବହାର କରି ଡାହାଣକୁ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"ବଢ଼ିଆ କାମ!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"ଆପଣ ସୁଇଚ ଆପ୍ସ ଜେଶ୍ଚର ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।"</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"ଆପ୍ସକୁ ସୁଇଚ କରିବାକୁ ଆପଣଙ୍କ ଟଚପେଡରେ ଚାରି ଆଙ୍ଗୁଠି ବ୍ୟବହାର କରି ଡାହାଣକୁ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"ସବୁ ଆପ ଭ୍ୟୁ କରନ୍ତୁ"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ଆପଣଙ୍କର କୀବୋର୍ଡରେ ଆକ୍ସନ କୀ\'କୁ ଦବାନ୍ତୁ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ବହୁତ ବଢ଼ିଆ!"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 23a94b0..b338e1b 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ਬੈਟਰੀ ਪ੍ਰਤੀਸ਼ਤ ਅਗਿਆਤ ਹੈ।"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ।"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ।"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ।"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"ਰੋਮਿੰਗ"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"ਬੰਦ"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"ਹੱਬ ਮੋਡ ਦੀ ਪੜਚੋਲ ਕਰੋ"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"ਚਾਰਜ ਕਰਨ ਵੇਲੇ ਆਪਣੇ ਮਨਪਸੰਦ ਵਿਜੇਟਾਂ ਅਤੇ ਸਕ੍ਰੀਨ ਸੇਵਰਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰੋ।"</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"ਚਲੋ ਸ਼ੁਰੂ ਕਰੀਏ"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"ਗੱਲਬਾਤ ਸੂਚਨਾਵਾਂ ਦੇ ਸਿਖਰ \'ਤੇ ਅਤੇ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਵਜੋਂ ਦਿਖਾਈਆਂ ਜਾਂਦੀਆਂ ਹਨ, ਜੋ ਕਿ ਬਬਲ ਵਜੋਂ ਦਿਸਦੀਆਂ ਹਨ ਅਤੇ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਸੁਵਿਧਾ ਵਿੱਚ ਵਿਘਨ ਵੀ ਪਾ ਸਕਦੀਆਂ ਹਨ"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ਤਰਜੀਹ"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ ਗੱਲਬਾਤ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"ਖਾਰਜ ਕਰੋ"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"ਦੁਬਾਰਾ ਨਾ ਦਿਖਾਓ"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਸੋਧਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ਕਾਲ ਸੰਬੰਧੀ ਸੂਚਨਾਵਾਂ ਨੂੰ ਸੋਧਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ਇਹ ਸੂਚਨਾਵਾਂ ਦਾ ਗਰੁੱਪ ਇੱਥੇ ਸੰਰੂਪਿਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
@@ -915,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"ਨਕਸ਼ੇ"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"ਬਾਊਂਸ ਕੁੰਜੀਆਂ ਨੂੰ ਟੌਗਲ ਕਰੋ"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"ਮਾਊਸ ਕੁੰਜੀਆਂ ਨੂੰ ਟੌਗਲ ਕਰੋ"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"ਸਥਿਰ ਕੁੰਜੀਆਂ ਨੂੰ ਟੌਗਲ ਕਰੋ"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"ਧੀਮੀਆਂ ਕੁੰਜੀਆਂ ਨੂੰ ਟੌਗਲ ਕਰੋ"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Access ਨੂੰ ਟੌਗਲ ਕਰੋ"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"TalkBack ਨੂੰ ਟੌਗਲ ਕਰੋ"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"ਵੱਡਦਰਸ਼ੀਕਰਨ ਨੂੰ ਟੌਗਲ ਕਰੋ"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"\'ਚੁਣੋ ਅਤੇ ਸੁਣੋ\' ਨੂੰ ਕਿਰਿਆਸ਼ੀਲ ਕਰੋ"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ਵੌਲਿਊਮ ਬਟਨ ਸ਼ਾਰਟਕੱਟ"</string>
     <string name="battery" msgid="769686279459897127">"ਬੈਟਰੀ"</string>
@@ -1304,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ਖੋਲ੍ਹਣ ਲਈ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤੋ"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ਪ੍ਰਮਾਣੀਕਰਨ ਲੋੜੀਂਦਾ ਹੈ। ਪ੍ਰਮਾਣਿਤ ਕਰਨ ਲਈ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨੂੰ ਸਪਰਸ਼ ਕਰੋ।"</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"ਜਾਰੀ ਕਾਲ"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"ਮੋਬਾਈਲ ਡਾਟਾ"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"ਕਨੈਕਟ ਹੈ"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"ਕੁਝ ਸਮੇਂ ਲਈ ਕਨੈਕਟ ਹੈ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index fd41419..2d3d396 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Poziom naładowania baterii jest nieznany."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Połączono z <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Połączono z urządzeniem <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Nie połączono."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Wył."</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Aby otworzyć aplikację za pomocą widżetu, musisz potwierdzić swoją tożsamość. Pamiętaj też, że każdy będzie mógł wyświetlić widżety nawet wtedy, gdy tablet będzie zablokowany. Niektóre widżety mogą nie być przeznaczone do umieszczenia na ekranie blokady i ich dodanie w tym miejscu może być niebezpieczne."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Przycisk Pokaż wygaszacz ekranu"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Odkryj tryb centrali"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Podczas ładowania możesz korzystać z ulubionych widżetów i wygaszaczy ekranu."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Do dzieła"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Wyświetla się u góry powiadomień w rozmowach oraz jako zdjęcie profilowe na ekranie blokady, jako dymek, przerywa działanie trybu Nie przeszkadzać"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priorytetowe"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> nie obsługuje funkcji rozmów"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Zamknij"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Nie pokazuj ponownie"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Tych powiadomień nie można zmodyfikować."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Powiadomień o połączeniach nie można modyfikować."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Tej grupy powiadomień nie można tu skonfigurować"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendarz"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kalkulator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Mapy"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Przełącz ustawienie klawiszy z filtrem powtórzeń"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Przełącz ustawienie klawiszy myszy"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Przełącz ustawienie klawiszy trwałych"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Przełącz ustawienie klawiszy powolnych"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Przełącz ustawienie aplikacji Voice Access"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Nie przeszkadzać"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Wł./wył. przyciskami głośności"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"By otworzyć, użyj odcisku palca"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Wymagane uwierzytelnienie. Dotknij czytnika liniii papilarnych, by uwierzytelnić."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Trwa rozmowa"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobilna transmisja danych"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Połączono"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Tymczasowe połączenie"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Znasz już gest wyświetlania ostatnio używanych aplikacji."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Aby wyświetlić ostatnie aplikacje, przesuń 3 palcami w górę na touchpadzie i przytrzymaj"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Przełączanie aplikacji"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Przesuń 4 palcami w prawo po touchpadzie"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Brawo!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Gest do przełączania aplikacji został opanowany."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Aby przełączać aplikacje, przesuwaj 4 palcami w prawo po touchpadzie"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Wyświetl wszystkie aplikacje"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Naciśnij klawisz działania na klawiaturze"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Brawo!"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index b31296d..39c4dfe 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Porcentagem da bateria desconhecida."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Conectado a <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Sem conexão."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Desativados"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir um app usando um widget, você precisa confirmar sua identidade. E não se esqueça que qualquer pessoa pode ver os widgets, mesmo com o tablet bloqueado. Além disso, alguns apps não foram criados para a tela de bloqueio, é melhor manter a segurança."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendi"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Botão \"Mostrar protetor de tela\""</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Conheça o modo Hub"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Acesse seus widgets e protetores de tela favoritos durante o carregamento."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Vamos lá"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparecem na parte superior das notificações de conversa, como uma foto do perfil na tela de bloqueio e como um balão. Interrompem o Não perturbe."</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritárias"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não é compatível com recursos de conversa"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Dispensar"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Não mostrar novamente"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar essas notificações."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Não é possível modificar as notificações de chamada."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Não é possível configurar esse grupo de notificações aqui"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculadora"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Mapas"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Alternar teclas de filtragem"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Alternar teclas do mouse"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Alternar teclas de aderência"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Alternar teclas lentas"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Alternar Voice Access"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Não perturbe"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Atalho de botões de volume"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use a impressão digital para abrir"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autenticação obrigatória. Toque no sensor de impressão digital para autenticar."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Chamada em andamento"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Dados móveis"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Conectado"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Temporariamente conectado"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Você concluiu o gesto para ver os apps recentes."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Se quiser ver os apps recentes, deslize para cima e pressione o touchpad com três dedos"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Mudar de app"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Deslize para a direita com quatro dedos no touchpad"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Muito bem!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Você concluiu o gesto para mudar de app."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Deslize para a direita com quatro dedos no touchpad para mudar de app"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todos os apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pressione a tecla de ação no teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Muito bem!"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 9187391..cb9730a 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Percentagem da bateria desconhecida."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Ligado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Ligado a <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Sem ligação."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Desativado"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Explore o modo Hub"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Aceda aos seus widgets e proteções de ecrã favoritos durante o carregamento."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Começar"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparece na parte superior das notificações de conversas e como uma imagem do perfil no ecrã de bloqueio, surge como um balão, interrompe o modo Não incomodar"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> não suporta funcionalidades de conversa."</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Ignorar"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Não mostrar novamente"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar estas notificações."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Não é possível modificar as notificações de chamadas."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Não é possível configurar este grupo de notificações aqui."</string>
@@ -915,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendário"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculadora"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Ativar/desativar a funcionalidade evitar pressão repetida"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Ativar/desativar teclas do rato"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Ativar/desativar teclas aderentes"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Ativar/desativar teclas lentas"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Ativar/desativar Voice Access"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Ativar/desativar TalkBack"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Ativar/desativar ampliação"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"Ativar Selecionar para falar"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Não incomodar"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Atalho dos botões de volume"</string>
     <string name="battery" msgid="769686279459897127">"Bateria"</string>
@@ -1304,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Utilize a impressão digital para abrir"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autenticação necessária. Toque no sensor de impressões digitais para autenticar."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Chamada em curso"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Dados móveis"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Ligado"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Ligado temporariamente"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index b31296d..39c4dfe 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Porcentagem da bateria desconhecida."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Conectado a <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Sem conexão."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Desativados"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir um app usando um widget, você precisa confirmar sua identidade. E não se esqueça que qualquer pessoa pode ver os widgets, mesmo com o tablet bloqueado. Além disso, alguns apps não foram criados para a tela de bloqueio, é melhor manter a segurança."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendi"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Botão \"Mostrar protetor de tela\""</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Conheça o modo Hub"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Acesse seus widgets e protetores de tela favoritos durante o carregamento."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Vamos lá"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Aparecem na parte superior das notificações de conversa, como uma foto do perfil na tela de bloqueio e como um balão. Interrompem o Não perturbe."</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritárias"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não é compatível com recursos de conversa"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Dispensar"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Não mostrar novamente"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Não é possível modificar essas notificações."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Não é possível modificar as notificações de chamada."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Não é possível configurar esse grupo de notificações aqui"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Agenda"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculadora"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Mapas"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Alternar teclas de filtragem"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Alternar teclas do mouse"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Alternar teclas de aderência"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Alternar teclas lentas"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Alternar Voice Access"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Não perturbe"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Atalho de botões de volume"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use a impressão digital para abrir"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autenticação obrigatória. Toque no sensor de impressão digital para autenticar."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Chamada em andamento"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Dados móveis"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Conectado"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Temporariamente conectado"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Você concluiu o gesto para ver os apps recentes."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Se quiser ver os apps recentes, deslize para cima e pressione o touchpad com três dedos"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Mudar de app"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Deslize para a direita com quatro dedos no touchpad"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Muito bem!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Você concluiu o gesto para mudar de app."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Deslize para a direita com quatro dedos no touchpad para mudar de app"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todos os apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pressione a tecla de ação no teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Muito bem!"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index fc23118..a6d11f4 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Procentajul bateriei este necunoscut."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectat la <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"S-a stabilit conexiunea la <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Neconectat."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Dezactivate"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Pentru a deschide o aplicație folosind un widget, va trebui să-ți confirmi identitatea. În plus, reține că oricine poate să vadă widgeturile, chiar dacă tableta este blocată. Este posibil ca unele widgeturi să nu fi fost create pentru ecranul de blocare și poate fi nesigur să le adaugi aici."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Butonul Afișează screensaverul"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Explorează modul hub"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Accesează widgeturile și screensaverele preferate în timpul încărcării."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Să începem"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Se afișează în partea de sus a notificărilor pentru conversații și ca fotografie de profil pe ecranul de blocare, apare ca un balon, întrerupe funcția Nu deranja"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritate"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu acceptă funcții pentru conversații"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Închide"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Nu mai afișa"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Aceste notificări nu pot fi modificate."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Notificările pentru apeluri nu pot fi modificate."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Acest grup de notificări nu poate fi configurat aici"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Comută evitarea apăsării repetate"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Comută tastele pentru mouse"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Comută tastele adezive"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Comută tastele lente"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Comută Accesul vocal"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Nu deranja"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Comandă rapidă din butoanele de volum"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Folosește amprenta ca să deschizi"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autentificare obligatorie. Atinge senzorul de amprentă pentru a te autentifica."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Apel în desfășurare"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Date mobile"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Conectat"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Conectat temporar"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Ai finalizat gestul pentru afișarea aplicațiilor recente."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Ca să vezi aplicațiile recente, glisează în sus și ține apăsat cu trei degete pe touchpad"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Comută între aplicații"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Glisează spre dreapta cu patru degete pe touchpad"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Excelent!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Ai finalizat gestul de trecere la altă aplicație."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Glisează la dreapta cu patru degete pe touchpad pentru a comuta între aplicații"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Vezi toate aplicațiile"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Apasă tasta de acțiuni de pe tastatură"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Felicitări!"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 5b0ce2e..46007fe 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Уровень заряда батареи в процентах неизвестен."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>: подключено."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Подключено к: <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Не подключено"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Роуминг"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Отключен"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Чтобы открыть приложение, используя виджет, вам нужно будет подтвердить свою личность. Обратите внимание, что виджеты видны всем, даже если планшет заблокирован. Некоторые виджеты не предназначены для использования на заблокированном экране. Добавлять их туда может быть небезопасно."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ОК"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Кнопка \"Показать заставку\""</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Попробуйте режим домашнего центра"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Пока устройство заряжается, будут показываться любимые заставки и вы сможете пользоваться привычными виджетами."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Попробовать"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Сменить пользователя."</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"раскрывающееся меню"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Появляется в верхней части уведомлений о сообщениях, в виде всплывающего чата, а также в качестве фото профиля на заблокированном экране, прерывает режим \"Не беспокоить\"."</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Приоритет"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" не поддерживает функции разговоров."</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Закрыть"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Больше не показывать"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Эти уведомления нельзя изменить."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Уведомления о звонках нельзя изменить."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Эту группу уведомлений нельзя настроить здесь."</string>
@@ -918,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календарь"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Калькулятор"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Карты"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Включить или отключить контроль повторного нажатия"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Включить или отключить управление указателем с клавиатуры"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Включить или отключить залипание клавиш"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Включить или отключить долгие нажатия клавиш"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Включить или отключить Voice Access"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Включить или отключить TalkBack"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Включить или отключить увеличение"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"Включить Озвучивание при нажатии"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не беспокоить"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Кнопки регулировки громкости"</string>
     <string name="battery" msgid="769686279459897127">"Батарея"</string>
@@ -1290,7 +1289,7 @@
     <string name="missed_call" msgid="4228016077700161689">"Пропущенный вызов"</string>
     <string name="messages_count_overflow_indicator" msgid="7850934067082006043">"<xliff:g id="NUMBER">%d</xliff:g>+"</string>
     <string name="people_tile_description" msgid="8154966188085545556">"Будьте в курсе последних сообщений, пропущенных вызовов и обновлений статуса."</string>
-    <string name="people_tile_title" msgid="6589377493334871272">"Чат"</string>
+    <string name="people_tile_title" msgid="6589377493334871272">"Разговор"</string>
     <string name="paused_by_dnd" msgid="7856941866433556428">"Приостановлено в режиме \"Не беспокоить\""</string>
     <string name="new_notification_text_content_description" msgid="2915029960094389291">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> отправил сообщение: <xliff:g id="NOTIFICATION">%2$s</xliff:g>"</string>
     <string name="new_notification_image_content_description" msgid="6017506886810813123">"Пользователь <xliff:g id="NAME">%1$s</xliff:g> отправил изображение"</string>
@@ -1307,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Используйте отпечаток пальца для входа."</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Требуется аутентификация. Приложите палец к сканеру отпечатков."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Текущий вызов"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобильный интернет"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Подключено"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Временное подключение"</string>
@@ -1454,7 +1455,7 @@
     <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Это приложение"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Специальные возможности"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Сочетания клавиш"</string>
-    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Настройки сочетаний клавиш"</string>
+    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Настройка сочетаний клавиш"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Удалить сочетание клавиш?"</string>
     <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Сбросить настройки?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"Чтобы сохранить сочетание клавиш, нажмите одновременно клавишу действия и одну или несколько дополнительных клавиш"</string>
@@ -1512,12 +1513,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Вы выполнили жест для просмотра недавних приложений."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Чтобы увидеть недавние приложения, проведите по сенсорной панели тремя пальцами вверх и удерживайте."</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Переход в другое приложение"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Проведите по сенсорной панели четырьмя пальцами вправо."</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Отлично!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Вы выполнили жест перехода в другое приложение."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Для перехода в другое приложение проведите по сенсорной панели четырьмя пальцами вправо."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Все приложения"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Нажмите клавишу действия на клавиатуре."</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Блестяще!"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 1c25011..7c1c440 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"බැටරි ප්‍රතිශතය නොදනී."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> වෙත සම්බන්ධ කරන ලදි."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> වෙත සම්බන්ධ විය."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"සම්බන්ධ වී නැත."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"රෝමිං"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"ක්‍රියාවිරහිතයි"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"විජට් එකක් භාවිතයෙන් යෙදුමක් විවෘත කිරීමට, ඔබට ඒ ඔබ බව සත්‍යාපනය කිරීමට අවශ්‍ය වනු ඇත. එසේම, ඔබේ ටැබ්ලටය අගුළු දමා ඇති විට පවා ඕනෑම කෙනෙකුට ඒවා බැලිය හැකි බව මතක තබා ගන්න. සමහර විජට් ඔබේ අගුළු තිරය සඳහා අදහස් කර නොතිබිය හැකි අතර මෙහි එක් කිරීමට අනාරක්ෂිත විය හැක."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"තේරුණා"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"තිර සුරැකුම් බොත්තම පෙන්වන්න"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"හබ් ප්‍රකාරය ගවේෂණය කරන්න"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"ආරෝපණය කරන අතරේ ඔබේ ප්‍රියතම විජට් සහ තිර සුරැකුම් වෙත ප්‍රවේශ වන්න."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"යමු"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"පරිශීලක මාරුව"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"නිපතන මෙනුව"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"සංවාද දැනුම්දීම්වල ඉහළින්ම සහ අගුලු තිරයේ ඇති පැතිකඩ පින්තූරයක් ලෙස පෙන්වයි, බුබුළක් ලෙස දිස් වේ, බාධා නොකරන්න සඳහා බාධා කරයි"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ප්‍රමුඛතාව"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> සංවාද විශේෂාංගවලට සහාය නොදක්වයි"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"අස් කරන්න"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"නැවත නොපෙන්වන්න"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"මෙම දැනුම්දීම් වෙනස් කළ නොහැක."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"ඇමතුම් දැනුම්දීම් වෙනස් කළ නොහැකිය."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"මෙම දැනුම්දීම් සමූහය මෙහි වින්‍යාස කළ නොහැක"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"දින දර්ශනය"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"ගණකය"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"සිතියම්"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"උඩ පනින යතුරු ටොගල කරන්න"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"මූසික යතුරු ටොගල් කරන්න"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"ඇලෙන සුළු යතුරු ටොගල් කරන්න"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"මන්දගාමී යතුරු ටොගල් කරන්න"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"හඬ ප්‍රවේශය ටොගල් කරන්න"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"බාධා නොකරන්න"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"හඩ පරිමා බොත්තම් කෙටිමග"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"විවෘත කිරීමට ඇඟිලි සලකුණ භාවිත කරන්න"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"සත්‍යාපනය අවශ්‍යයි. සත්‍යාපනය කිරීමට ඇඟිලි සලකුණු සංවේදකය ස්පර්ශ කරන්න."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"කර ගෙන යන ඇමතුම"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"ජංගම දත්ත"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"සම්බන්ධයි"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"තාවකාලිකව සම්බන්ධ කළා"</string>
@@ -1454,7 +1458,7 @@
     <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"වත්මන් යෙදුම"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ප්‍රවේශ්‍යතාව"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"යතුරු පුවරු කෙටි මං"</string>
-    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"කෙටිමං අභිරුචිකරණය කරන්න"</string>
+    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"කෙටිමං අභිරුචිකරණය"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"කෙටිමඟ ඉවත් කරන්න ද?"</string>
     <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"පෙරනිමියට යළි සකසන්න ද?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"මෙම කෙටිමඟ නිර්මාණය කිරීමට, ක්‍රියාකාරී යතුර සහ තවත් යතුරු එකක් හෝ කිහිපයක් එකවර ඔබන්න"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"ඔබ මෑත යෙදුම් ඉංගිත බැලීම සම්පූර්ණ කර ඇත."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"මෑත කාලීන යෙදුම් බැලීමට, ඔබේ ස්පර්ශක පෑඩයේ ඇඟිලි තුනක් භාවිතයෙන් ඉහළට ස්වයිප් කරගෙන සිටින්න"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"යෙදුම් මාරු කරන්න"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"ඔබේ ස්පර්ශක පෑඩයේ ඇඟිලි හතරක් භාවිතයෙන් දකුණට ස්වයිප් කරන්න"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"අනර්ඝ වැඩක්!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"ඔබ යෙදුම් මාරු කිරීමේ ඉංගිතය සම්පූර්ණ කර ඇත."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"යෙදුම් මාරු කිරීමට ඔබේ ස්පර්ශක පෑඩයේ ඇඟිලි හතරක් භාවිතයෙන් දකුණට ස්වයිප් කරන්න"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"සියලු යෙදුම් බලන්න"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ඔබේ යතුරු පුවරුවේ ක්‍රියාකාරී යතුර ඔබන්න"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"හොඳින් කළා!"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 07eb200..3851173 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Percento batérie nie je známe."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Pripojené k zariadeniu <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Pripojené k zariadeniu <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Nepripojené."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Vypnuté"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ak chcete otvoriť aplikáciu pomocou miniaplikácie, budete musieť overiť svoju totožnosť. Pamätajte, že si miniaplikáciu môže pozrieť ktokoľvek, aj keď máte tablet uzamknutý. Niektoré miniaplikácie možno nie sú určené pre uzamknutú obrazovku a ich pridanie tu môže byť nebezpečné."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Dobre"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Zobraziť tlačidlo šetriča obrazovky"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Preskúmajte režim centra"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Počas nabíjania máte prístup k svojim obľúbeným miniaplikáciám a šetričom obrazovky."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Poďme na to"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Zobrazuje sa ako bublina v hornej časti upozornení konverzácie a profilová fotka na uzamknutej obrazovke, preruší režim bez vyrušení"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritné"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nepodporuje funkcie konverzácie"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Zavrieť"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Nabudúce nezobrazovať"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Tieto upozornenia sa nedajú upraviť."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Upozornenia na hovory sa nedajú upraviť."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Túto skupinu upozornení nejde na tomto mieste konfigurovať"</string>
@@ -881,12 +882,12 @@
     <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Zobrazenie upozornení"</string>
     <string name="group_system_full_screenshot" msgid="5742204844232667785">"Vytvorenie snímky obrazovky"</string>
     <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Zobrazenie skratiek"</string>
-    <string name="group_system_go_back" msgid="2730322046244918816">"Prechod späť"</string>
-    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Prechod na plochu"</string>
-    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Zobrazenie nedávnych aplikácií"</string>
-    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Cyklické prechádzanie dopredu nedávnymi aplikáciámi"</string>
-    <string name="group_system_cycle_back" msgid="8194102916946802902">"Cyklické prechádzanie dozadu nedávnymi aplikáciami"</string>
-    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Otvorenie zoznamu aplikácií"</string>
+    <string name="group_system_go_back" msgid="2730322046244918816">"Späť"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Prejsť na plochu"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Zobraziť nedávne aplikácie"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Prechádzať nedávnymi aplikáciami"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Prechádzať nedávnymi aplikáciami opačne"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Otvoriť zoznam aplikácií"</string>
     <string name="group_system_access_system_settings" msgid="8731721963449070017">"Otvorenie nastavení"</string>
     <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otvorenie Asistenta"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Uzamknutie obrazovky"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendár"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kalkulačka"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Mapy"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Prepnúť na opakované stlačenia"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Prepnúť na myš klávesnicou"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Prepnúť na režim uzamknutia klávesa"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Prepnúť na pomalé klávesy"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Prepnúť na Voice Access"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Režim bez vyrušení"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Skratka tlačidiel hlasitosti"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Otvorte odtlačkom prsta"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Vyžaduje sa overenie. Dotknite sa senzora odtlačkov prstov."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Prebiehajúci hovor"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobilné dáta"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Pripojené"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Dočasne pripojené"</string>
@@ -1459,7 +1463,7 @@
     <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Chcete resetovať na predvolené nastavenie?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"Ak chcete vytvoriť túto skratku, stlačte súčasne akčný kláves a minimálne jeden ďalší kláves"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Týmto natrvalo odstránite vlastnú skratku."</string>
-    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Týmto natrvalo odstránite všetky vlastné odkazy."</string>
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Týmto natrvalo odstránite všetky vlastné skratky."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prehľadávať skratky"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Žiadne výsledky vyhľadávania"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zbalenia"</string>
@@ -1476,7 +1480,7 @@
     <string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Nastavenia klávesnice"</string>
     <string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nastaviť skratku"</string>
     <string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Odstrániť"</string>
-    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Áno, resetovať"</string>
+    <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Resetovať"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Zrušiť"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Stlačte kláves"</string>
     <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="3325858369539848162">"Kombinácia klávesov sa už používa. Skúste inú kombináciu."</string>
@@ -1490,13 +1494,13 @@
     <string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Naučte sa gestá touchpadu"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Pohybujte sa v systéme pomocou klávesnice a touchpadu"</string>
     <string name="launch_keyboard_touchpad_tutorial_notification_content" msgid="1780725168171929365">"Naučte sa gestá touchpadu, klávesové skratky a ďalšie funkcie"</string>
-    <string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Prechod späť"</string>
+    <string name="touchpad_tutorial_back_gesture_button" msgid="3104716365403620315">"Späť"</string>
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Prejsť na plochu"</string>
-    <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Zobrazenie nedávnych aplikácií"</string>
+    <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Zobraziť nedávne aplikácie"</string>
     <string name="touchpad_tutorial_switch_apps_gesture_button" msgid="7768255095423767779">"Prepínanie aplikácií"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Hotovo"</string>
     <string name="gesture_error_title" msgid="469064941635578511">"Skúste to znova."</string>
-    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Prejdenie späť"</string>
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Späť"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Potiahnite troma prstami na touchpade doľava alebo doprava"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Výborne!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Použili ste gesto na prechod späť."</string>
@@ -1506,18 +1510,16 @@
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Skvelé!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Použili ste gesto na prechod na plochu."</string>
     <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Ak chcete prejsť na plochu, potiahnite troma prstami na touchpade"</string>
-    <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Zobrazenie nedávnych aplikácií"</string>
+    <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Zobraziť nedávne aplikácie"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Potiahnite troma prstami na touchpade nahor a pridržte"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Skvelé!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Použili ste gesto na zobrazenie nedávnych aplikácií."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Ak si chcete zobraziť nedávne aplikácie, potiahnite troma prstami na touchpade nahor a pridržte ich"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Prepínanie aplikácií"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Potiahnite na touchpade štyrmi prstami doprava"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Skvelé!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Dokončili ste gesto na prepnutie aplikácií."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Aplikácie prepnete tak, že potiahnete štyrmi prstami na touchpade doprava"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Zobrazenie všetkých aplikácií"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Stlačte na klávesnici akčný kláves"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Dobre!"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index e0c65e3..be51fbb 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Neznan odstotek napolnjenosti baterije."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Povezava vzpostavljena z: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Vzpostavljena povezava: <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Ni povezan."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Gostovanje"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Izklopljeno"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Raziščite način središča"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Med polnjenjem dostopajte do priljubljenih pripomočkov in ohranjevalnikov zaslona."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Pa začnimo"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -913,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Koledar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Računalo"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Zemljevidi"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Preklopi prezrtje hitrih zaporednih pritiskov tipk"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Preklopi tipke za miško"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Preklopi zaklepanje tipk"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Preklopi daljši pritisk tipk"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Preklopi Glasovni dostop"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ne moti"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Bližnjica z gumboma za glasnost"</string>
@@ -1302,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Odprite s prstnim odtisom"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Zahtevano je preverjanje pristnosti. Za preverjanje pristnosti se dotaknite tipala prstnih odtisov."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Aktivni klic"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Prenos podatkov v mobilnem omrežju"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Povezano"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Začasno vzpostavljena povezava"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index f6bd8b5..e40ef60 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Përqindja e baterisë e panjohur."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Lidhur me <xliff:g id="BLUETOOTH">%s</xliff:g>"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Është lidhur me <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Nuk është i lidhur."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Joaktiv"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Për të hapur një aplikacion duke përdorur një miniaplikacion, do të duhet të verifikosh që je ti. Ki parasysh gjithashtu që çdo person mund t\'i shikojë, edhe kur tableti yt është i kyçur. Disa miniaplikacione mund të mos jenë planifikuar për ekranin tënd të kyçjes dhe mund të mos jetë e sigurt t\'i shtosh këtu."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"E kuptova"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Shfaq butonin e mbrojtësit të ekranit"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Eksploro në modalitetin Hub"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Qasu në mbrojtësit e ekranit dhe miniaplikacionet e tua të preferuara gjatë karikimit."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Fillojmë"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -753,8 +756,7 @@
     <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"Po përditësohet"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Profili i punës"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Modaliteti i aeroplanit"</string>
-    <!-- no translation found for status_bar_supervision (6735015942701134125) -->
-    <skip />
+    <string name="status_bar_supervision" msgid="6735015942701134125">"Kontrollet prindërore"</string>
     <string name="zen_alarm_warning" msgid="7844303238486849503">"Nuk do ta dëgjosh alarmin e radhës në <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template" msgid="2234991538018805736">"në <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="3561752195856839456">"në <xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -805,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Shfaqet në krye të njoftimeve të bisedës dhe si fotografia e profilit në ekranin e kyçjes, shfaqet si flluskë dhe ndërpret modalitetin \"Mos shqetëso\""</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Me përparësi"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mbështet veçoritë e bisedës"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Hiq"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Mos e shfaq më"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Këto njoftime nuk mund të modifikohen."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Njoftimet e telefonatave nuk mund të modifikohen."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ky grup njoftimesh nuk mund të konfigurohet këtu"</string>
@@ -919,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalendari"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Makina llogaritëse"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Aktivizo/çaktivizo tastet e përsëritura"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Aktivizo/çaktivizo tastet e miut"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Aktivizo/çaktivizo tastet e përhershme"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Aktivizo/çaktivizo tastet e ngadalta"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Aktivizo/çaktivizo \"Qasjen me zë\""</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Mos shqetëso"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Shkurtorja e butonave të volumit"</string>
@@ -1308,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Përdor gjurmën e gishtit për ta hapur"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Kërkohet vërtetimi. Prek sensorin e gjurmës së gishtit për t\'u vërtetuar."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Telefonatë në vazhdim"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Të dhënat celulare"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Lidhur"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Lidhur përkohësisht"</string>
@@ -1513,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Përfundove gjestin për shikimin e aplikacioneve të fundit."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Për të shikuar aplikacionet e fundit, rrëshqit shpejt lart dhe mbaj shtypur me tre gishta në bllokun me prekje"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Ndërro aplikacionet"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Rrëshqit shpejt djathtas duke përdorur katër gishta në bllokun me prekje"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Punë e shkëlqyer!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"E ke përfunduar gjestin e ndërrimit të aplikacioneve."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Rrëshqit shpejt djathtas duke përdorur katër gishta në bllokun me prekje për të ndërruar aplikacionet"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Shiko të gjitha aplikacionet"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Shtyp tastin e veprimit në tastierë"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Shumë mirë!"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 9232888..ad837b4 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Проценат напуњености батерије није познат."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Повезани сте са <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Повезани смо са уређајем <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Није повезано."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Роминг"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Искључено"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Истражите режим центра"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Приступајте омиљеним виџетима и чуварима екрана током пуњења."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Идемо"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Приказује се у врху обавештења о конверзацијама и као слика профила на закључаном екрану, појављује се као облачић, прекида режим Не узнемиравај"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Приоритетно"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не подржава функције конверзације"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Одбаци"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Не приказуј поново"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ова обавештења не могу да се мењају."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Обавештења о позивима не могу да се мењају."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Ова група обавештења не може да се конфигурише овде"</string>
@@ -915,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Калкулатор"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Мапе"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Укључи или искључи дужи одзив тастера"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Укључи или искључи тастере миша"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Укључи или искључи лепљиве тастере"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Укључи или искључи споре тастере"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Укључи или искључи Приступ гласом"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Укључи или искључи Talkback"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Укључи или искључи Увећање"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"Активирај Изаберите за говор"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не узнемиравај"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Пречица за дугмад за јачину звука"</string>
     <string name="battery" msgid="769686279459897127">"Батерија"</string>
@@ -1304,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Отворите помоћу отиска прста"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Потребна је потврда идентитета. Додирните сензор за отисак прста да бисте потврдили идентитет."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Позив је у току"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобилни подаци"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Повезано"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Привремено повезано"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index cfa9c0a..c0b8460 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Okänd batterinivå."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Ansluten till <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Ansluten till <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Inte ansluten."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Av"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Du måste verifiera din identitet innan du öppnar en app med en widget. Tänk också på att alla kan se dem, även när surfplattan är låst. Vissa widgetar kanske inte är avsedda för låsskärmen och det kan vara osäkert att lägga till dem här."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Visa skärmsläckarknappen"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Utforska hubbläget"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Få åtkomst till dina favoritwidgetar och skärmsläckare under laddning."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Då kör vi"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Visas högst upp i konversationsaviseringarna och som profilbild på låsskärmen, visas som bubbla, åsidosätter Stör ej"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> har inte stöd för konversationsfunktioner"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Stäng"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Visa inte igen"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Det går inte att ändra de här aviseringarna."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Det går inte att ändra samtalsaviseringarna."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Den här aviseringsgruppen kan inte konfigureras här"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalender"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kalkylator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Kartor"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Aktivera/inaktivera studsande tangenter"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Aktivera/inaktivera mustangenter"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Aktivera/inaktivera låstangentsläget"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Aktivera/inaktivera långsamma tangenter"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Aktivera/inaktivera röststyrning"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Stör ej"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Genväg till volymknappar"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Öppna med fingeravtryck"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autentisering krävs. Identifiera dig genom att trycka på fingeravtryckssensorn."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Pågående samtal"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobildata"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Ansluten"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Tillfälligt ansluten"</string>
@@ -1459,7 +1463,7 @@
     <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Vill du återställa till standardinställningarna?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"Skapa det här kortkommandot genom att trycka på åtgärdstangenten och en eller flera andra tangenter samtidigt"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Det anpassade kortkommandot raderas permanent."</string>
-    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Alla anpassade genvägar raderas permanent."</string>
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Alla anpassade kortkommandon raderas permanent."</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sökgenvägar"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Inga sökresultat"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikonen Komprimera"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Du är klar med rörelsen för att se de senaste apparna."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Svep uppåt på styrplattan med tre fingrar och håll kvar för att se nyligen använda appar"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Byta app"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Svep åt höger med fyra fingrar på styrplattan"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Bra jobbat!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Du har slutfört rörelsen för att byta app"</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Svep åt höger med fyra fingrar på styrplattan för att byta app"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Visa alla appar"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tryck på åtgärdstangenten på tangentbordet"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bra gjort!"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 9ec763b..bcad102 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Asilimia ya betri haijulikani."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Imeunganishwa kwenye <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Imeunganishwa kwenye <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Haijaunganishwa."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Mitandao ya ng\'ambo"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Zima"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Utahitaji kuthibitisha kuwa ni wewe ili ufungue programu ukitumia wijeti. Pia, kumbuka kuwa mtu yeyote anaweza kuziona, hata kishikwambi chako kikiwa kimefungwa. Huenda baadhi ya wijeti hazikukusudiwa kutumika kwenye skrini yako iliyofungwa na huenda si salama kuziweka hapa."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Nimeelewa"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Kitufe cha “Onyesha taswira ya skrini”"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Gundua hali ya kutumia ikiwa imepachikwa"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Fikia wijeti unazopenda na taswira za skrini wakati unachaji."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Anza"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Huonyeshwa kwenye sehemu ya juu ya arifa za mazungumzo na kama picha ya wasifu kwenye skrini iliyofungwa. Huonekana kama kiputo na hukatiza kipengele cha Usinisumbue"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Kipaumbele"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> haitumii vipengele vya mazungumzo"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Ondoa"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Usionyeshe tena"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Arifa hizi haziwezi kubadilishwa."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Arifa za simu haziwezi kubadilishwa."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Kikundi hiki cha arifa hakiwezi kuwekewa mipangilio hapa"</string>
@@ -918,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Kalenda"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kikokotoo"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Ramani"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Kugeuza mibofyo inayopuuzwa"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Kugeuza vitufe vya kipanya"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Kugeuza vitufe vinavyonata"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Kugeuza vitufe vya polepole"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Kugeuza Kufikia kwa Kutamka"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Washa/Zima Talkback"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Washa/Zima Kipengele cha Ukuzaji"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"Washa kipengele cha Chagua ili Izungumze"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Usinisumbue"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Njia ya mkato ya vitufe vya sauti"</string>
     <string name="battery" msgid="769686279459897127">"Betri"</string>
@@ -1307,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Tumia alama ya kidole kufungua"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Uthibitishaji unahitajika. Gusa kitambua alama ya kidole ili uthibitishe."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Simu inayoendelea"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Data ya mtandao wa simu"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Imeunganishwa"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Imeunganishwa kwa muda"</string>
@@ -1454,7 +1455,7 @@
     <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Programu Inayotumika Sasa"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ufikivu"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Mikato ya kibodi"</string>
-    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Kuweka mapendeleo ya njia za mkato"</string>
+    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Mapendeleo ya njia za mkato"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Ungependa kuondoa njia ya mkato?"</string>
     <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Ungependa kurejesha njia za mkato chaguomsingi?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"Ili kuanzisha njia hii ya mkato, bonyeza kitufe cha Vitendo na ufunguo mmoja au zaidi kwa pamoja"</string>
@@ -1512,12 +1513,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Umekamilisha mafunzo ya mguso wa kuangalia programu za hivi majuzi."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Telezesha vidole vitatu juu na ushikilie kwenye padi yako ya kugusa ili uangalie programu za hivi majuzi"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Badilisha programu"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Telezesha vidole vinne kulia kwenye padi yako ya kugusa"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Kazi nzuri!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Umekamilisha mafunzo kuhusu mguso wa kubadili programu."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Telezesha vidole vinne kulia kwenye padi yako ya kugusa ili ubadilishe programu"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Angalia programu zote"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Bonyeza kitufe cha vitendo kwenye kibodi yako"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Vizuri sana!"</string>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index ab0f788..b438315 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -19,7 +19,7 @@
 
 <!-- These resources are around just to allow their values to be customized
      for different hardware and product builds. -->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
+<resources>
     <!-- The maximum number of rows in the QuickSettings -->
     <integer name="quick_settings_max_rows">4</integer>
 
@@ -51,9 +51,7 @@
     ignored. -->
     <string-array name="config_keyguardQuickAffordanceDefaults" translatable="false">
         <item>bottom_start:home</item>
-        <!-- TODO(b/384119565): revisit decision on defaults -->
-        <item android:featureFlag="!com.android.systemui.glanceable_hub_v2_resources">bottom_end:create_note</item>
-        <item android:featureFlag="com.android.systemui.glanceable_hub_v2_resources">bottom_end:glanceable_hub</item>
+        <item>bottom_end:create_note</item>
     </string-array>
 
     <!-- Whether volume panel should use the large screen layout or not -->
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 26f32ef..d22c8d91 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -126,4 +126,6 @@
     <dimen name="controls_content_padding">24dp</dimen>
     <dimen name="control_list_vertical_spacing">8dp</dimen>
     <dimen name="control_list_horizontal_spacing">16dp</dimen>
+
+    <dimen name="communal_to_dream_button_size">64dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index bca92d3..f5f110a 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"பேட்டரி சதவீதம் தெரியவில்லை."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>க்கு இணைக்கப்பட்டது."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> உடன் இணைக்கப்பட்டுள்ளது."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"இணைக்கப்படவில்லை."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"ரோமிங்"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"ஆஃப்"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"விட்ஜெட்டைப் பயன்படுத்தி ஆப்ஸைத் திறக்க, அது நீங்கள்தான் என்பதை உறுதிசெய்ய வேண்டும். அத்துடன், உங்கள் டேப்லெட் பூட்டப்பட்டிருந்தாலும்கூட அவற்றை யார் வேண்டுமானாலும் பார்க்கலாம் என்பதை நினைவில்கொள்ளுங்கள். சில விட்ஜெட்கள் உங்கள் பூட்டுத் திரைக்காக உருவாக்கப்பட்டவை அல்ல என்பதையும் அவற்றை இங்கே சேர்ப்பது பாதுகாப்பற்றதாக இருக்கக்கூடும் என்பதையும் நினைவில்கொள்ளுங்கள்."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"சரி"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"ஸ்கிரீன் சேவரைக் காட்டும் பட்டன்"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"ஹப் பயன்முறையைக் கண்டறியுங்கள்"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"சார்ஜிங்கின்போது உங்களுக்குப் பிடித்த விட்ஜெட்களையும் ஸ்கிரீன் சேவர்களையும் அணுகலாம்."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"தொடங்குக"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"பயனரை மாற்று"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"கீழ் இழுக்கும் மெனு"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"உரையாடல் அறிவிப்புகளின் மேற்பகுதியில் காட்டப்படும், திரை பூட்டப்பட்டிருக்கும்போது சுயவிவரப் படமாகக் காட்டப்படும், குமிழாகத் தோன்றும், தொந்தரவு செய்ய வேண்டாம் அம்சம் இயக்கப்பட்டிருக்கும்போதும் காட்டப்படும்"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"முன்னுரிமை"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"உரையாடல் அம்சங்களை <xliff:g id="APP_NAME">%1$s</xliff:g> ஆதரிக்காது"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"மூடுக"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"மீண்டும் காட்டாதே"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"இந்த அறிவிப்புகளை மாற்ற இயலாது."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"அழைப்பு அறிவிப்புகளை மாற்ற முடியாது."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"இந்த அறிவுப்புக் குழுக்களை இங்கே உள்ளமைக்க இயலாது"</string>
@@ -918,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"கால்குலேட்டர்"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"பவுன்ஸ் பட்டன்களை நிலைமாற்றுதல்"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"மவுஸ் பட்டன்களை நிலைமாற்றுதல்"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"ஸ்டிக்கி பட்டன்களை நிலைமாற்றுதல்"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"ஸ்லோ பட்டன்களை நிலைமாற்றுதல்"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"குரல் அணுகலை நிலைமாற்றுதல்"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Talkback அம்சத்தை நிலைமாற்றுதல்"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"பெரிதாக்கலை நிலைமாற்றுதல்"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"பேசும் திரையை இயக்குதல்"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"தொந்தரவு செய்ய வேண்டாம்"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ஒலியளவுப் பொத்தான்களுக்கான ஷார்ட்கட்"</string>
     <string name="battery" msgid="769686279459897127">"பேட்டரி"</string>
@@ -1307,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"கைரேகையைப் பயன்படுத்தி திறந்திடுங்கள்"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"அங்கீகாரம் தேவை. கைரேகை சென்சாரைத் தொட்டு அங்கீகரியுங்கள்."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"செயலில் உள்ள அழைப்பு"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"மொபைல் டேட்டா"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"இணைக்கப்பட்டது"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"தற்காலிகமாக இணைக்கப்பட்டுள்ளது"</string>
@@ -1512,12 +1513,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"சமீபத்தில் பயன்படுத்திய ஆப்ஸுக்கான சைகை பயிற்சியை நிறைவுசெய்துவிட்டீர்கள்."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"சமீபத்திய ஆப்ஸைப் பார்க்க, உங்கள் டச்பேடில் மூன்று விரல்களால் மேல்நோக்கி ஸ்வைப் செய்து பிடிக்கவும்"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"ஆப்ஸுக்கிடையில் மாறுங்கள்"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"டச்பேடில் நான்கு விரல்களால் வலதுபுறம் ஸ்வைப் செய்யவும்"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"அருமை!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"ஆப்ஸுக்கிடையில் மாறும் சைகைப் பயிற்சியை முடித்துவிட்டீர்கள்."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"ஆப்ஸுக்கிடையே மாற டச்பேடில் நான்கு விரல்களால் வலதுபுறம் ஸ்வைப் செய்யவும்"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"அனைத்து ஆப்ஸையும் காட்டு"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"உங்கள் கீபோர்டில் ஆக்‌ஷன் பட்டனை அழுத்தவும்"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"அருமை!"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index c439e00..0f365c9 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"బ్యాటరీ శాతం తెలియదు."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>కి కనెక్ట్ చేయబడింది."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>కి కనెక్ట్ చేయబడింది."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"కనెక్ట్ చేయబడలేదు."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"రోమింగ్"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"ఆఫ్ చేయండి"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"హబ్ మోడ్‌ను అన్వేషించండి"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"ఛార్జింగ్ అయ్యే సమయంలో మీకు ఇష్టమైన విడ్జెట్‌లను, స్క్రీన్ సేవర్‌లను యాక్సెస్ చేయండి."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"ప్రారంభించండి"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"సంభాషణ నోటిఫికేషన్‌ల ఎగువున, లాక్ స్క్రీన్‌లో ప్రొఫైల్ ఫోటో‌గా చూపిస్తుంది, బబుల్‌గా కనిపిస్తుంది, \'అంతరాయం కలిగించవద్దు\'ను అంతరాయం కలిగిస్తుంది"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ప్రాధాన్యత"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> సంభాషణ ఫీచర్‌లను సపోర్ట్ చేయదు"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"విస్మరించండి"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"మళ్లీ చూపవద్దు"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ఈ నోటిఫికేషన్‌లను ఎడిట్ చేయడం వీలుపడదు."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"కాల్ నోటిఫికేషన్‌లను ఎడిట్ చేయడం సాధ్యం కాదు."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"ఈ నోటిఫికేషన్‌ల గ్రూప్‌ను ఇక్కడ కాన్ఫిగర్ చేయలేము"</string>
@@ -915,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"క్యాలిక్యులేటర్"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"బౌన్స్ కీలను టోగుల్ చేయండి"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"మౌస్ కీలను టోగుల్ చేయండి"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"స్టిక్కీ కీలను టోగుల్ చేయండి"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"నిదానంగా పనిచేసే కీలను టోగుల్ చేయండి"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Voice Accessను టోగుల్ చేయండి"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"అంతరాయం కలిగించవద్దు"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"వాల్యూమ్ బటన్‌ల షార్ట్‌కట్"</string>
@@ -1304,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"తెరవడానికి వేలిముద్రను ఉపయోగించండి"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ప్రామాణీకరణ అవసరం. ప్రామాణీకరించడానికి వేలిముద్ర సెన్సార్‌ను తాకండి."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"కాల్ కొనసాగుతోంది"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"మొబైల్ డేటా"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"కనెక్ట్ చేయబడింది"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"తాత్కాలికంగా కనెక్ట్ చేయబడింది"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 7eef449..81b7e19 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ไม่ทราบเปอร์เซ็นต์แบตเตอรี่"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"เชื่อมต่อกับ <xliff:g id="BLUETOOTH">%s</xliff:g> แล้ว"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"เชื่อมต่อกับ <xliff:g id="CAST">%s</xliff:g>"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"ไม่ได้เชื่อมต่อ"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"โรมมิ่ง"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"ปิด"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"สำรวจโหมดฮับ"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"เข้าถึงวิดเจ็ตและภาพพักหน้าจอโปรดขณะชาร์จ"</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"มาเริ่มกันเลย"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -913,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"ปฏิทิน"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"เครื่องคิดเลข"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"แผนที่"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"เปิด/ปิดคีย์ตีกลับ"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"เปิด/ปิดแป้นเมาส์"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"เปิด/ปิดคีย์ติดหนึบ"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"เปิด/ปิดการเพิ่มระยะเวลาในการกดปุ่ม"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"เปิด/ปิดการเข้าถึงด้วยเสียง"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"เปิด/ปิด TalkBack"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"เปิด/ปิดการขยาย"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"เปิดใช้งานการเลือกเพื่อให้อ่าน"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ห้ามรบกวน"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"ทางลัดปุ่มปรับระดับเสียง"</string>
     <string name="battery" msgid="769686279459897127">"แบตเตอรี่"</string>
@@ -1302,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ใช้ลายนิ้วมือเพื่อเปิด"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ต้องมีการตรวจสอบสิทธิ์ แตะเซ็นเซอร์ลายนิ้วมือเพื่อตรวจสอบสิทธิ์"</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"สายที่สนทนาอยู่"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"อินเทอร์เน็ตมือถือ"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"เชื่อมต่อแล้ว"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"เชื่อมต่อแล้วชั่วคราว"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 154ba65..4b744f5 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Hindi alam ang porsyento ng baterya."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Nakakonekta sa <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Nakakonekta sa <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Hindi nakakonekta."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Roaming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Naka-off"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"I-explore ang hub mode"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"I-access ang mga paborito mong widget at screen saver habang nagcha-charge."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Tara na"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Makikita sa itaas ng mga notification ng pag-uusap at bilang larawan sa profile sa lock screen, lumalabas bilang bubble, naaabala ang Huwag Istorbohin"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Priyoridad"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"Hindi sinusuportahan ng <xliff:g id="APP_NAME">%1$s</xliff:g> ang mga feature ng pag-uusap"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"I-dismiss"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Huwag nang ipakita ulit"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Hindi puwedeng baguhin ang mga notification na ito."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Hindi mabago ang mga notification ng tawag."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Hindi mako-configure dito ang pangkat na ito ng mga notification"</string>
@@ -881,8 +885,8 @@
     <string name="group_system_go_back" msgid="2730322046244918816">"Bumalik"</string>
     <string name="group_system_access_home_screen" msgid="4130366993484706483">"Pumunta sa home screen"</string>
     <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Tingnan ang mga kamakailang app"</string>
-    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Mag-cycle pasulong sa mga kamakailang app"</string>
-    <string name="group_system_cycle_back" msgid="8194102916946802902">"Mag-cycle pabalik sa mga kamakailang app"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Mag-cycle forward sa mga kamakailang app"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Mag-cycle backward sa mga kamakailang app"</string>
     <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Buksan ang listahan ng mga app"</string>
     <string name="group_system_access_system_settings" msgid="8731721963449070017">"Buksan ang mga setting"</string>
     <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Buksan ang assistant"</string>
@@ -915,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Calendar"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Calculator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Mga mapa"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"I-toggle ang mga bounce key"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"I-toggle ang mga mouse key"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"I-toggle ang mga sticky key"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"I-toggle ang mga slow key"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"I-toggle ang Pag-access gamit ang Boses"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"I-toggle ang Talkback"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"I-toggle ang Magnification"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"I-activate ang Select to Speak"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Huwag Istorbohin"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Shortcut ng mga button ng volume"</string>
     <string name="battery" msgid="769686279459897127">"Baterya"</string>
@@ -1304,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Gamitin ang fingerprint para buksan"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Kailangan ng pag-authenticate. Pindutin ang sensor para sa fingerprint para mag-authenticate."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Kasalukuyang tawag"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobile data"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Nakakonekta"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Pansamantalang nakakonekta"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index d532bef..fbdc7b6 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Pil yüzdesi bilinmiyor."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> ile bağlı."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> bağlantısı kuruldu."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Bağlanmadı."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Dolaşım"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Kapalı"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Widget kullanarak bir uygulamayı açmak için kimliğinizi doğrulamanız gerekir. Ayrıca, tabletiniz kilitliyken bile widget\'ların herkes tarafından görüntülenebileceğini unutmayın. Bazı widget\'lar kilit ekranınız için tasarlanmamış olabileceğinden buraya eklenmeleri güvenli olmayabilir."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Anladım"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Ekran koruyucuyu göster düğmesi"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Hub Modu\'nu keşfedin"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Cihazınız şarj olurken en sevdiğiniz widget\'lara ve ekran koruyuculara erişin."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Başlayalım"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Görüşme bildirimlerinin üstünde ve kilit ekranında profil resmi olarak gösterilir, baloncuk olarak görünür, Rahatsız Etmeyin\'i kesintiye uğratır"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Öncelikli"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>, sohbet özelliklerini desteklemiyor"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Kapat"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Tekrar gösterme"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Bu bildirimler değiştirilemez."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Arama bildirimleri değiştirilemez."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Bu bildirim grubu burada yapılandırılamaz"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Takvim"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Hesap Makinesi"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Haritalar"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Tekrarlı basmayı yoksayma tuşlarını aç/kapat"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Fare tuşlarını aç/kapat"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Yapışkan tuşları aç/kapat"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Yavaş tuşları aç/kapat"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Sesli Erişim\'i aç/kapat"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Rahatsız Etmeyin"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Ses düğmeleri kısayolu"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Açmak için parmak izi kullanın"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Kimlik doğrulaması gerekiyor. Kimlik doğrulaması için parmak izi sensörüne dokunun."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Devam eden arama"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobil veri"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Bağlı"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Geçici olarak bağlandı"</string>
@@ -1448,8 +1452,7 @@
     <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistem uygulamaları"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Çoklu görev"</string>
     <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Bölünmüş ekran"</string>
-    <!-- no translation found for shortcutHelper_category_accessibility (8068337792277570938) -->
-    <skip />
+    <string name="shortcutHelper_category_accessibility" msgid="8068337792277570938">"Erişilebilirlik"</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_current_app_shortcuts" msgid="4017840565974573628">"Mevcut Uygulama"</string>
@@ -1513,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Son uygulamaları görüntüleme hareketini tamamladınız."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Son kullanılan uygulamaları görüntülemek için dokunmatik alanda üç parmağınızla yukarı kaydırıp basılı tutun"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Uygulamalar arasında geçiş yapma"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Dokunmatik alanda dört parmağınızla sağa kaydırın"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Tebrikler!"</string>
-    <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Uygulamalar arasında geçiş yapma hareketini tamamladınız."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Uygulamalar arası geçiş hareketini tamamladınız."</string>
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Uygulamalar arasında geçiş yapmak için dokunmatik alanda dört parmağınızla sağa kaydırın"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Tüm uygulamaları göster"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Klavyenizde eylem tuşuna basın"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Tebrikler!"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index c3a01f5..4a89f20 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Відсоток заряду акумулятора невідомий."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Підключено до <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Під’єднано до пристрою <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Не з’єднано."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Роумінг"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Вимкнено"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Щоб відкрити додаток за допомогою віджета, вам потрібно буде підтвердити особу. Пам’ятайте також, що бачити віджети можуть усі, навіть коли планшет заблоковано. Можливо, деякі віджети не призначені для заблокованого екрана, і додавати їх на нього може бути небезпечно."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Кнопка \"Показати заставку\""</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Представляємо режим центру керування"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Використовуйте улюблені віджети й заставки, поки пристрій заряджається."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Почати"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Змінити користувача"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"спадне меню"</string>
@@ -753,8 +756,7 @@
     <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"Оновлення"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Робочий профіль"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Режим польоту"</string>
-    <!-- no translation found for status_bar_supervision (6735015942701134125) -->
-    <skip />
+    <string name="status_bar_supervision" msgid="6735015942701134125">"Батьківський контроль"</string>
     <string name="zen_alarm_warning" msgid="7844303238486849503">"Наступний сигнал о <xliff:g id="WHEN">%1$s</xliff:g> не пролунає"</string>
     <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g>"</string>
@@ -805,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"З’являється вгорі сповіщень про розмови і як зображення профілю на заблокованому екрані, відображається як спливаючий чат, перериває режим \"Не турбувати\""</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Пріоритет"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не підтримує функції розмов"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Закрити"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Більше не показувати"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ці сповіщення не можна змінити."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Сповіщення про виклик не можна змінити."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Цю групу сповіщень не можна налаштувати тут"</string>
@@ -919,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Календар"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Калькулятор"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Карти"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Увімкнути або вимкнути ігнорування повторного натискання"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Увімкнути або вимкнути клавіші керування мишею"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Увімкнути або вимкнути залипання клавіш"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Увімкнути або вимкнути повільні клавіші"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Увімкнути або вимкнути Голосовий доступ"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Не турбувати"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Кнопки гучності на корпусі"</string>
@@ -1308,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Щоб відкрити, використайте відбиток пальця"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Пройдіть автентифікацію. Для цього торкніться сканера відбитків пальців."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Поточний дзвінок"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобільний трафік"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Підключено"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Тимчасово з’єднано"</string>
@@ -1449,14 +1452,13 @@
     <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системні додатки"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Багатозадачність"</string>
     <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Розділити екран"</string>
-    <!-- no translation found for shortcutHelper_category_accessibility (8068337792277570938) -->
-    <skip />
+    <string name="shortcutHelper_category_accessibility" msgid="8068337792277570938">"Функції доступності"</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_current_app_shortcuts" msgid="4017840565974573628">"Поточний додаток"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Доступність"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Комбінації клавіш"</string>
-    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Налаштуйте комбінації клавіш"</string>
+    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Комбінації клавіш"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Видалити комбінацію клавіш?"</string>
     <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Відновити комбінації клавіш за умовчанням?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"Щоб створити цю комбінацію, одночасно натисніть клавішу дії і одну чи кілька інших клавіш"</string>
@@ -1514,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Ви виконали жест для перегляду нещодавно відкритих додатків."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Щоб переглянути останні додатки, проведіть трьома пальцями вгору й утримуйте їх на сенсорній панелі"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Перемикання між додатками"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Проведіть чотирма пальцями вправо по сенсорній панелі"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Чудово!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Ви виконали жест перемикання додатків."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Щоб перемикати додатки, проводьте чотирма пальцями вправо по сенсорній панелі"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Переглянути всі додатки"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Натисніть клавішу дії на клавіатурі"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Чудово!"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index bbde335..5c97d27 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"بیٹری کی فیصد نامعلوم ہے۔"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> سے منسلک ہیں۔"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> سے منسلک ہے۔"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"مربوط نہیں ہے۔"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"رومنگ"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"آف ہے"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"ہب موڈ دریافت کریں"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"چارج کرتے وقت اپنے پسندیدہ ویجیٹس اور اسکرین سیورز تک رسائی حاصل کریں۔"</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"آئیے شروع کریں"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"یہ گفتگو کی اطلاعات کے اوپری حصّے پر اور مقفل اسکرین پر پروفائل کی تصویر کے بطور دکھائی دیتا ہے، بلبلے کے بطور ظاہر ہوتا ہے، \'ڈسٹرب نہ کریں\' میں مداخلت کرتا ہے"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ترجیح"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ گفتگو کی خصوصیات کو سپورٹ نہیں کرتی ہے"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"برخاست کریں"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"دوبارہ نہ دکھائیں"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"ان اطلاعات کی ترمیم نہیں کی جا سکتی۔"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"کال کی اطلاعات میں ترمیم نہیں کی جا سکتی۔"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"اطلاعات کے اس گروپ کو یہاں کنفیگر نہیں کیا جا سکتا"</string>
@@ -915,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"کیلنڈر"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"کیلکولیٹر"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"باؤنس کلیدیں ٹوگل کریں"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"ماؤس کنٹرول کرنے کی کلیدیں ٹوگل کریں"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"دبی رہنے والی کلیدیں ٹوگل کریں"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"سست کلیدیں ٹوگل کریں"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"صوتی رسائی کو ٹوگل کریں"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"ڈسٹرب نہ کریں"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"والیوم بٹنز کے شارٹ کٹ"</string>
@@ -1304,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"کھولنے کے لیے فنگر پرنٹ کا استعمال کریں"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"توثیق مطلوب ہے۔ توثیق کرنے کے لیے فنگر پرنٹ سینسر کو ٹچ کریں۔"</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"جاری کال"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"موبائل ڈیٹا"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"منسلک ہے"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"عارضی طور پر منسلک ہے"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index ea4a7c7..9a75943 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batareya quvvati foizi nomaʼlum."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Ulangan: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Bunga ulangan: <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Ulanmagan."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Rouming"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Oʻchiq"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Hub rejimi bilan tanishing"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Quvvatlash paytida sevimli vidjetlar va ekran lavhalaridan foydalaning."</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Boshlash"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -877,7 +883,7 @@
     <string name="group_system_full_screenshot" msgid="5742204844232667785">"Skrinshot olish"</string>
     <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Yorliqlarni ochish"</string>
     <string name="group_system_go_back" msgid="2730322046244918816">"Orqaga"</string>
-    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Bosh ekranni ochish"</string>
+    <string name="group_system_access_home_screen" msgid="4130366993484706483">"Bosh ekranga chiqish"</string>
     <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Oxirgi ilovalarni koʻrish"</string>
     <string name="group_system_cycle_forward" msgid="5478663965957647805">"Oxirgi ilovalarni oldinga varaqlash"</string>
     <string name="group_system_cycle_back" msgid="8194102916946802902">"Oxirgi ilovalarni orqaga varaqlash"</string>
@@ -913,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Taqvim"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Kalkulyator"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Xaritalar"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Takror bosish nazoratini yoqish yoki oʻchirish"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Kursorni klaviaturadan boshqarishni yoqish yoki oʻchirish"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Yopishqoq tugmalarni yoqish yoki oʻchirish"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Tugmalar uzoq bosilishini yoqish yoki oʻchirish"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Ovozli boshqaruvni yoqish yoki oʻchirish"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"Talkbackni yoqish"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"Lupani yoqish"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"Teginib tinglash funksiyasini yoqish"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Bezovta qilinmasin"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Ovoz balandligini boshqarish tugmalari"</string>
     <string name="battery" msgid="769686279459897127">"Batareya"</string>
@@ -1302,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Ochish uchun barmoq izidan foydalaning"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Haqiqiylikni tekshirish talab etiladi. Autentifikatsiya uchun barmoq izi skaneriga tegining."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Joriy chaqiruv"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobil internet"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Ulangan"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Vaqtincha ulangan"</string>
@@ -1445,17 +1451,17 @@
     <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ekranni ikkiga ajratish"</string>
     <string name="shortcutHelper_category_accessibility" msgid="8068337792277570938">"Qulaylik"</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_app_shortcuts" msgid="8010249408308587117">"Ilovalar"</string>
     <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Joriy ilova"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qulayliklar"</string>
     <string name="shortcut_helper_title" msgid="8567500639300970049">"Tezkor tugmalar"</string>
-    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Yorliqlarni moslash"</string>
+    <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Tezkor tugmalarni sozlash"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Tezkor tugma olib tashlansinmi?"</string>
     <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Asliga qaytarilsinmi?"</string>
     <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"Bu tezkor tugmani yaratish uchun Amal tugmasi va bir yoki bir nechta tugmalarni birgalikda bosing"</string>
     <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Bunda maxsus tezkor tugma butunlay oʻchirib tashlanadi."</string>
     <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Bunda barcha maxsus yorliqlaringiz butunlay oʻchirib tashlanadi."</string>
-    <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tezkor tugmalar qidiruvi"</string>
+    <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Qidiruv"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Hech narsa topilmadi"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Yigʻish belgisi"</string>
     <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Amal bajarish uchun Meta tugmasi belgisi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 5380afa..d023242 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Tỷ lệ phần trăm pin không xác định."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Đã kết nối với <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Đã kết nối với <xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Chưa được kết nối."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Chuyển vùng"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Tắt"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Để dùng tiện ích mở một ứng dụng, bạn cần xác minh danh tính của mình. Ngoài ra, hãy lưu ý rằng bất kỳ ai cũng có thể xem các tiện ích này, ngay cả khi máy tính bảng của bạn được khoá. Một số tiện ích có thể không dành cho màn hình khoá và không an toàn khi thêm vào đây."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Tôi hiểu"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Hiện nút trình bảo vệ màn hình"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Khám phá chế độ thiết bị trung tâm"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Truy cập vào các tiện ích và trình bảo vệ màn hình mà bạn yêu thích trong khi sạc."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Bắt đầu"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Hiện ở đầu phần thông báo cuộc trò chuyện và ở dạng ảnh hồ sơ trên màn hình khóa, xuất hiện ở dạng bong bóng, làm gián đoạn chế độ Không làm phiền"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Mức độ ưu tiên"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> không hỗ trợ các tính năng trò chuyện"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Đóng"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Không hiện lại"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Không thể sửa đổi các thông báo này."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Không thể sửa đổi các thông báo cuộc gọi."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Không thể định cấu hình nhóm thông báo này tại đây"</string>
@@ -918,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Lịch"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Máy tính"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"Bản đồ"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Bật/tắt phím nảy"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Bật/tắt phím điều khiển chuột"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Bật/tắt phím cố định"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Bật/tắt phím chậm"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Bật/tắt tính năng Điều khiển bằng giọng nói"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Không làm phiền"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Phím tắt các nút âm lượng"</string>
@@ -1307,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Dùng vân tay để mở"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Bạn cần phải xác thực. Hãy chạm vào cảm biến vân tay để xác thực."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Cuộc gọi đang diễn ra"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Dữ liệu di động"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Đã kết nối"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Tạm thời có kết nối"</string>
@@ -1512,12 +1516,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Bạn đã hoàn tất cử chỉ xem ứng dụng gần đây."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Để xem các ứng dụng gần đây, hãy dùng 3 ngón tay vuốt lên và giữ trên bàn di chuột"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Chuyển đổi ứng dụng"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Dùng 4 ngón tay vuốt sang phải trên bàn di chuột"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Tuyệt vời!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Bạn đã thực hiện xong cử chỉ chuyển đổi ứng dụng."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Dùng 4 ngón tay vuốt sang phải trên bàn di chuột để chuyển đổi ứng dụng"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Xem tất cả các ứng dụng"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Nhấn phím hành động trên bàn phím"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Rất tốt!"</string>
diff --git a/packages/SystemUI/res/values-xlarge-land/config.xml b/packages/SystemUI/res/values-xlarge-land/config.xml
index 6d8b64a..4c77f30 100644
--- a/packages/SystemUI/res/values-xlarge-land/config.xml
+++ b/packages/SystemUI/res/values-xlarge-land/config.xml
@@ -16,5 +16,5 @@
 
 <resources>
     <item name="shortcut_helper_screen_width_fraction"  format="float" type="dimen">0.8</item>
-    <bool name="center_align_magic_portrait_shape">true</bool>
+    <bool name="center_align_focal_area_shape">true</bool>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 4b29fb6..23178d8d 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"电池电量百分比未知。"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"已连接到<xliff:g id="BLUETOOTH">%s</xliff:g>。"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"已连接到 <xliff:g id="CAST">%s</xliff:g>。"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"未连接。"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"漫游"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"已关闭"</string>
@@ -539,6 +543,8 @@
     <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"探索基座接入模式"</string>
     <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"充电时访问您喜爱的微件和屏保。"</string>
     <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"现在就试试吧"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
+    <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>
@@ -801,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"以气泡形式显示在对话通知顶部(屏幕锁定时显示为个人资料照片),并且会中断勿扰模式"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"优先"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g>不支持对话功能"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"关闭"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"不再显示"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"无法修改这些通知。"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"无法修改来电通知。"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"您无法在此处配置这组通知"</string>
@@ -915,15 +919,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"日历"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"计算器"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"地图"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"开启/关闭防抖键"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"开启/关闭鼠标键"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"开启/关闭粘滞键"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"开启/关闭慢速键"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"开启/关闭语音操控"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"勿扰"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"音量按钮快捷键"</string>
@@ -1304,6 +1309,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"使用指纹即可打开"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"需要进行身份验证。请轻触指纹传感器以验证身份。"</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"正在通话"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"移动数据网络"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"已连接"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"已暂时连接"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 1605840..794a7ba 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"電量百分比不明。"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"已連線至<xliff:g id="BLUETOOTH">%s</xliff:g>。"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"已連接至 <xliff:g id="CAST">%s</xliff:g>。"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"未連線。"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"漫遊"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"關閉"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"如要使用小工具開啟應用程式,系統會要求你驗證身分。請注意,所有人都能查看小工具,即使平板電腦已鎖定亦然。部分小工具可能不適用於上鎖畫面,新增至這裡可能會有安全疑慮。"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"知道了"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"顯示螢幕保護程式按鈕"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"探索插座模式"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"在充電時存取你喜愛的小工具和螢幕保護程式。"</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"立即開始"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉式選單"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"以對話氣泡形式顯示在對話通知頂部 (在上鎖畫面會顯示為個人檔案相片),並會中斷「請勿打擾」模式"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"優先"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」不支援對話功能"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"關閉"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"不要再顯示"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"無法修改這些通知。"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"無法修改通話通知。"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"無法在此設定這組通知"</string>
@@ -918,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"日曆"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"計算機"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"地圖"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"切換彈跳鍵"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"切換滑鼠鍵"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"切換相黏鍵"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"切換緩慢鍵"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"切換語音操控"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"切換 Talkback"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"切換放大模式"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"啟用「揀選朗讀內容」"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"請勿騷擾"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"音量按鈕快速鍵"</string>
     <string name="battery" msgid="769686279459897127">"電池"</string>
@@ -1307,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"使用指紋即可開啟"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"需要驗證。掂一下指紋感應器就可以驗證。"</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"通話中"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"流動數據"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"已連線"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"已暫時連線"</string>
@@ -1457,9 +1458,9 @@
     <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"自訂快速鍵"</string>
     <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"要移除快速鍵嗎?"</string>
     <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"要重設至預設捷徑嗎?"</string>
-    <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"如要建立此快速鍵,請同時按下 Action 鍵及另外一個或多個鍵"</string>
-    <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"這將永久刪除你的自訂快速鍵。"</string>
-    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"這將永久刪除你的所有自訂捷徑。"</string>
+    <string name="shortcut_customize_mode_add_shortcut_description" msgid="7636040209946696120">"如要建立此快速鍵,請同時按下快捷操作鍵及另外一個或多個鍵"</string>
+    <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"此操作會永久刪除此自訂快速鍵。"</string>
+    <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"此操作會永久刪除所有自訂快速鍵。"</string>
     <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜尋快速鍵"</string>
     <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"沒有相符的搜尋結果"</string>
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收合圖示"</string>
@@ -1512,12 +1513,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"你已完成「查看最近使用的應用程式」手勢的教學課程。"</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"如要查看最近使用的應用程式,請用三隻手指在觸控板上向上滑動並按住"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"切換應用程式"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"在觸控板上用四隻手指向右滑動"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"做得好!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"你已完成「應用程式切換手勢」的教學課程。"</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"在觸控板上用四隻手指向右滑動,即可切換應用程式"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"查看所有應用程式"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"按下鍵盤上的快捷操作鍵"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"做得好!"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index cbdb641..689475c 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -250,6 +250,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"電池電量不明。"</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"已連線至<xliff:g id="BLUETOOTH">%s</xliff:g>。"</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"已連線至 <xliff:g id="CAST">%s</xliff:g>。"</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"尚未連線。"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"漫遊"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"關閉"</string>
@@ -536,11 +540,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"如要使用小工具開啟應用程式,需先驗證身分。請留意,即使平板電腦已鎖定,所有人都還是能查看小工具。某些小工具可能不適用於螢幕鎖定畫面,新增到此可能會有安全疑慮。"</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"我知道了"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"顯示螢幕保護程式按鈕"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"瞭解 Hub 模式"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"在充電時使用喜愛的小工具和螢幕保護程式。"</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"開始使用"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉式選單"</string>
@@ -804,10 +807,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"以對話框的形式顯示在對話通知頂端 (螢幕鎖定時會顯示為個人資料相片),並會中斷「零打擾」模式"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"優先"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」不支援對話功能"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"關閉"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"不要再顯示"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"無法修改這些通知。"</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"無法修改來電通知。"</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"無法在這裡設定這個通知群組"</string>
@@ -918,16 +919,14 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"日曆"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"計算機"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"地圖"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
-    <skip />
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"切換彈回鍵"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"切換滑鼠按鍵"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"切換相黏鍵"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"切換延遲感應鍵"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"切換 Voice Access"</string>
+    <string name="group_accessibility_toggle_talkback" msgid="5017967056006325713">"切換 TalkBack"</string>
+    <string name="group_accessibility_toggle_magnification" msgid="3892267763383743128">"切換放大功能"</string>
+    <string name="group_accessibility_activate_select_to_speak" msgid="9157775915495428592">"啟用隨選朗讀"</string>
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"零打擾"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"音量鍵快速鍵"</string>
     <string name="battery" msgid="769686279459897127">"電池"</string>
@@ -1307,6 +1306,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"使用指紋即可開啟"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"需要驗證。輕觸指紋感應器即可進行驗證。"</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"通話中"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"行動數據"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"已連線"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"已暫時建立連線"</string>
@@ -1479,7 +1480,7 @@
     <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"是,請重設"</string>
     <string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"取消"</string>
     <string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"按下按鍵"</string>
-    <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="3325858369539848162">"這組按鍵已在使用中,請試試其他組合。"</string>
+    <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="3325858369539848162">"按鍵組合重複,請試試其他組合。"</string>
     <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"無法設定捷徑。"</string>
     <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string>
     <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"新增快速鍵"</string>
@@ -1512,12 +1513,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"你已完成「查看最近使用的應用程式」手勢教學課程。"</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"如要查看最近使用的應用程式,請在觸控板上用三指向上滑動並按住"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"切換應用程式"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"在觸控板上用四指向右滑動"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"太棒了!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"你已完成應用程式切換手勢的教學課程。"</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"在觸控板上用四指向右滑動,即可切換應用程式"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"查看所有應用程式"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"按下鍵盤上的快捷操作鍵"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"非常好!"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 16d223d..d07a44d 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -252,6 +252,10 @@
     <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Iphesenti lebhethri alaziwa."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Xhuma ku-<xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"Ixhumeke ku-<xliff:g id="CAST">%s</xliff:g>."</string>
+    <!-- no translation found for accessibility_expand_group (521237935987978624) -->
+    <skip />
+    <!-- no translation found for accessibility_open_application (1749126077501259712) -->
+    <skip />
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Akuxhunyiwe"</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"Iyazulazula"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Valiwe"</string>
@@ -538,11 +542,10 @@
     <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ukuze uvule i-app usebenzisa iwijethi, uzodinga ukuqinisekisa ukuthi nguwe. Futhi, khumbula ukuthi noma ubani angakwazi ukuzibuka, nanoma ithebhulethi yakho ikhiyiwe. Amanye amawijethi kungenzeka abengahloselwe ukukhiya isikrini sakho futhi kungenzeka awaphephile ukuthi angafakwa lapha."</string>
     <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ngiyezwa"</string>
     <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"Bonisa inkinobho yesigcini sesikrini"</string>
-    <!-- no translation found for hub_onboarding_bottom_sheet_title (162092881395529947) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_text (8589816797970240544) -->
-    <skip />
-    <!-- no translation found for hub_onboarding_bottom_sheet_action_button (6161983690157872829) -->
+    <string name="hub_onboarding_bottom_sheet_title" msgid="162092881395529947">"Hlola imodi yehabhu"</string>
+    <string name="hub_onboarding_bottom_sheet_text" msgid="8589816797970240544">"Finyelela amawijethi akho ayintandokazi nezigcinisikrini ngenkathi ushaja."</string>
+    <string name="hub_onboarding_bottom_sheet_action_button" msgid="6161983690157872829">"Asihambe"</string>
+    <!-- no translation found for glanceable_hub_to_dream_button_tooltip (9018287673822335829) -->
     <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>
@@ -806,10 +809,8 @@
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Ivela phezu kwezaziso zengxoxo futhi njengesithombe sephrofayela esikrinini sokukhiya, ivela njengebhamuza, ukuphazamisa okuthi Ungaphazamisi"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Okubalulekile"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayisekeli izici zengxoxo"</string>
-    <!-- no translation found for notification_inline_dismiss (88423586921134258) -->
-    <skip />
-    <!-- no translation found for notification_inline_disable_promotion (6880961831026048166) -->
-    <skip />
+    <string name="notification_inline_dismiss" msgid="88423586921134258">"Chitha"</string>
+    <string name="notification_inline_disable_promotion" msgid="6880961831026048166">"Ungabonisi futhi"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Lezi zaziso azikwazi ukushintshwa."</string>
     <string name="notification_unblockable_call_desc" msgid="5907328164696532169">"Izaziso zekholi azikwazi ukushintshwa."</string>
     <string name="notification_multichannel_desc" msgid="7414593090056236179">"Leli qembu lezaziso alikwazi ukulungiselelwa lapha"</string>
@@ -920,15 +921,16 @@
     <string name="keyboard_shortcut_group_applications_calendar" msgid="4229602992120154157">"Ikhalenda"</string>
     <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"Isibali"</string>
     <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"I-Maps"</string>
-    <!-- no translation found for group_accessibility_toggle_bounce_keys (4183584952493519179) -->
+    <string name="group_accessibility_toggle_bounce_keys" msgid="4183584952493519179">"Guqula okhiye abaphindwayo"</string>
+    <string name="group_accessibility_toggle_mouse_keys" msgid="534757719357514361">"Guqula okhiye bemawusi"</string>
+    <string name="group_accessibility_toggle_sticky_keys" msgid="7722214637652104184">"Guqula okhiye abanamathelayo"</string>
+    <string name="group_accessibility_toggle_slow_keys" msgid="8569881436531795062">"Guqula okhiye abanensayo"</string>
+    <string name="group_accessibility_toggle_voice_access" msgid="5436708239015479017">"Guqula Ukufinyelela Kwezwi"</string>
+    <!-- no translation found for group_accessibility_toggle_talkback (5017967056006325713) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_mouse_keys (534757719357514361) -->
+    <!-- no translation found for group_accessibility_toggle_magnification (3892267763383743128) -->
     <skip />
-    <!-- no translation found for group_accessibility_toggle_sticky_keys (7722214637652104184) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_slow_keys (8569881436531795062) -->
-    <skip />
-    <!-- no translation found for group_accessibility_toggle_voice_access (5436708239015479017) -->
+    <!-- no translation found for group_accessibility_activate_select_to_speak (9157775915495428592) -->
     <skip />
     <string name="volume_and_do_not_disturb" msgid="502044092739382832">"Ungaphazamisi"</string>
     <string name="volume_dnd_silent" msgid="4154597281458298093">"Izinqamuleli zezinkinobho zevolomu"</string>
@@ -1309,6 +1311,8 @@
     <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Sebenzisa izigxivizo zeminwe ukuvula"</string>
     <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Ukufakazela ubuqiniso budingekile. Thinta inzwa yezigxivizo zeminwe ukuze uqinisekise."</string>
     <string name="ongoing_call_content_description" msgid="6394763878322348560">"Ikholi eqhubekayo"</string>
+    <!-- no translation found for ongoing_notification_extra_content_description (2098752668861351265) -->
+    <skip />
     <string name="mobile_data_settings_title" msgid="3955246641380064901">"Idatha yeselula"</string>
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Ixhunyiwe"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Ixhume okwesikhashana"</string>
@@ -1514,12 +1518,10 @@
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Uqedele ukubuka ukuthinta kwama-app akamuva."</string>
     <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Ukuze ubuke ama-app akamuva, swayiphela phezulu futhi ubambe usebenzisa iminwe emithathu kuphedi yakho yokuthinta"</string>
     <string name="touchpad_switch_apps_gesture_action_title" msgid="6835222344612924512">"Shintsha ama-app"</string>
-    <!-- no translation found for touchpad_switch_apps_gesture_guidance (2554844933805502538) -->
-    <skip />
+    <string name="touchpad_switch_apps_gesture_guidance" msgid="2554844933805502538">"Swayiphela ngakwesokudla usebenzisa iminwe emine ephedini yokuthinta yakho"</string>
     <string name="touchpad_switch_apps_gesture_success_title" msgid="4894947244328032458">"Umsebenzi omuhle!"</string>
     <string name="touchpad_switch_apps_gesture_success_body" msgid="8151089866035126312">"Ukuqedile ukuthinta kokushintsha ama-app."</string>
-    <!-- no translation found for touchpad_switch_gesture_error_body (5895231916964677918) -->
-    <skip />
+    <string name="touchpad_switch_gesture_error_body" msgid="5895231916964677918">"Swayiphela ngakwesokudla usebenzisa iminwe emine ephedini yokuthinta yakho ukuze ushintshe ama-app"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Buka wonke ama-app"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Cindezela inkinobho yokufinyelela kukhibhodi yakho"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Wenze kahle!"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 68e33f2..9b8926e 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -1107,7 +1107,7 @@
     <!-- The dream component used when the device is low light environment. -->
     <string translatable="false" name="config_lowLightDreamComponent"/>
 
-    <!--Whether we should position magic portrait shape effects in the center of lockscreen
-    it's false by default, and only be true in tablet landscape -->
-    <bool name="center_align_magic_portrait_shape">false</bool>
+    <!-- Configuration for wallpaper focal area -->
+    <bool name="center_align_focal_area_shape">false</bool>
+    <string name="focal_area_target" translatable="false" />
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 42d66e2..d93716b 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -574,6 +574,8 @@
 
     <dimen name="notification_panel_margin_bottom">32dp</dimen>
 
+    <dimen name="notification_2025_panel_margin_bottom">64dp</dimen>
+
     <!-- The bottom padding of the panel that holds the list of notifications. -->
     <dimen name="notification_panel_padding_bottom">0dp</dimen>
 
@@ -951,6 +953,8 @@
     <dimen name="communal_widget_picker_desired_width">360dp</dimen>
     <dimen name="communal_widget_picker_desired_height">240dp</dimen>
 
+    <dimen name="communal_to_dream_button_size">48dp</dimen>
+
     <!-- The width/height of the unlock icon view on keyguard. -->
     <dimen name="keyguard_lock_height">42dp</dimen>
     <dimen name="keyguard_lock_padding">20dp</dimen>
@@ -1521,11 +1525,11 @@
     <dimen name="media_output_dialog_icon_corner_radius">16dp</dimen>
     <dimen name="media_output_dialog_title_anim_y_delta">12.5dp</dimen>
     <dimen name="media_output_dialog_background_radius">16dp</dimen>
-    <dimen name="media_output_dialog_active_background_radius">30dp</dimen>
-    <dimen name="media_output_dialog_default_margin_end">16dp</dimen>
-    <dimen name="media_output_dialog_selectable_margin_end">80dp</dimen>
+    <dimen name="media_output_dialog_active_background_radius">32dp</dimen>
+    <dimen name="media_output_dialog_item_height">64dp</dimen>
+    <dimen name="media_output_dialog_margin_horizontal">16dp</dimen>
     <dimen name="media_output_dialog_list_padding_top">8dp</dimen>
-    <dimen name="media_output_dialog_icon_left_radius">28dp</dimen>
+    <dimen name="media_output_dialog_icon_left_radius">@dimen/media_output_dialog_active_background_radius</dimen>
     <dimen name="media_output_dialog_icon_right_radius">0dp</dimen>
 
     <!-- Distance that the full shade transition takes in order to complete by tapping on a button
@@ -1781,6 +1785,7 @@
     <dimen name="wallet_button_vertical_padding">8dp</dimen>
 
     <!-- Ongoing activity chip -->
+    <dimen name="ongoing_activity_chip_min_text_width">12dp</dimen>
     <dimen name="ongoing_activity_chip_max_text_width">74dp</dimen>
     <dimen name="ongoing_activity_chip_margin_start">5dp</dimen>
     <!-- The activity chip side padding, used with the default phone icon. -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index fc9635b..7b2e812 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -3401,6 +3401,8 @@
 
     <!-- Content description for a chip in the status bar showing that the user is currently on a call. [CHAR LIMIT=NONE] -->
     <string name="ongoing_call_content_description">Ongoing call</string>
+    <!-- Content description for a chip in the status bar showing that the user currently has an ongoing activity. [CHAR LIMIT=NONE]-->
+    <string name="ongoing_notification_extra_content_description">Ongoing</string>
 
     <!-- Provider Model: Default title of the mobile network in the mobile layout. [CHAR LIMIT=50] -->
     <string name="mobile_data_settings_title">Mobile data</string>
diff --git a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/Utils.kt b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/Utils.kt
index 870e6e6..5b99a3f 100644
--- a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/Utils.kt
+++ b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/Utils.kt
@@ -17,13 +17,6 @@
 
 import android.Manifest
 import android.app.ActivityTaskManager
-import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
-import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
-import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX
-import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED
-import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
-import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX
-import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
 import android.content.Context
 import android.content.pm.PackageManager
 import android.graphics.Bitmap
@@ -44,6 +37,9 @@
 import android.view.accessibility.AccessibilityEvent
 import android.view.accessibility.AccessibilityManager
 import com.android.internal.widget.LockPatternUtils
+import com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD
+import com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN
+import com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN
 import com.android.systemui.biometrics.shared.model.PromptKind
 
 object Utils {
@@ -80,7 +76,7 @@
         view.notifySubtreeAccessibilityStateChanged(
             view,
             view,
-            AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE
+            AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE,
         )
     }
 
@@ -94,14 +90,10 @@
 
     @JvmStatic
     fun getCredentialType(utils: LockPatternUtils, userId: Int): PromptKind =
-        when (utils.getKeyguardStoredPasswordQuality(userId)) {
-            PASSWORD_QUALITY_SOMETHING -> PromptKind.Pattern
-            PASSWORD_QUALITY_NUMERIC,
-            PASSWORD_QUALITY_NUMERIC_COMPLEX -> PromptKind.Pin
-            PASSWORD_QUALITY_ALPHABETIC,
-            PASSWORD_QUALITY_ALPHANUMERIC,
-            PASSWORD_QUALITY_COMPLEX,
-            PASSWORD_QUALITY_MANAGED -> PromptKind.Password
+        when (utils.getCredentialTypeForUser(userId)) {
+            CREDENTIAL_TYPE_PATTERN -> PromptKind.Pattern
+            CREDENTIAL_TYPE_PIN -> PromptKind.Pin
+            CREDENTIAL_TYPE_PASSWORD -> PromptKind.Password
             else -> PromptKind.Password
         }
 
@@ -112,7 +104,7 @@
     @JvmStatic
     fun <T : SensorPropertiesInternal> findFirstSensorProperties(
         properties: List<T>?,
-        sensorIds: IntArray
+        sensorIds: IntArray,
     ): T? = properties?.firstOrNull { sensorIds.contains(it.sensorId) }
 
     @JvmStatic
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index c266a5b..0b66a0f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -296,7 +296,7 @@
     private final Provider<JavaAdapter> mJavaAdapter;
     private final Provider<SceneInteractor> mSceneInteractor;
     private final Provider<AlternateBouncerInteractor> mAlternateBouncerInteractor;
-    private final CommunalSceneInteractor mCommunalSceneInteractor;
+    private final Provider<CommunalSceneInteractor> mCommunalSceneInteractor;
     private final AuthController mAuthController;
     private final UiEventLogger mUiEventLogger;
     private final Set<String> mAllowFingerprintOnOccludingActivitiesFromPackage;
@@ -2210,7 +2210,7 @@
             Provider<AlternateBouncerInteractor> alternateBouncerInteractor,
             Provider<JavaAdapter> javaAdapter,
             Provider<SceneInteractor> sceneInteractor,
-            CommunalSceneInteractor communalSceneInteractor) {
+            Provider<CommunalSceneInteractor> communalSceneInteractor) {
         mContext = context;
         mSubscriptionManager = subscriptionManager;
         mUserTracker = userTracker;
@@ -2543,7 +2543,7 @@
 
         if (glanceableHubV2()) {
             mJavaAdapter.get().alwaysCollectFlow(
-                    mCommunalSceneInteractor.isCommunalVisible(),
+                    mCommunalSceneInteractor.get().isCommunalVisible(),
                     this::onCommunalShowingChanged
             );
         }
diff --git a/packages/SystemUI/src/com/android/systemui/BootCompleteCacheImpl.kt b/packages/SystemUI/src/com/android/systemui/BootCompleteCacheImpl.kt
index 3a9a238..cadef52 100644
--- a/packages/SystemUI/src/com/android/systemui/BootCompleteCacheImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/BootCompleteCacheImpl.kt
@@ -41,7 +41,7 @@
     }
 
     init {
-        dumpManager.registerDumpable(TAG, this)
+        dumpManager.registerNormalDumpable(TAG, this)
     }
 
     @GuardedBy("listeners")
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
index 615363d..db2ca1d 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
@@ -203,8 +203,8 @@
             return;
         }
         final float currentScale = mController.getScale();
-        final float currentCenterX = mController.getCenterX();
-        final float currentCenterY = mController.getCenterY();
+        final float currentCenterX = mController.getMagnificationFrameCenterX();
+        final float currentCenterY = mController.getMagnificationFrameCenterY();
 
         if (mState == STATE_DISABLED) {
             // We don't need to offset the center during the animation.
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index 1587ab1..a67ec65 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -497,6 +497,9 @@
         if (configDiff == 0) {
             return;
         }
+        if (Flags.updateWindowMagnifierBottomBoundary()) {
+            updateSystemGestureInsetsTop();
+        }
         if ((configDiff & ActivityInfo.CONFIG_ORIENTATION) != 0) {
             onRotate();
         }
@@ -542,8 +545,11 @@
         }
         mWindowBounds.set(currentWindowBounds);
         final Size windowFrameSize = restoreMagnificationWindowFrameIndexAndSizeIfPossible();
-        final float newCenterX = (getCenterX()) * mWindowBounds.width() / oldWindowBounds.width();
-        final float newCenterY = (getCenterY()) * mWindowBounds.height() / oldWindowBounds.height();
+        final float newCenterX =
+                (getMagnificationFrameCenterX()) * mWindowBounds.width() / oldWindowBounds.width();
+        final float newCenterY =
+                (getMagnificationFrameCenterY()) * mWindowBounds.height()
+                        / oldWindowBounds.height();
 
         setMagnificationFrame(windowFrameSize.getWidth(), windowFrameSize.getHeight(),
                 (int) newCenterX, (int) newCenterY);
@@ -672,8 +678,12 @@
     }
 
     private void onWindowInsetChanged() {
-        if (updateSystemGestureInsetsTop()) {
-            updateSystemUIStateIfNeeded();
+        if (Flags.updateWindowMagnifierBottomBoundary()) {
+            updateSystemGestureInsetsTop();
+        } else {
+            if (updateSystemGestureInsetsTop()) {
+                updateSystemUIStateIfNeeded();
+            }
         }
     }
 
@@ -939,7 +949,9 @@
         final int x = MathUtils.clamp(mMagnificationFrame.left - mMirrorSurfaceMargin, minX, maxX);
 
         final int minY = -mOuterBorderSize;
-        final int maxY = mWindowBounds.bottom - height + mOuterBorderSize;
+        final int maxY = Flags.updateWindowMagnifierBottomBoundary()
+                ? mSystemGestureTop - height + mOuterBorderSize
+                : mWindowBounds.bottom - height + mOuterBorderSize;
         final int y = MathUtils.clamp(mMagnificationFrame.top - mMirrorSurfaceMargin, minY, maxY);
 
         if (computeWindowSize) {
@@ -1098,6 +1110,10 @@
     }
 
     private void updateSysUIState(boolean force) {
+        if (Flags.updateWindowMagnifierBottomBoundary()) {
+            return;
+        }
+
         final boolean overlap = isActivated() && mSystemGestureTop > 0
                 && mMirrorViewBounds.bottom > mSystemGestureTop;
         if (force || overlap != mOverlapWithGestureInsets) {
@@ -1313,7 +1329,7 @@
      *
      * @return the X coordinate. {@link Float#NaN} if the window is invisible.
      */
-    float getCenterX() {
+    float getMagnificationFrameCenterX() {
         return isActivated() ? mMagnificationFrame.exactCenterX() : Float.NaN;
     }
 
@@ -1322,10 +1338,30 @@
      *
      * @return the Y coordinate. {@link Float#NaN} if the window is invisible.
      */
-    float getCenterY() {
+    float getMagnificationFrameCenterY() {
         return isActivated() ? mMagnificationFrame.exactCenterY() : Float.NaN;
     }
 
+    /**
+     * Returns the screen-relative X coordinate of the center of the magnifier window.
+     * This could be different from the position of the magnification frame since the magnification
+     * frame could overlap with the bottom inset, but the magnifier window would not.
+     * @return the Y coordinate. {@link Float#NaN} if the window is invisible.
+     */
+    float getMagnifierWindowX() {
+        return isActivated() ? (float) mMirrorViewBounds.left : Float.NaN;
+    }
+
+    /**
+     * Returns the screen-relative Y coordinate of the center of the magnifier window.
+     * This could be different from the position of the magnification frame since the magnification
+     * frame could overlap with the bottom inset, but the magnifier window would not.
+     * @return the Y coordinate. {@link Float#NaN} if the window is invisible.
+     */
+    float getMagnifierWindowY() {
+        return isActivated() ? (float) mMirrorViewBounds.top : Float.NaN;
+    }
+
 
     @VisibleForTesting
     boolean isDiagonalScrollingEnabled() {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
index 9d9f569..c14d28d 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
@@ -392,15 +392,6 @@
             setSystemGestureExclusion();
             mIsVisible = true;
             mCallback.onSettingsPanelVisibilityChanged(/* shown= */ true);
-
-            if (resetPosition) {
-                // We could not put focus on the settings panel automatically
-                // since it is an inactive window. Therefore, we announce the existence of
-                // magnification settings for accessibility when it is opened.
-                mSettingView.announceForAccessibility(
-                        mContext.getResources().getString(
-                                R.string.accessibility_magnification_settings_panel_description));
-            }
         }
         mContext.registerReceiver(mScreenOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
index 21569c1..64a46c0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
@@ -131,7 +131,7 @@
 
     override fun onViewAttached() {
         dialogManager.registerListener(dialogListener)
-        dumpManager.registerDumpable(dumpTag, this)
+        dumpManager.registerNormalDumpable(dumpTag, this)
         udfpsOverlayInteractor.setHandleTouches(shouldHandle = !shouldPauseAuth())
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractor.kt
index 08b3e99..84d3d7f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractor.kt
@@ -72,10 +72,9 @@
         // Request LockSettingsService to return the Gatekeeper Password in the
         // VerifyCredentialResponse so that we can request a Gatekeeper HAT with the
         // Gatekeeper Password and operationId.
-        var effectiveUserId = request.userInfo.deviceCredentialOwnerId
+        val effectiveUserId = request.userInfo.deviceCredentialOwnerId
         val response =
             if (Flags.privateSpaceBp() && effectiveUserId != request.userInfo.userId) {
-                effectiveUserId = request.userInfo.userId
                 lockPatternUtils.verifyTiedProfileChallenge(
                     credential,
                     request.userInfo.userId,
@@ -101,7 +100,7 @@
                 lockPatternUtils.verifyGatekeeperPasswordHandle(
                     pwHandle,
                     request.operationInfo.gatekeeperChallenge,
-                    effectiveUserId,
+                    request.userInfo.userId,
                 )
             val hat = gkResponse.gatekeeperHAT
             lockPatternUtils.removeGatekeeperPasswordHandle(pwHandle)
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 008fb26..a164ff4 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
@@ -126,7 +126,12 @@
                 is PromptKind.Biometric ->
                     BiometricPromptRequest.Biometric(
                         info = promptInfo,
-                        userInfo = BiometricUserInfo(userId = userId),
+                        userInfo =
+                            BiometricUserInfo(
+                                userId = userId,
+                                deviceCredentialOwnerId =
+                                    credentialInteractor.getCredentialOwnerOrSelfId(userId),
+                            ),
                         operationInfo = BiometricOperationInfo(gatekeeperChallenge = challenge),
                         modalities = kind.activeModalities,
                         opPackageName = opPackageName,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt
index e7a68ac..8d5ea3c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialPasswordViewBinder.kt
@@ -12,6 +12,7 @@
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.biometrics.ui.CredentialPasswordView
 import com.android.systemui.biometrics.ui.CredentialView
 import com.android.systemui.biometrics.ui.IPinPad
@@ -21,7 +22,6 @@
 import kotlinx.coroutines.awaitCancellation
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.firstOrNull
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 /** Sub-binder for the [CredentialPasswordView]. */
 object CredentialPasswordViewBinder {
@@ -42,7 +42,7 @@
         view.repeatWhenAttached {
             // the header info never changes - do it early
             val header = viewModel.header.first()
-            passwordField.setTextOperationUser(UserHandle.of(header.user.userIdForPasswordEntry))
+            passwordField.setTextOperationUser(UserHandle.of(header.user.deviceCredentialOwnerId))
             viewModel.inputFlags.firstOrNull()?.let { flags -> passwordField.inputType = flags }
             if (requestFocusForInput) {
                 passwordField.requestFocus()
@@ -65,7 +65,7 @@
                         if (attestation != null) {
                             imeManager.hideSoftInputFromWindow(
                                 view.windowToken,
-                                0 // flag
+                                0, // flag
                             )
                             host.onCredentialMatched(attestation)
                         } else {
@@ -79,7 +79,7 @@
                     launch {
                             onBackInvokedDispatcher.registerOnBackInvokedCallback(
                                 OnBackInvokedDispatcher.PRIORITY_DEFAULT,
-                                onBackInvokedCallback
+                                onBackInvokedCallback,
                             )
                             awaitCancellation()
                         }
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorImpl.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorImpl.kt
index 0303048..94fca21 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorImpl.kt
@@ -53,7 +53,7 @@
     private val deviceItemActionInteractorImpl: DeviceItemActionInteractorImpl,
 ) : DeviceItemActionInteractor {
 
-    override suspend fun onClick(deviceItem: DeviceItem, dialog: SystemUIDialog) {
+    override suspend fun onClick(deviceItem: DeviceItem, dialog: SystemUIDialog?) {
         withContext(backgroundDispatcher) {
             if (!audioSharingInteractor.audioSharingAvailable()) {
                 return@withContext deviceItemActionInteractorImpl.onClick(deviceItem, dialog)
@@ -70,10 +70,18 @@
                     DeviceItemType.AVAILABLE_AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE -> {
                     if (audioSharingInteractor.qsDialogImprovementAvailable()) {
                         withContext(mainDispatcher) {
-                            delegateFactory
-                                .create(deviceItem.cachedBluetoothDevice)
-                                .createDialog()
-                                .let { dialogTransitionAnimator.showFromDialog(it, dialog) }
+                            val audioSharingDialog =
+                                delegateFactory
+                                    .create(deviceItem.cachedBluetoothDevice)
+                                    .createDialog()
+
+                            if (dialog != null) {
+                                audioSharingDialog.let {
+                                    dialogTransitionAnimator.showFromDialog(it, dialog)
+                                }
+                            } else {
+                                audioSharingDialog.show()
+                            }
                         }
                     } else {
                         launchSettings(deviceItem.cachedBluetoothDevice.device, dialog)
@@ -141,7 +149,7 @@
             )
     }
 
-    private fun launchSettings(device: BluetoothDevice, dialog: SystemUIDialog) {
+    private fun launchSettings(device: BluetoothDevice, dialog: SystemUIDialog?) {
         val intent =
             Intent(Settings.ACTION_BLUETOOTH_SETTINGS).apply {
                 putExtra(
@@ -155,7 +163,8 @@
         activityStarter.postStartActivityDismissingKeyguard(
             intent,
             0,
-            dialogTransitionAnimator.createActivityTransitionController(dialog),
+            if (dialog == null) null
+            else dialogTransitionAnimator.createActivityTransitionController(dialog),
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContent.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContent.kt
new file mode 100644
index 0000000..8bc9299
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContent.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bluetooth.qsdialog
+
+import android.view.LayoutInflater
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.viewinterop.AndroidView
+import com.android.systemui.res.R
+
+@Composable
+fun BluetoothDetailsContent() {
+    AndroidView(
+        modifier = Modifier.fillMaxSize(),
+        factory = { context ->
+            // Inflate with the existing dialog xml layout
+            LayoutInflater.from(context).inflate(R.layout.bluetooth_tile_dialog, null)
+            // TODO: b/378513956 - Implement the bluetooth details view
+        },
+    )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentManager.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentManager.kt
new file mode 100644
index 0000000..0be28f3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentManager.kt
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bluetooth.qsdialog
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.View.AccessibilityDelegate
+import android.view.View.GONE
+import android.view.View.INVISIBLE
+import android.view.View.VISIBLE
+import android.view.ViewGroup
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import android.view.accessibility.AccessibilityNodeInfo
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction
+import android.widget.Button
+import android.widget.ImageView
+import android.widget.ProgressBar
+import android.widget.Switch
+import android.widget.TextView
+import androidx.annotation.StringRes
+import androidx.recyclerview.widget.AsyncListDiffer
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.android.internal.R as InternalR
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.res.R
+import com.android.systemui.util.time.SystemClock
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.withContext
+
+data class DeviceItemClick(val deviceItem: DeviceItem, val clickedView: View, val target: Target) {
+    enum class Target {
+        ENTIRE_ROW,
+        ACTION_ICON,
+    }
+}
+
+/** View content manager for showing active, connected and saved bluetooth devices. */
+class BluetoothDetailsContentManager
+@AssistedInject
+internal constructor(
+    @Assisted private val initialUiProperties: BluetoothTileDialogViewModel.UiProperties,
+    @Assisted private val cachedContentHeight: Int,
+    @Assisted private val bluetoothTileDialogCallback: BluetoothTileDialogCallback,
+    @Assisted private val isInDialog: Boolean,
+    @Assisted private val doneButtonCallback: () -> Unit,
+    @Main private val mainDispatcher: CoroutineDispatcher,
+    private val systemClock: SystemClock,
+    private val uiEventLogger: UiEventLogger,
+    private val logger: BluetoothTileDialogLogger,
+) {
+
+    private val mutableBluetoothStateToggle: MutableStateFlow<Boolean?> = MutableStateFlow(null)
+    internal val bluetoothStateToggle
+        get() = mutableBluetoothStateToggle.asStateFlow()
+
+    private val mutableBluetoothAutoOnToggle: MutableStateFlow<Boolean?> = MutableStateFlow(null)
+    internal val bluetoothAutoOnToggle
+        get() = mutableBluetoothAutoOnToggle.asStateFlow()
+
+    private val mutableDeviceItemClick: MutableStateFlow<DeviceItemClick?> = MutableStateFlow(null)
+    internal val deviceItemClick
+        get() = mutableDeviceItemClick.asStateFlow()
+
+    private val mutableContentHeight: MutableStateFlow<Int?> = MutableStateFlow(null)
+    internal val contentHeight
+        get() = mutableContentHeight.asStateFlow()
+
+    private val deviceItemAdapter: Adapter = Adapter()
+
+    private var lastUiUpdateMs: Long = -1
+
+    private var lastItemRow: Int = -1
+
+    // UI Components
+    private lateinit var contentView: View
+    private lateinit var doneButton: Button
+    private lateinit var bluetoothToggle: Switch
+    private lateinit var subtitleTextView: TextView
+    private lateinit var seeAllButton: View
+    private lateinit var pairNewDeviceButton: View
+    private lateinit var deviceListView: RecyclerView
+    private lateinit var autoOnToggle: Switch
+    private lateinit var autoOnToggleLayout: View
+    private lateinit var autoOnToggleInfoTextView: TextView
+    private lateinit var audioSharingButton: Button
+    private lateinit var progressBarAnimation: ProgressBar
+    private lateinit var progressBarBackground: View
+    private lateinit var scrollViewContent: View
+
+    @AssistedFactory
+    internal interface Factory {
+        fun create(
+            initialUiProperties: BluetoothTileDialogViewModel.UiProperties,
+            cachedContentHeight: Int,
+            dialogCallback: BluetoothTileDialogCallback,
+            isInDialog: Boolean,
+            doneButtonCallback: () -> Unit,
+        ): BluetoothDetailsContentManager
+    }
+
+    fun bind(contentView: View) {
+        this.contentView = contentView
+
+        doneButton = contentView.requireViewById(R.id.done_button)
+        bluetoothToggle = contentView.requireViewById(R.id.bluetooth_toggle)
+        subtitleTextView = contentView.requireViewById(R.id.bluetooth_tile_dialog_subtitle)
+        seeAllButton = contentView.requireViewById(R.id.see_all_button)
+        pairNewDeviceButton = contentView.requireViewById(R.id.pair_new_device_button)
+        deviceListView = contentView.requireViewById(R.id.device_list)
+        autoOnToggle = contentView.requireViewById(R.id.bluetooth_auto_on_toggle)
+        autoOnToggleLayout = contentView.requireViewById(R.id.bluetooth_auto_on_toggle_layout)
+        autoOnToggleInfoTextView =
+            contentView.requireViewById(R.id.bluetooth_auto_on_toggle_info_text)
+        audioSharingButton = contentView.requireViewById(R.id.audio_sharing_button)
+        progressBarAnimation =
+            contentView.requireViewById(R.id.bluetooth_tile_dialog_progress_animation)
+        progressBarBackground =
+            contentView.requireViewById(R.id.bluetooth_tile_dialog_progress_background)
+        scrollViewContent = contentView.requireViewById(R.id.scroll_view)
+
+        setupToggle()
+        setupRecyclerView()
+        setupDoneButton()
+
+        subtitleTextView.text = contentView.context.getString(initialUiProperties.subTitleResId)
+        seeAllButton.setOnClickListener { bluetoothTileDialogCallback.onSeeAllClicked(it) }
+        pairNewDeviceButton.setOnClickListener {
+            bluetoothTileDialogCallback.onPairNewDeviceClicked(it)
+        }
+        audioSharingButton.apply {
+            setOnClickListener { bluetoothTileDialogCallback.onAudioSharingButtonClicked(it) }
+            accessibilityDelegate =
+                object : AccessibilityDelegate() {
+                    override fun onInitializeAccessibilityNodeInfo(
+                        host: View,
+                        info: AccessibilityNodeInfo,
+                    ) {
+                        super.onInitializeAccessibilityNodeInfo(host, info)
+                        info.addAction(
+                            AccessibilityAction(
+                                AccessibilityAction.ACTION_CLICK.id,
+                                contentView.context.getString(
+                                    R.string
+                                        .quick_settings_bluetooth_audio_sharing_button_accessibility
+                                ),
+                            )
+                        )
+                    }
+                }
+        }
+        scrollViewContent.apply {
+            minimumHeight =
+                resources.getDimensionPixelSize(initialUiProperties.scrollViewMinHeightResId)
+            layoutParams.height = maxOf(cachedContentHeight, minimumHeight)
+        }
+    }
+
+    fun start() {
+        lastUiUpdateMs = systemClock.elapsedRealtime()
+    }
+
+    fun releaseView() {
+        mutableContentHeight.value = scrollViewContent.measuredHeight
+    }
+
+    internal suspend fun animateProgressBar(animate: Boolean) {
+        withContext(mainDispatcher) {
+            if (animate) {
+                showProgressBar()
+            } else {
+                delay(PROGRESS_BAR_ANIMATION_DURATION_MS)
+                hideProgressBar()
+            }
+        }
+    }
+
+    internal suspend fun onDeviceItemUpdated(
+        deviceItem: List<DeviceItem>,
+        showSeeAll: Boolean,
+        showPairNewDevice: Boolean,
+    ) {
+        withContext(mainDispatcher) {
+            val start = systemClock.elapsedRealtime()
+            val itemRow = deviceItem.size + showSeeAll.toInt() + showPairNewDevice.toInt()
+            // If not the first load, add a slight delay for smoother dialog height change
+            if (itemRow != lastItemRow && lastItemRow != -1) {
+                delay(MIN_HEIGHT_CHANGE_INTERVAL_MS - (start - lastUiUpdateMs))
+            }
+            if (isActive) {
+                deviceItemAdapter.refreshDeviceItemList(deviceItem) {
+                    seeAllButton.visibility = if (showSeeAll) VISIBLE else GONE
+                    pairNewDeviceButton.visibility = if (showPairNewDevice) VISIBLE else GONE
+                    // Update the height after data is updated
+                    scrollViewContent.layoutParams.height = WRAP_CONTENT
+                    lastUiUpdateMs = systemClock.elapsedRealtime()
+                    lastItemRow = itemRow
+                    logger.logDeviceUiUpdate(lastUiUpdateMs - start)
+                }
+            }
+        }
+    }
+
+    internal fun onBluetoothStateUpdated(
+        isEnabled: Boolean,
+        uiProperties: BluetoothTileDialogViewModel.UiProperties,
+    ) {
+        bluetoothToggle.apply {
+            isChecked = isEnabled
+            setEnabled(true)
+            alpha = ENABLED_ALPHA
+        }
+        subtitleTextView.text = contentView.context.getString(uiProperties.subTitleResId)
+        autoOnToggleLayout.visibility = uiProperties.autoOnToggleVisibility
+    }
+
+    internal fun onBluetoothAutoOnUpdated(isEnabled: Boolean, @StringRes infoResId: Int) {
+        autoOnToggle.isChecked = isEnabled
+        autoOnToggleInfoTextView.text = contentView.context.getString(infoResId)
+    }
+
+    internal fun onAudioSharingButtonUpdated(visibility: Int, label: String?, isActive: Boolean) {
+        audioSharingButton.apply {
+            this.visibility = visibility
+            label?.let { text = it }
+            this.isActivated = isActive
+        }
+    }
+
+    private fun setupToggle() {
+        bluetoothToggle.setOnCheckedChangeListener { view, isChecked ->
+            mutableBluetoothStateToggle.value = isChecked
+            view.apply {
+                isEnabled = false
+                alpha = DISABLED_ALPHA
+            }
+            logger.logBluetoothState(BluetoothStateStage.USER_TOGGLED, isChecked.toString())
+            uiEventLogger.log(BluetoothTileDialogUiEvent.BLUETOOTH_TOGGLE_CLICKED)
+        }
+
+        autoOnToggleLayout.visibility = initialUiProperties.autoOnToggleVisibility
+        autoOnToggle.setOnCheckedChangeListener { _, isChecked ->
+            mutableBluetoothAutoOnToggle.value = isChecked
+            uiEventLogger.log(BluetoothTileDialogUiEvent.BLUETOOTH_AUTO_ON_TOGGLE_CLICKED)
+        }
+    }
+
+    private fun setupDoneButton() {
+        if (isInDialog) {
+            doneButton.setOnClickListener { doneButtonCallback() }
+        } else {
+            doneButton.visibility = GONE
+        }
+    }
+
+    private fun setupRecyclerView() {
+        deviceListView.apply {
+            layoutManager = LinearLayoutManager(contentView.context)
+            adapter = deviceItemAdapter
+        }
+    }
+
+    private fun showProgressBar() {
+        if (progressBarAnimation.visibility != VISIBLE) {
+            progressBarAnimation.visibility = VISIBLE
+            progressBarBackground.visibility = INVISIBLE
+        }
+    }
+
+    private fun hideProgressBar() {
+        if (progressBarAnimation.visibility != INVISIBLE) {
+            progressBarAnimation.visibility = INVISIBLE
+            progressBarBackground.visibility = VISIBLE
+        }
+    }
+
+    internal inner class Adapter : RecyclerView.Adapter<Adapter.DeviceItemViewHolder>() {
+
+        private val diffUtilCallback =
+            object : DiffUtil.ItemCallback<DeviceItem>() {
+                override fun areItemsTheSame(
+                    deviceItem1: DeviceItem,
+                    deviceItem2: DeviceItem,
+                ): Boolean {
+                    return deviceItem1.cachedBluetoothDevice == deviceItem2.cachedBluetoothDevice
+                }
+
+                override fun areContentsTheSame(
+                    deviceItem1: DeviceItem,
+                    deviceItem2: DeviceItem,
+                ): Boolean {
+                    return deviceItem1.type == deviceItem2.type &&
+                        deviceItem1.cachedBluetoothDevice == deviceItem2.cachedBluetoothDevice &&
+                        deviceItem1.deviceName == deviceItem2.deviceName &&
+                        deviceItem1.connectionSummary == deviceItem2.connectionSummary &&
+                        // Ignored the icon drawable
+                        deviceItem1.iconWithDescription?.second ==
+                            deviceItem2.iconWithDescription?.second &&
+                        deviceItem1.background == deviceItem2.background &&
+                        deviceItem1.isEnabled == deviceItem2.isEnabled &&
+                        deviceItem1.actionAccessibilityLabel == deviceItem2.actionAccessibilityLabel
+                }
+            }
+
+        private val asyncListDiffer = AsyncListDiffer(this, diffUtilCallback)
+
+        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DeviceItemViewHolder {
+            val view =
+                LayoutInflater.from(parent.context)
+                    .inflate(R.layout.bluetooth_device_item, parent, false)
+            return DeviceItemViewHolder(view)
+        }
+
+        override fun getItemCount() = asyncListDiffer.currentList.size
+
+        override fun onBindViewHolder(holder: DeviceItemViewHolder, position: Int) {
+            val item = getItem(position)
+            holder.bind(item)
+        }
+
+        internal fun getItem(position: Int) = asyncListDiffer.currentList[position]
+
+        internal fun refreshDeviceItemList(updated: List<DeviceItem>, callback: () -> Unit) {
+            asyncListDiffer.submitList(updated, callback)
+        }
+
+        internal inner class DeviceItemViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+            private val container = view.requireViewById<View>(R.id.bluetooth_device_row)
+            private val nameView = view.requireViewById<TextView>(R.id.bluetooth_device_name)
+            private val summaryView = view.requireViewById<TextView>(R.id.bluetooth_device_summary)
+            private val iconView = view.requireViewById<ImageView>(R.id.bluetooth_device_icon)
+            private val actionIcon = view.requireViewById<ImageView>(R.id.gear_icon_image)
+            private val actionIconView = view.requireViewById<View>(R.id.gear_icon)
+            private val divider = view.requireViewById<View>(R.id.divider)
+
+            internal fun bind(item: DeviceItem) {
+                container.apply {
+                    isEnabled = item.isEnabled
+                    background = item.background?.let { context.getDrawable(it) }
+                    setOnClickListener {
+                        mutableDeviceItemClick.value =
+                            DeviceItemClick(item, it, DeviceItemClick.Target.ENTIRE_ROW)
+                        uiEventLogger.log(BluetoothTileDialogUiEvent.DEVICE_CLICKED)
+                    }
+
+                    // updating icon colors
+                    val tintColor =
+                        context.getColor(
+                            if (item.isActive) InternalR.color.materialColorOnPrimaryContainer
+                            else InternalR.color.materialColorOnSurface
+                        )
+
+                    // update icons
+                    iconView.apply {
+                        item.iconWithDescription?.let {
+                            setImageDrawable(it.first)
+                            contentDescription = it.second
+                        }
+                    }
+
+                    actionIcon.setImageResource(item.actionIconRes)
+                    actionIcon.drawable?.setTint(tintColor)
+
+                    divider.setBackgroundColor(tintColor)
+
+                    // update text styles
+                    nameView.setTextAppearance(
+                        if (item.isActive) R.style.TextAppearance_BluetoothTileDialog_Active
+                        else R.style.TextAppearance_BluetoothTileDialog
+                    )
+                    summaryView.setTextAppearance(
+                        if (item.isActive) R.style.TextAppearance_BluetoothTileDialog_Active
+                        else R.style.TextAppearance_BluetoothTileDialog
+                    )
+
+                    accessibilityDelegate =
+                        object : AccessibilityDelegate() {
+                            override fun onInitializeAccessibilityNodeInfo(
+                                host: View,
+                                info: AccessibilityNodeInfo,
+                            ) {
+                                super.onInitializeAccessibilityNodeInfo(host, info)
+                                info.addAction(
+                                    AccessibilityAction(
+                                        AccessibilityAction.ACTION_CLICK.id,
+                                        item.actionAccessibilityLabel,
+                                    )
+                                )
+                            }
+                        }
+                }
+                nameView.text = item.deviceName
+                summaryView.text = item.connectionSummary
+
+                actionIconView.setOnClickListener {
+                    mutableDeviceItemClick.value =
+                        DeviceItemClick(item, it, DeviceItemClick.Target.ACTION_ICON)
+                }
+            }
+        }
+    }
+
+    internal companion object {
+        const val MIN_HEIGHT_CHANGE_INTERVAL_MS = 800L
+        const val ACTION_BLUETOOTH_DEVICE_DETAILS =
+            "com.android.settings.BLUETOOTH_DEVICE_DETAIL_SETTINGS"
+        const val ACTION_PREVIOUSLY_CONNECTED_DEVICE =
+            "com.android.settings.PREVIOUSLY_CONNECTED_DEVICE"
+        const val ACTION_PAIR_NEW_DEVICE = "android.settings.BLUETOOTH_PAIRING_SETTINGS"
+        const val ACTION_AUDIO_SHARING = "com.android.settings.BLUETOOTH_AUDIO_SHARING_SETTINGS"
+        const val DISABLED_ALPHA = 0.3f
+        const val ENABLED_ALPHA = 1f
+        const val PROGRESS_BAR_ANIMATION_DURATION_MS = 1500L
+
+        private fun Boolean.toInt(): Int {
+            return if (this) 1 else 0
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsViewModel.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsViewModel.kt
index 9dd3b6d..ac4d82a 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsViewModel.kt
@@ -16,30 +16,11 @@
 
 package com.android.systemui.bluetooth.qsdialog
 
-import android.view.LayoutInflater
-import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.viewinterop.AndroidView
 import com.android.systemui.plugins.qs.TileDetailsViewModel
-import com.android.systemui.res.R
 
 class BluetoothDetailsViewModel(onLongClick: () -> Unit) : TileDetailsViewModel() {
     private val _onLongClick = onLongClick
 
-    @Composable
-    override fun GetContentView() {
-        AndroidView(
-            modifier = Modifier.fillMaxWidth().fillMaxHeight(),
-            factory = { context ->
-                // Inflate with the existing dialog xml layout
-                LayoutInflater.from(context).inflate(R.layout.bluetooth_tile_dialog, null)
-                // TODO: b/378513956 - Implement the bluetooth details view
-            },
-        )
-    }
-
     override fun clickOnSettingsButton() {
         _onLongClick()
     }
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt
index 56caddf..3e61c45 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt
@@ -18,50 +18,14 @@
 
 import android.os.Bundle
 import android.view.LayoutInflater
-import android.view.View
-import android.view.View.AccessibilityDelegate
-import android.view.View.GONE
-import android.view.View.INVISIBLE
-import android.view.View.VISIBLE
-import android.view.ViewGroup
-import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
-import android.view.accessibility.AccessibilityNodeInfo
-import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction
-import android.widget.Button
-import android.widget.ImageView
-import android.widget.ProgressBar
-import android.widget.Switch
-import android.widget.TextView
-import androidx.annotation.StringRes
-import androidx.recyclerview.widget.AsyncListDiffer
-import androidx.recyclerview.widget.DiffUtil
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import com.android.internal.R as InternalR
 import com.android.internal.logging.UiEventLogger
-import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.qs.flags.QsDetailedView
 import com.android.systemui.res.R
 import com.android.systemui.shade.domain.interactor.ShadeDialogContextInteractor
 import com.android.systemui.statusbar.phone.SystemUIDialog
-import com.android.systemui.util.time.SystemClock
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.asSharedFlow
-import kotlinx.coroutines.flow.asStateFlow
-import kotlinx.coroutines.isActive
-import kotlinx.coroutines.withContext
-
-data class DeviceItemClick(val deviceItem: DeviceItem, val clickedView: View, val target: Target) {
-    enum class Target {
-        ENTIRE_ROW,
-        ACTION_ICON,
-    }
-}
 
 /** Dialog for showing active, connected and saved bluetooth devices. */
 class BluetoothTileDialogDelegate
@@ -71,37 +35,13 @@
     @Assisted private val cachedContentHeight: Int,
     @Assisted private val bluetoothTileDialogCallback: BluetoothTileDialogCallback,
     @Assisted private val dismissListener: Runnable,
-    @Main private val mainDispatcher: CoroutineDispatcher,
-    private val systemClock: SystemClock,
     private val uiEventLogger: UiEventLogger,
-    private val logger: BluetoothTileDialogLogger,
     private val systemuiDialogFactory: SystemUIDialog.Factory,
     private val shadeDialogContextInteractor: ShadeDialogContextInteractor,
+    private val bluetoothDetailsContentManagerFactory: BluetoothDetailsContentManager.Factory,
 ) : SystemUIDialog.Delegate {
 
-    private val mutableBluetoothStateToggle: MutableStateFlow<Boolean?> = MutableStateFlow(null)
-    internal val bluetoothStateToggle
-        get() = mutableBluetoothStateToggle.asStateFlow()
-
-    private val mutableBluetoothAutoOnToggle: MutableStateFlow<Boolean?> = MutableStateFlow(null)
-    internal val bluetoothAutoOnToggle
-        get() = mutableBluetoothAutoOnToggle.asStateFlow()
-
-    private val mutableDeviceItemClick: MutableSharedFlow<DeviceItemClick> =
-        MutableSharedFlow(extraBufferCapacity = 1)
-    internal val deviceItemClick
-        get() = mutableDeviceItemClick.asSharedFlow()
-
-    private val mutableContentHeight: MutableSharedFlow<Int> =
-        MutableSharedFlow(extraBufferCapacity = 1)
-    internal val contentHeight
-        get() = mutableContentHeight.asSharedFlow()
-
-    private val deviceItemAdapter: Adapter = Adapter()
-
-    private var lastUiUpdateMs: Long = -1
-
-    private var lastItemRow: Int = -1
+    lateinit var contentManager: BluetoothDetailsContentManager
 
     @AssistedFactory
     internal interface Factory {
@@ -114,6 +54,9 @@
     }
 
     override fun createDialog(): SystemUIDialog {
+        // If `QsDetailedView` is enabled, it should show the details view.
+        QsDetailedView.assertInLegacyMode()
+
         return systemuiDialogFactory.create(this, shadeDialogContextInteractor.context)
     }
 
@@ -127,362 +70,24 @@
             dialog.setContentView(this)
         }
 
-        setupToggle(dialog)
-        setupRecyclerView(dialog)
-
-        getSubtitleTextView(dialog).text = context.getString(initialUiProperties.subTitleResId)
-        dialog.requireViewById<View>(R.id.done_button).setOnClickListener { dialog.dismiss() }
-        getSeeAllButton(dialog).setOnClickListener {
-            bluetoothTileDialogCallback.onSeeAllClicked(it)
-        }
-        getPairNewDeviceButton(dialog).setOnClickListener {
-            bluetoothTileDialogCallback.onPairNewDeviceClicked(it)
-        }
-        getAudioSharingButtonView(dialog).apply {
-            setOnClickListener { bluetoothTileDialogCallback.onAudioSharingButtonClicked(it) }
-            accessibilityDelegate =
-                object : AccessibilityDelegate() {
-                    override fun onInitializeAccessibilityNodeInfo(
-                        host: View,
-                        info: AccessibilityNodeInfo,
-                    ) {
-                        super.onInitializeAccessibilityNodeInfo(host, info)
-                        info.addAction(
-                            AccessibilityAction(
-                                AccessibilityAction.ACTION_CLICK.id,
-                                context.getString(
-                                    R.string
-                                        .quick_settings_bluetooth_audio_sharing_button_accessibility
-                                ),
-                            )
-                        )
-                    }
-                }
-        }
-        getScrollViewContent(dialog).apply {
-            minimumHeight =
-                resources.getDimensionPixelSize(initialUiProperties.scrollViewMinHeightResId)
-            layoutParams.height = maxOf(cachedContentHeight, minimumHeight)
-        }
+        contentManager =
+            bluetoothDetailsContentManagerFactory.create(
+                initialUiProperties,
+                cachedContentHeight,
+                bluetoothTileDialogCallback,
+                /* isInDialog= */ true,
+                /* doneButtonCallback= */ fun() {
+                    dialog.dismiss()
+                },
+            )
+        contentManager.bind(dialog.requireViewById(R.id.root))
     }
 
     override fun onStart(dialog: SystemUIDialog) {
-        lastUiUpdateMs = systemClock.elapsedRealtime()
+        contentManager.start()
     }
 
     override fun onStop(dialog: SystemUIDialog) {
-        mutableContentHeight.tryEmit(getScrollViewContent(dialog).measuredHeight)
-    }
-
-    internal suspend fun animateProgressBar(dialog: SystemUIDialog, animate: Boolean) {
-        withContext(mainDispatcher) {
-            if (animate) {
-                showProgressBar(dialog)
-            } else {
-                delay(PROGRESS_BAR_ANIMATION_DURATION_MS)
-                hideProgressBar(dialog)
-            }
-        }
-    }
-
-    internal suspend fun onDeviceItemUpdated(
-        dialog: SystemUIDialog,
-        deviceItem: List<DeviceItem>,
-        showSeeAll: Boolean,
-        showPairNewDevice: Boolean,
-    ) {
-        withContext(mainDispatcher) {
-            val start = systemClock.elapsedRealtime()
-            val itemRow = deviceItem.size + showSeeAll.toInt() + showPairNewDevice.toInt()
-            // If not the first load, add a slight delay for smoother dialog height change
-            if (itemRow != lastItemRow && lastItemRow != -1) {
-                delay(MIN_HEIGHT_CHANGE_INTERVAL_MS - (start - lastUiUpdateMs))
-            }
-            if (isActive) {
-                deviceItemAdapter.refreshDeviceItemList(deviceItem) {
-                    getSeeAllButton(dialog).visibility = if (showSeeAll) VISIBLE else GONE
-                    getPairNewDeviceButton(dialog).visibility =
-                        if (showPairNewDevice) VISIBLE else GONE
-                    // Update the height after data is updated
-                    getScrollViewContent(dialog).layoutParams.height = WRAP_CONTENT
-                    lastUiUpdateMs = systemClock.elapsedRealtime()
-                    lastItemRow = itemRow
-                    logger.logDeviceUiUpdate(lastUiUpdateMs - start)
-                }
-            }
-        }
-    }
-
-    internal fun onBluetoothStateUpdated(
-        dialog: SystemUIDialog,
-        isEnabled: Boolean,
-        uiProperties: BluetoothTileDialogViewModel.UiProperties,
-    ) {
-        getToggleView(dialog).apply {
-            isChecked = isEnabled
-            setEnabled(true)
-            alpha = ENABLED_ALPHA
-        }
-        getSubtitleTextView(dialog).text = dialog.context.getString(uiProperties.subTitleResId)
-        getAutoOnToggleView(dialog).visibility = uiProperties.autoOnToggleVisibility
-    }
-
-    internal fun onBluetoothAutoOnUpdated(
-        dialog: SystemUIDialog,
-        isEnabled: Boolean,
-        @StringRes infoResId: Int,
-    ) {
-        getAutoOnToggle(dialog).isChecked = isEnabled
-        getAutoOnToggleInfoTextView(dialog).text = dialog.context.getString(infoResId)
-    }
-
-    internal fun onAudioSharingButtonUpdated(
-        dialog: SystemUIDialog,
-        visibility: Int,
-        label: String?,
-        isActive: Boolean,
-    ) {
-        getAudioSharingButtonView(dialog).apply {
-            this.visibility = visibility
-            label?.let { text = it }
-            this.isActivated = isActive
-        }
-    }
-
-    private fun setupToggle(dialog: SystemUIDialog) {
-        val toggleView = getToggleView(dialog)
-        toggleView.setOnCheckedChangeListener { view, isChecked ->
-            mutableBluetoothStateToggle.value = isChecked
-            view.apply {
-                isEnabled = false
-                alpha = DISABLED_ALPHA
-            }
-            logger.logBluetoothState(BluetoothStateStage.USER_TOGGLED, isChecked.toString())
-            uiEventLogger.log(BluetoothTileDialogUiEvent.BLUETOOTH_TOGGLE_CLICKED)
-        }
-
-        getAutoOnToggleView(dialog).visibility = initialUiProperties.autoOnToggleVisibility
-        getAutoOnToggle(dialog).setOnCheckedChangeListener { _, isChecked ->
-            mutableBluetoothAutoOnToggle.value = isChecked
-            uiEventLogger.log(BluetoothTileDialogUiEvent.BLUETOOTH_AUTO_ON_TOGGLE_CLICKED)
-        }
-    }
-
-    private fun getToggleView(dialog: SystemUIDialog): Switch {
-        return dialog.requireViewById(R.id.bluetooth_toggle)
-    }
-
-    private fun getSubtitleTextView(dialog: SystemUIDialog): TextView {
-        return dialog.requireViewById(R.id.bluetooth_tile_dialog_subtitle)
-    }
-
-    private fun getSeeAllButton(dialog: SystemUIDialog): View {
-        return dialog.requireViewById(R.id.see_all_button)
-    }
-
-    private fun getPairNewDeviceButton(dialog: SystemUIDialog): View {
-        return dialog.requireViewById(R.id.pair_new_device_button)
-    }
-
-    private fun getDeviceListView(dialog: SystemUIDialog): RecyclerView {
-        return dialog.requireViewById(R.id.device_list)
-    }
-
-    private fun getAutoOnToggle(dialog: SystemUIDialog): Switch {
-        return dialog.requireViewById(R.id.bluetooth_auto_on_toggle)
-    }
-
-    private fun getAudioSharingButtonView(dialog: SystemUIDialog): Button {
-        return dialog.requireViewById(R.id.audio_sharing_button)
-    }
-
-    private fun getAutoOnToggleView(dialog: SystemUIDialog): View {
-        return dialog.requireViewById(R.id.bluetooth_auto_on_toggle_layout)
-    }
-
-    private fun getAutoOnToggleInfoTextView(dialog: SystemUIDialog): TextView {
-        return dialog.requireViewById(R.id.bluetooth_auto_on_toggle_info_text)
-    }
-
-    private fun getProgressBarAnimation(dialog: SystemUIDialog): ProgressBar {
-        return dialog.requireViewById(R.id.bluetooth_tile_dialog_progress_animation)
-    }
-
-    private fun getProgressBarBackground(dialog: SystemUIDialog): View {
-        return dialog.requireViewById(R.id.bluetooth_tile_dialog_progress_background)
-    }
-
-    private fun getScrollViewContent(dialog: SystemUIDialog): View {
-        return dialog.requireViewById(R.id.scroll_view)
-    }
-
-    private fun setupRecyclerView(dialog: SystemUIDialog) {
-        getDeviceListView(dialog).apply {
-            layoutManager = LinearLayoutManager(dialog.context)
-            adapter = deviceItemAdapter
-        }
-    }
-
-    private fun showProgressBar(dialog: SystemUIDialog) {
-        val progressBarAnimation = getProgressBarAnimation(dialog)
-        val progressBarBackground = getProgressBarBackground(dialog)
-        if (progressBarAnimation.visibility != VISIBLE) {
-            progressBarAnimation.visibility = VISIBLE
-            progressBarBackground.visibility = INVISIBLE
-        }
-    }
-
-    private fun hideProgressBar(dialog: SystemUIDialog) {
-        val progressBarAnimation = getProgressBarAnimation(dialog)
-        val progressBarBackground = getProgressBarBackground(dialog)
-        if (progressBarAnimation.visibility != INVISIBLE) {
-            progressBarAnimation.visibility = INVISIBLE
-            progressBarBackground.visibility = VISIBLE
-        }
-    }
-
-    internal inner class Adapter : RecyclerView.Adapter<Adapter.DeviceItemViewHolder>() {
-
-        private val diffUtilCallback =
-            object : DiffUtil.ItemCallback<DeviceItem>() {
-                override fun areItemsTheSame(
-                    deviceItem1: DeviceItem,
-                    deviceItem2: DeviceItem,
-                ): Boolean {
-                    return deviceItem1.cachedBluetoothDevice == deviceItem2.cachedBluetoothDevice
-                }
-
-                override fun areContentsTheSame(
-                    deviceItem1: DeviceItem,
-                    deviceItem2: DeviceItem,
-                ): Boolean {
-                    return deviceItem1.type == deviceItem2.type &&
-                        deviceItem1.cachedBluetoothDevice == deviceItem2.cachedBluetoothDevice &&
-                        deviceItem1.deviceName == deviceItem2.deviceName &&
-                        deviceItem1.connectionSummary == deviceItem2.connectionSummary &&
-                        // Ignored the icon drawable
-                        deviceItem1.iconWithDescription?.second ==
-                            deviceItem2.iconWithDescription?.second &&
-                        deviceItem1.background == deviceItem2.background &&
-                        deviceItem1.isEnabled == deviceItem2.isEnabled &&
-                        deviceItem1.actionAccessibilityLabel == deviceItem2.actionAccessibilityLabel
-                }
-            }
-
-        private val asyncListDiffer = AsyncListDiffer(this, diffUtilCallback)
-
-        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DeviceItemViewHolder {
-            val view =
-                LayoutInflater.from(parent.context)
-                    .inflate(R.layout.bluetooth_device_item, parent, false)
-            return DeviceItemViewHolder(view)
-        }
-
-        override fun getItemCount() = asyncListDiffer.currentList.size
-
-        override fun onBindViewHolder(holder: DeviceItemViewHolder, position: Int) {
-            val item = getItem(position)
-            holder.bind(item)
-        }
-
-        internal fun getItem(position: Int) = asyncListDiffer.currentList[position]
-
-        internal fun refreshDeviceItemList(updated: List<DeviceItem>, callback: () -> Unit) {
-            asyncListDiffer.submitList(updated, callback)
-        }
-
-        internal inner class DeviceItemViewHolder(view: View) : RecyclerView.ViewHolder(view) {
-            private val container = view.requireViewById<View>(R.id.bluetooth_device_row)
-            private val nameView = view.requireViewById<TextView>(R.id.bluetooth_device_name)
-            private val summaryView = view.requireViewById<TextView>(R.id.bluetooth_device_summary)
-            private val iconView = view.requireViewById<ImageView>(R.id.bluetooth_device_icon)
-            private val actionIcon = view.requireViewById<ImageView>(R.id.gear_icon_image)
-            private val actionIconView = view.requireViewById<View>(R.id.gear_icon)
-            private val divider = view.requireViewById<View>(R.id.divider)
-
-            internal fun bind(item: DeviceItem) {
-                container.apply {
-                    isEnabled = item.isEnabled
-                    background = item.background?.let { context.getDrawable(it) }
-                    setOnClickListener {
-                        mutableDeviceItemClick.tryEmit(
-                            DeviceItemClick(item, it, DeviceItemClick.Target.ENTIRE_ROW)
-                        )
-                        uiEventLogger.log(BluetoothTileDialogUiEvent.DEVICE_CLICKED)
-                    }
-
-                    // updating icon colors
-                    val tintColor =
-                        context.getColor(
-                            if (item.isActive) InternalR.color.materialColorOnPrimaryContainer
-                            else InternalR.color.materialColorOnSurface
-                        )
-
-                    // update icons
-                    iconView.apply {
-                        item.iconWithDescription?.let {
-                            setImageDrawable(it.first)
-                            contentDescription = it.second
-                        }
-                    }
-
-                    actionIcon.setImageResource(item.actionIconRes)
-                    actionIcon.drawable?.setTint(tintColor)
-
-                    divider.setBackgroundColor(tintColor)
-
-                    // update text styles
-                    nameView.setTextAppearance(
-                        if (item.isActive) R.style.TextAppearance_BluetoothTileDialog_Active
-                        else R.style.TextAppearance_BluetoothTileDialog
-                    )
-                    summaryView.setTextAppearance(
-                        if (item.isActive) R.style.TextAppearance_BluetoothTileDialog_Active
-                        else R.style.TextAppearance_BluetoothTileDialog
-                    )
-
-                    accessibilityDelegate =
-                        object : AccessibilityDelegate() {
-                            override fun onInitializeAccessibilityNodeInfo(
-                                host: View,
-                                info: AccessibilityNodeInfo,
-                            ) {
-                                super.onInitializeAccessibilityNodeInfo(host, info)
-                                info.addAction(
-                                    AccessibilityAction(
-                                        AccessibilityAction.ACTION_CLICK.id,
-                                        item.actionAccessibilityLabel,
-                                    )
-                                )
-                            }
-                        }
-                }
-                nameView.text = item.deviceName
-                summaryView.text = item.connectionSummary
-
-                actionIconView.setOnClickListener {
-                    mutableDeviceItemClick.tryEmit(
-                        DeviceItemClick(item, it, DeviceItemClick.Target.ACTION_ICON)
-                    )
-                }
-            }
-        }
-    }
-
-    internal companion object {
-        const val MIN_HEIGHT_CHANGE_INTERVAL_MS = 800L
-        const val ACTION_BLUETOOTH_DEVICE_DETAILS =
-            "com.android.settings.BLUETOOTH_DEVICE_DETAIL_SETTINGS"
-        const val ACTION_PREVIOUSLY_CONNECTED_DEVICE =
-            "com.android.settings.PREVIOUSLY_CONNECTED_DEVICE"
-        const val ACTION_PAIR_NEW_DEVICE = "android.settings.BLUETOOTH_PAIRING_SETTINGS"
-        const val ACTION_AUDIO_SHARING = "com.android.settings.BLUETOOTH_AUDIO_SHARING_SETTINGS"
-        const val DISABLED_ALPHA = 0.3f
-        const val ENABLED_ALPHA = 1f
-        const val PROGRESS_BAR_ANIMATION_DURATION_MS = 1500L
-
-        private fun Boolean.toInt(): Int {
-            return if (this) 1 else 0
-        }
+        contentManager.releaseView()
     }
 }
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 bf04897..9492abb 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.bluetooth.qsdialog
 
+import android.content.Context
 import android.content.Intent
 import android.content.SharedPreferences
 import android.os.Bundle
@@ -34,15 +35,16 @@
 import com.android.systemui.animation.DialogCuj
 import com.android.systemui.animation.DialogTransitionAnimator
 import com.android.systemui.animation.Expandable
-import com.android.systemui.bluetooth.qsdialog.BluetoothTileDialogDelegate.Companion.ACTION_AUDIO_SHARING
-import com.android.systemui.bluetooth.qsdialog.BluetoothTileDialogDelegate.Companion.ACTION_PAIR_NEW_DEVICE
-import com.android.systemui.bluetooth.qsdialog.BluetoothTileDialogDelegate.Companion.ACTION_PREVIOUSLY_CONNECTED_DEVICE
+import com.android.systemui.bluetooth.qsdialog.BluetoothDetailsContentManager.Companion.ACTION_AUDIO_SHARING
+import com.android.systemui.bluetooth.qsdialog.BluetoothDetailsContentManager.Companion.ACTION_PAIR_NEW_DEVICE
+import com.android.systemui.bluetooth.qsdialog.BluetoothDetailsContentManager.Companion.ACTION_PREVIOUSLY_CONNECTED_DEVICE
 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.plugins.ActivityStarter
 import com.android.systemui.res.R
+import com.android.systemui.statusbar.phone.SystemUIDialog
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
@@ -57,7 +59,12 @@
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.withContext
 
-/** ViewModel for Bluetooth Dialog after clicking on the Bluetooth QS tile. */
+/**
+ * ViewModel for Bluetooth Dialog or Bluetooth Details View after clicking on the Bluetooth QS tile.
+ *
+ * TODO: b/378513956 Rename this class to BluetoothDetailsContentViewModel, since it's not only used
+ *   by the dialog view.
+ */
 @SysUISingleton
 internal class BluetoothTileDialogViewModel
 @Inject
@@ -78,36 +85,61 @@
     @Background private val backgroundDispatcher: CoroutineDispatcher,
     @Main private val sharedPreferences: SharedPreferences,
     private val bluetoothDialogDelegateFactory: BluetoothTileDialogDelegate.Factory,
+    private val bluetoothDetailsContentManagerFactory: BluetoothDetailsContentManager.Factory,
 ) : BluetoothTileDialogCallback {
 
+    lateinit var contentManager: BluetoothDetailsContentManager
     private var job: Job? = null
 
     /**
-     * Shows the dialog.
+     * Shows the details content.
      *
-     * @param view The view from which the dialog is shown.
+     * @param view The view from which the dialog is shown. If view is null, it should show the
+     *   bluetooth tile details view.
+     *
+     * TODO: b/378513956 Refactor this method into 2. One is called by the dialog to show the
+     *   dialog, another is called by the details view model to bind the view.
      */
-    fun showDialog(expandable: Expandable?) {
+    fun showDetailsContent(expandable: Expandable?, view: View?) {
         cancelJob()
 
         job =
             coroutineScope.launch(context = mainDispatcher) {
                 var updateDeviceItemJob: Job?
                 var updateDialogUiJob: Job? = null
-                val dialogDelegate = createBluetoothTileDialog()
-                val dialog = dialogDelegate.createDialog()
-                val context = dialog.context
+                val dialog: SystemUIDialog?
+                val context: Context
 
-                val controller =
-                    expandable?.dialogTransitionController(
-                        DialogCuj(
-                            InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
-                            INTERACTION_JANK_TAG,
+                if (view == null) {
+                    // Render with dialog
+                    val dialogDelegate = createBluetoothTileDialog()
+                    dialog = dialogDelegate.createDialog()
+                    context = dialog.context
+
+                    val controller =
+                        expandable?.dialogTransitionController(
+                            DialogCuj(
+                                InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
+                                INTERACTION_JANK_TAG,
+                            )
                         )
-                    )
-                controller?.let {
-                    dialogTransitionAnimator.show(dialog, it, animateBackgroundBoundsChange = true)
-                } ?: dialog.show()
+                    controller?.let {
+                        dialogTransitionAnimator.show(
+                            dialog,
+                            it,
+                            animateBackgroundBoundsChange = true,
+                        )
+                    } ?: dialog.show()
+                    // contentManager is created after dialog.show
+                    contentManager = dialogDelegate.contentManager
+                } else {
+                    // Render with tile details view
+                    dialog = null
+                    context = view.context
+                    contentManager = createContentManager()
+                    contentManager.bind(view)
+                    contentManager.start()
+                }
 
                 updateDeviceItemJob = launch {
                     deviceItemInteractor.updateDeviceItems(context, DeviceFetchTrigger.FIRST_LOAD)
@@ -121,15 +153,14 @@
                     ) { deviceItem, showSeeAll ->
                         updateDialogUiJob?.cancel()
                         updateDialogUiJob = launch {
-                            dialogDelegate.apply {
+                            contentManager.apply {
                                 onDeviceItemUpdated(
-                                    dialog,
                                     deviceItem,
                                     showSeeAll,
                                     showPairNewDevice =
                                         bluetoothStateInteractor.isBluetoothEnabled(),
                                 )
-                                animateProgressBar(dialog, false)
+                                animateProgressBar(false)
                             }
                         }
                     }
@@ -150,7 +181,7 @@
                         },
                     )
                     .onEach {
-                        dialogDelegate.animateProgressBar(dialog, true)
+                        contentManager.animateProgressBar(true)
                         updateDeviceItemJob?.cancel()
                         updateDeviceItemJob = launch {
                             deviceItemInteractor.updateDeviceItems(
@@ -171,16 +202,14 @@
                             .onEach {
                                 when (it) {
                                     is AudioSharingButtonState.Visible -> {
-                                        dialogDelegate.onAudioSharingButtonUpdated(
-                                            dialog,
+                                        contentManager.onAudioSharingButtonUpdated(
                                             VISIBLE,
                                             context.getString(it.resId),
                                             it.isActive,
                                         )
                                     }
                                     is AudioSharingButtonState.Gone -> {
-                                        dialogDelegate.onAudioSharingButtonUpdated(
-                                            dialog,
+                                        contentManager.onAudioSharingButtonUpdated(
                                             GONE,
                                             label = null,
                                             isActive = false,
@@ -197,8 +226,7 @@
                 // the device item list.
                 bluetoothStateInteractor.bluetoothStateUpdate
                     .onEach {
-                        dialogDelegate.onBluetoothStateUpdated(
-                            dialog,
+                        contentManager.onBluetoothStateUpdated(
                             it,
                             UiProperties.build(it, isAutoOnToggleFeatureAvailable()),
                         )
@@ -214,16 +242,17 @@
 
                 // bluetoothStateToggle is emitted when user toggles the bluetooth state switch,
                 // send the new value to the bluetoothStateInteractor and animate the progress bar.
-                dialogDelegate.bluetoothStateToggle
+                contentManager.bluetoothStateToggle
                     .filterNotNull()
                     .onEach {
-                        dialogDelegate.animateProgressBar(dialog, true)
+                        contentManager.animateProgressBar(true)
                         bluetoothStateInteractor.setBluetoothEnabled(it)
                     }
                     .launchIn(this)
 
                 // deviceItemClick is emitted when user clicked on a device item.
-                dialogDelegate.deviceItemClick
+                contentManager.deviceItemClick
+                    .filterNotNull()
                     .onEach {
                         when (it.target) {
                             DeviceItemClick.Target.ENTIRE_ROW -> {
@@ -245,7 +274,8 @@
                     .launchIn(this)
 
                 // contentHeight is emitted when the dialog is dismissed.
-                dialogDelegate.contentHeight
+                contentManager.contentHeight
+                    .filterNotNull()
                     .onEach {
                         withContext(backgroundDispatcher) {
                             sharedPreferences.edit().putInt(CONTENT_HEIGHT_PREF_KEY, it).apply()
@@ -258,8 +288,7 @@
                     // changed.
                     bluetoothAutoOnInteractor.isEnabled
                         .onEach {
-                            dialogDelegate.onBluetoothAutoOnUpdated(
-                                dialog,
+                            contentManager.onBluetoothAutoOnUpdated(
                                 it,
                                 if (it) R.string.turn_on_bluetooth_auto_info_enabled
                                 else R.string.turn_on_bluetooth_auto_info_disabled,
@@ -269,36 +298,48 @@
 
                     // bluetoothAutoOnToggle is emitted when user toggles the bluetooth auto on
                     // switch, send the new value to the bluetoothAutoOnInteractor.
-                    dialogDelegate.bluetoothAutoOnToggle
+                    contentManager.bluetoothAutoOnToggle
                         .filterNotNull()
                         .onEach { bluetoothAutoOnInteractor.setEnabled(it) }
                         .launchIn(this)
                 }
 
-                produce<Unit> { awaitClose { dialog.cancel() } }
+                produce<Unit> { awaitClose { dialog?.cancel() } }
             }
     }
 
     private suspend fun createBluetoothTileDialog(): BluetoothTileDialogDelegate {
-        val cachedContentHeight =
-            withContext(backgroundDispatcher) {
-                sharedPreferences.getInt(
-                    CONTENT_HEIGHT_PREF_KEY,
-                    ViewGroup.LayoutParams.WRAP_CONTENT,
-                )
-            }
-
         return bluetoothDialogDelegateFactory.create(
-            UiProperties.build(
-                bluetoothStateInteractor.isBluetoothEnabled(),
-                isAutoOnToggleFeatureAvailable(),
-            ),
-            cachedContentHeight,
+            getUiProperties(),
+            getCachedContentHeight(),
             this@BluetoothTileDialogViewModel,
             { cancelJob() },
         )
     }
 
+    private suspend fun createContentManager(): BluetoothDetailsContentManager {
+        return bluetoothDetailsContentManagerFactory.create(
+            getUiProperties(),
+            getCachedContentHeight(),
+            this@BluetoothTileDialogViewModel,
+            /* isInDialog= */ false,
+            /* doneButtonCallback= */ fun() {},
+        )
+    }
+
+    private suspend fun getUiProperties(): UiProperties {
+        return UiProperties.build(
+            bluetoothStateInteractor.isBluetoothEnabled(),
+            isAutoOnToggleFeatureAvailable(),
+        )
+    }
+
+    private suspend fun getCachedContentHeight(): Int {
+        return withContext(backgroundDispatcher) {
+            sharedPreferences.getInt(CONTENT_HEIGHT_PREF_KEY, ViewGroup.LayoutParams.WRAP_CONTENT)
+        }
+    }
+
     override fun onSeeAllClicked(view: View) {
         uiEventLogger.log(BluetoothTileDialogUiEvent.SEE_ALL_CLICKED)
         startSettingsActivity(Intent(ACTION_PREVIOUSLY_CONNECTED_DEVICE), view)
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractor.kt
index cb4ec37..26996ac 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractor.kt
@@ -27,7 +27,7 @@
 import kotlinx.coroutines.withContext
 
 interface DeviceItemActionInteractor {
-    suspend fun onClick(deviceItem: DeviceItem, dialog: SystemUIDialog)
+    suspend fun onClick(deviceItem: DeviceItem, dialog: SystemUIDialog?) {}
 
     suspend fun onActionIconClick(deviceItem: DeviceItem, onIntent: (Intent) -> Unit)
 }
@@ -40,7 +40,7 @@
     private val uiEventLogger: UiEventLogger,
 ) : DeviceItemActionInteractor {
 
-    override suspend fun onClick(deviceItem: DeviceItem, dialog: SystemUIDialog) {
+    override suspend fun onClick(deviceItem: DeviceItem, dialog: SystemUIDialog?) {
         withContext(backgroundDispatcher) {
             deviceItem.cachedBluetoothDevice.apply {
                 when (deviceItem.type) {
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 6f2a2c4..b13f6df 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,49 +16,75 @@
 
 package com.android.systemui.brightness.ui.compose
 
+import android.content.Context
 import android.view.MotionEvent
+import androidx.annotation.VisibleForTesting
+import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.AnimationVector1D
+import androidx.compose.animation.core.VectorConverter
 import androidx.compose.animation.core.animateFloatAsState
+import androidx.compose.animation.core.tween
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.interaction.DragInteraction
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.shape.CornerSize
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
 import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Text
+import androidx.compose.material3.Slider
+import androidx.compose.material3.SliderDefaults
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.produceState
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.rememberUpdatedState
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.drawWithCache
+import androidx.compose.ui.draw.drawWithContent
 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.asImageBitmap
+import androidx.compose.ui.graphics.drawscope.DrawScope
+import androidx.compose.ui.graphics.drawscope.translate
+import androidx.compose.ui.graphics.painter.BitmapPainter
+import androidx.compose.ui.graphics.painter.ColorPainter
+import androidx.compose.ui.graphics.painter.Painter
 import androidx.compose.ui.input.pointer.pointerInteropFilter
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.colorResource
-import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.app.tracing.coroutines.launchTraced as launch
-import com.android.compose.PlatformSlider
 import com.android.compose.ui.graphics.drawInOverlay
 import com.android.systemui.Flags
+import com.android.systemui.biometrics.Utils.toBitmap
 import com.android.systemui.brightness.shared.model.GammaBrightness
+import com.android.systemui.brightness.ui.compose.AnimationSpecs.IconAppearSpec
+import com.android.systemui.brightness.ui.compose.AnimationSpecs.IconDisappearSpec
+import com.android.systemui.brightness.ui.compose.Dimensions.IconPadding
+import com.android.systemui.brightness.ui.compose.Dimensions.IconSize
+import com.android.systemui.brightness.ui.compose.Dimensions.SliderBackgroundFrameSize
+import com.android.systemui.brightness.ui.compose.Dimensions.SliderBackgroundRoundedCorner
+import com.android.systemui.brightness.ui.compose.Dimensions.SliderTrackRoundedCorner
+import com.android.systemui.brightness.ui.compose.Dimensions.ThumbTrackGapSize
 import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel
 import com.android.systemui.brightness.ui.viewmodel.Drag
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.common.shared.model.Text
-import com.android.systemui.common.ui.compose.Icon
 import com.android.systemui.compose.modifiers.sysuiResTag
 import com.android.systemui.haptics.slider.SeekableSliderTrackerConfig
 import com.android.systemui.haptics.slider.SliderHapticFeedbackConfig
@@ -67,27 +93,32 @@
 import com.android.systemui.qs.ui.compose.borderOnFocus
 import com.android.systemui.res.R
 import com.android.systemui.utils.PolicyRestriction
+import platform.test.motion.compose.values.MotionTestValueKey
+import platform.test.motion.compose.values.motionTestValues
 
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
 @Composable
-private fun BrightnessSlider(
-    viewModel: BrightnessSliderViewModel,
+@VisibleForTesting
+fun BrightnessSlider(
     gammaValue: Int,
     valueRange: IntRange,
-    label: Text.Resource,
-    icon: Icon,
+    iconResProvider: (Float) -> Int,
+    imageLoader: suspend (Int, Context) -> Icon.Loaded,
     restriction: PolicyRestriction,
     onRestrictedClick: (PolicyRestriction.Restricted) -> Unit,
     onDrag: (Int) -> Unit,
     onStop: (Int) -> Unit,
+    overriddenByAppState: Boolean,
     modifier: Modifier = Modifier,
-    formatter: (Int) -> String = { "$it" },
+    showToast: () -> Unit = {},
     hapticsViewModelFactory: SliderHapticsViewModel.Factory,
 ) {
     var value by remember(gammaValue) { mutableIntStateOf(gammaValue) }
     val animatedValue by
         animateFloatAsState(targetValue = value.toFloat(), label = "BrightnessSliderAnimatedValue")
     val floatValueRange = valueRange.first.toFloat()..valueRange.last.toFloat()
-    val isRestricted = remember(restriction) { restriction is PolicyRestriction.Restricted }
+    val isRestricted = restriction is PolicyRestriction.Restricted
+    val enabled = !isRestricted
     val interactionSource = remember { MutableInteractionSource() }
     val hapticsViewModel: SliderHapticsViewModel? =
         if (Flags.hapticsForComposeSliders()) {
@@ -105,20 +136,56 @@
         } else {
             null
         }
+    val colors = SliderDefaults.colors()
 
-    val overriddenByAppState by
-        if (Flags.showToastWhenAppControlBrightness()) {
-            viewModel.brightnessOverriddenByWindow.collectAsStateWithLifecycle()
-        } else {
-            remember { mutableStateOf(false) }
+    // The value state is recreated every time gammaValue changes, so we recreate this derivedState
+    // We have to use value as that's the value that changes when the user is dragging (gammaValue
+    // is always the starting value: actual (not temporary) brightness).
+    val iconRes by
+        remember(gammaValue, valueRange) {
+            derivedStateOf {
+                val percentage =
+                    (value - valueRange.first) * 100f / (valueRange.last - valueRange.first)
+                iconResProvider(percentage)
+            }
+        }
+    val context = LocalContext.current
+    val painter: Painter by
+        produceState<Painter>(
+            initialValue = ColorPainter(Color.Transparent),
+            key1 = iconRes,
+            key2 = context,
+        ) {
+            val icon = imageLoader(iconRes, context)
+            // toBitmap is Drawable?.() -> Bitmap? and handles null internally.
+            val bitmap = icon.drawable.toBitmap()!!.asImageBitmap()
+            this@produceState.value = BitmapPainter(bitmap)
         }
 
-    PlatformSlider(
+    val activeIconColor = colors.activeTickColor
+    val inactiveIconColor = colors.inactiveTickColor
+    val trackIcon: DrawScope.(Offset, Color, Float) -> Unit =
+        remember(painter) {
+            { offset, color, alpha ->
+                translate(offset.x + IconPadding.toPx(), offset.y) {
+                    with(painter) {
+                        draw(
+                            IconSize.toSize(),
+                            colorFilter = ColorFilter.tint(color),
+                            alpha = alpha,
+                        )
+                    }
+                }
+            }
+        }
+
+    Slider(
         value = animatedValue,
         valueRange = floatValueRange,
-        enabled = !isRestricted,
+        enabled = enabled,
+        colors = colors,
         onValueChange = {
-            if (!isRestricted) {
+            if (enabled) {
                 if (!overriddenByAppState) {
                     hapticsViewModel?.onValueChange(it)
                     value = it.toInt()
@@ -127,7 +194,7 @@
             }
         },
         onValueChangeFinished = {
-            if (!isRestricted) {
+            if (enabled) {
                 if (!overriddenByAppState) {
                     hapticsViewModel?.onValueChangeEnded()
                     onStop(value)
@@ -140,46 +207,117 @@
                     onRestrictedClick(restriction)
                 }
             },
-        icon = { isDragging ->
-            if (isDragging) {
-                Text(text = formatter(value))
-            } else {
-                Icon(modifier = Modifier.size(24.dp), icon = icon)
-            }
-        },
-        label = {
-            Text(
-                text = stringResource(id = label.res),
-                style = MaterialTheme.typography.titleMedium,
-                maxLines = 1,
+        interactionSource = interactionSource,
+        thumb = {
+            SliderDefaults.Thumb(
+                interactionSource = interactionSource,
+                enabled = enabled,
+                thumbSize = DpSize(4.dp, 52.dp),
             )
         },
-        interactionSource = interactionSource,
+        track = { sliderState ->
+            var showIconActive by remember { mutableStateOf(true) }
+            val iconActiveAlphaAnimatable = remember {
+                Animatable(
+                    initialValue = 1f,
+                    typeConverter = Float.VectorConverter,
+                    label = "iconActiveAlpha",
+                )
+            }
+
+            val iconInactiveAlphaAnimatable = remember {
+                Animatable(
+                    initialValue = 0f,
+                    typeConverter = Float.VectorConverter,
+                    label = "iconInactiveAlpha",
+                )
+            }
+
+            LaunchedEffect(iconActiveAlphaAnimatable, iconInactiveAlphaAnimatable, showIconActive) {
+                if (showIconActive) {
+                    launch { iconActiveAlphaAnimatable.appear() }
+                    launch { iconInactiveAlphaAnimatable.disappear() }
+                } else {
+                    launch { iconActiveAlphaAnimatable.disappear() }
+                    launch { iconInactiveAlphaAnimatable.appear() }
+                }
+            }
+
+            SliderDefaults.Track(
+                sliderState = sliderState,
+                modifier =
+                    Modifier.motionTestValues {
+                            (iconActiveAlphaAnimatable.isRunning ||
+                                iconInactiveAlphaAnimatable.isRunning) exportAs
+                                BrightnessSliderMotionTestKeys.AnimatingIcon
+
+                            iconActiveAlphaAnimatable.value exportAs
+                                BrightnessSliderMotionTestKeys.ActiveIconAlpha
+                            iconInactiveAlphaAnimatable.value exportAs
+                                BrightnessSliderMotionTestKeys.InactiveIconAlpha
+                        }
+                        .height(40.dp)
+                        .drawWithContent {
+                            drawContent()
+
+                            val yOffset = size.height / 2 - IconSize.toSize().height / 2
+                            val activeTrackStart = 0f
+                            val activeTrackEnd =
+                                size.width * sliderState.coercedValueAsFraction -
+                                    ThumbTrackGapSize.toPx()
+                            val inactiveTrackStart = activeTrackEnd + ThumbTrackGapSize.toPx() * 2
+                            val inactiveTrackEnd = size.width
+
+                            val activeTrackWidth = activeTrackEnd - activeTrackStart
+                            val inactiveTrackWidth = inactiveTrackEnd - inactiveTrackStart
+                            if (
+                                IconSize.toSize().width < activeTrackWidth - IconPadding.toPx() * 2
+                            ) {
+                                showIconActive = true
+                                trackIcon(
+                                    Offset(activeTrackStart, yOffset),
+                                    activeIconColor,
+                                    iconActiveAlphaAnimatable.value,
+                                )
+                            } else if (
+                                IconSize.toSize().width <
+                                    inactiveTrackWidth - IconPadding.toPx() * 2
+                            ) {
+                                showIconActive = false
+                                trackIcon(
+                                    Offset(inactiveTrackStart, yOffset),
+                                    inactiveIconColor,
+                                    iconInactiveAlphaAnimatable.value,
+                                )
+                            }
+                        },
+                trackCornerSize = SliderTrackRoundedCorner,
+                trackInsideCornerSize = 2.dp,
+                drawStopIndicator = null,
+                thumbTrackGapSize = ThumbTrackGapSize,
+            )
+        },
     )
+
+    val currentShowToast by rememberUpdatedState(showToast)
     // Showing the warning toast if the current running app window has controlled the
     // brightness value.
     if (Flags.showToastWhenAppControlBrightness()) {
-        val context = LocalContext.current
         LaunchedEffect(interactionSource) {
             interactionSource.interactions.collect { interaction ->
                 if (interaction is DragInteraction.Start && overriddenByAppState) {
-                    viewModel.showToast(
-                        context,
-                        R.string.quick_settings_brightness_unable_adjust_msg,
-                    )
+                    currentShowToast()
                 }
             }
         }
     }
 }
 
-private val sliderBackgroundFrameSize = 8.dp
-
 private fun Modifier.sliderBackground(color: Color) = drawWithCache {
-    val offsetAround = sliderBackgroundFrameSize.toPx()
-    val newSize = Size(size.width + 2 * offsetAround, size.height + 2 * offsetAround)
-    val offset = Offset(-offsetAround, -offsetAround)
-    val cornerRadius = CornerRadius(offsetAround + size.height / 2)
+    val offsetAround = SliderBackgroundFrameSize.toSize()
+    val newSize = Size(size.width + 2 * offsetAround.width, size.height + 2 * offsetAround.height)
+    val offset = Offset(-offsetAround.width, -offsetAround.height)
+    val cornerRadius = CornerRadius(SliderBackgroundRoundedCorner.toPx())
     onDrawBehind {
         drawRoundRect(color = color, topLeft = offset, size = newSize, cornerRadius = cornerRadius)
     }
@@ -192,21 +330,30 @@
     containerColor: Color = colorResource(R.color.shade_scrim_background_dark),
 ) {
     val gamma = viewModel.currentBrightness.value
+    if (gamma == BrightnessSliderViewModel.initialValue.value) { // Ignore initial negative value.
+        return
+    }
+    val context = LocalContext.current
     val coroutineScope = rememberCoroutineScope()
     val restriction by
         viewModel.policyRestriction.collectAsStateWithLifecycle(
             initialValue = PolicyRestriction.NoRestriction
         )
+    val overriddenByAppState by
+        if (Flags.showToastWhenAppControlBrightness()) {
+            viewModel.brightnessOverriddenByWindow.collectAsStateWithLifecycle()
+        } else {
+            remember { mutableStateOf(false) }
+        }
 
     DisposableEffect(Unit) { onDispose { viewModel.setIsDragging(false) } }
 
     Box(modifier = modifier.fillMaxWidth().sysuiResTag("brightness_slider")) {
         BrightnessSlider(
-            viewModel = viewModel,
             gammaValue = gamma,
             valueRange = viewModel.minBrightness.value..viewModel.maxBrightness.value,
-            label = viewModel.label,
-            icon = viewModel.icon,
+            iconResProvider = BrightnessSliderViewModel::getIconForPercentage,
+            imageLoader = viewModel::loadImage,
             restriction = restriction,
             onRestrictedClick = viewModel::showPolicyRestrictionDialog,
             onDrag = {
@@ -220,7 +367,7 @@
             modifier =
                 Modifier.borderOnFocus(
                         color = MaterialTheme.colorScheme.secondary,
-                        cornerSize = CornerSize(32.dp),
+                        cornerSize = CornerSize(SliderTrackRoundedCorner),
                     )
                     .then(if (viewModel.showMirror) Modifier.drawInOverlay() else Modifier)
                     .sliderBackground(containerColor)
@@ -234,8 +381,38 @@
                         }
                         false
                     },
-            formatter = viewModel::formatValue,
             hapticsViewModelFactory = viewModel.hapticsViewModelFactory,
+            overriddenByAppState = overriddenByAppState,
+            showToast = {
+                viewModel.showToast(context, R.string.quick_settings_brightness_unable_adjust_msg)
+            },
         )
     }
 }
+
+private object Dimensions {
+    val SliderBackgroundFrameSize = DpSize(10.dp, 6.dp)
+    val SliderBackgroundRoundedCorner = 24.dp
+    val SliderTrackRoundedCorner = 12.dp
+    val IconSize = DpSize(28.dp, 28.dp)
+    val IconPadding = 6.dp
+    val ThumbTrackGapSize = 6.dp
+}
+
+private object AnimationSpecs {
+    val IconAppearSpec = tween<Float>(durationMillis = 100, delayMillis = 33)
+    val IconDisappearSpec = tween<Float>(durationMillis = 50)
+}
+
+private suspend fun Animatable<Float, AnimationVector1D>.appear() =
+    animateTo(targetValue = 1f, animationSpec = IconAppearSpec)
+
+private suspend fun Animatable<Float, AnimationVector1D>.disappear() =
+    animateTo(targetValue = 0f, animationSpec = IconDisappearSpec)
+
+@VisibleForTesting
+object BrightnessSliderMotionTestKeys {
+    val AnimatingIcon = MotionTestValueKey<Boolean>("animatingIcon")
+    val ActiveIconAlpha = MotionTestValueKey<Float>("activeIconAlpha")
+    val InactiveIconAlpha = MotionTestValueKey<Float>("inactiveIconAlpha")
+}
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt
index 7df7155..ed1cef3 100644
--- a/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt
@@ -17,6 +17,8 @@
 package com.android.systemui.brightness.ui.viewmodel
 
 import android.content.Context
+import androidx.annotation.DrawableRes
+import androidx.annotation.FloatRange
 import androidx.annotation.StringRes
 import androidx.compose.runtime.getValue
 import com.android.systemui.brightness.domain.interactor.BrightnessPolicyEnforcementInteractor
@@ -24,9 +26,9 @@
 import com.android.systemui.brightness.shared.model.GammaBrightness
 import com.android.systemui.classifier.Classifier
 import com.android.systemui.classifier.domain.interactor.FalsingInteractor
-import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.common.shared.model.Text
+import com.android.systemui.common.shared.model.asIcon
+import com.android.systemui.graphics.ImageLoader
 import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.lifecycle.Hydrator
@@ -57,6 +59,7 @@
     private val falsingInteractor: FalsingInteractor,
     @Assisted private val supportsMirroring: Boolean,
     private val brightnessWarningToast: BrightnessWarningToast,
+    private val imageLoader: ImageLoader,
 ) : ExclusiveActivatable() {
 
     private val hydrator = Hydrator("BrightnessSliderViewModel.hydrator")
@@ -64,17 +67,13 @@
     val currentBrightness by
         hydrator.hydratedStateOf(
             "currentBrightness",
-            GammaBrightness(0),
+            initialValue,
             screenBrightnessInteractor.gammaBrightness,
         )
 
     val maxBrightness = screenBrightnessInteractor.maxGammaBrightness
     val minBrightness = screenBrightnessInteractor.minGammaBrightness
 
-    val label = Text.Resource(R.string.quick_settings_brightness_dialog_title)
-
-    val icon = Icon.Resource(R.drawable.ic_brightness_full, ContentDescription.Resource(label.res))
-
     val policyRestriction = brightnessPolicyEnforcementInteractor.brightnessPolicyRestriction
 
     fun showPolicyRestrictionDialog(restriction: PolicyRestriction.Restricted) {
@@ -94,6 +93,16 @@
         falsingInteractor.isFalseTouch(Classifier.BRIGHTNESS_SLIDER)
     }
 
+    suspend fun loadImage(@DrawableRes resId: Int, context: Context): Icon.Loaded {
+        return imageLoader
+            .loadDrawable(
+                android.graphics.drawable.Icon.createWithResource(context, resId),
+                maxHeight = 200,
+                maxWidth = 200,
+            )!!
+            .asIcon(null, resId)
+    }
+
     /**
      * As a brightness slider is dragged, the corresponding events should be sent using this method.
      */
@@ -104,18 +113,6 @@
         }
     }
 
-    /**
-     * Format the current value of brightness as a percentage between the minimum and maximum gamma.
-     */
-    fun formatValue(value: Int): String {
-        val min = minBrightness.value
-        val max = maxBrightness.value
-        val coercedValue = value.coerceIn(min, max)
-        val percentage = (coercedValue - min) * 100 / (max - min)
-        // This is not finalized UI so using fixed string
-        return "$percentage%"
-    }
-
     fun setIsDragging(dragging: Boolean) {
         brightnessMirrorShowingInteractor.setMirrorShowing(dragging && supportsMirroring)
     }
@@ -131,6 +128,26 @@
     interface Factory {
         fun create(supportsMirroring: Boolean): BrightnessSliderViewModel
     }
+
+    companion object {
+        val initialValue = GammaBrightness(-1)
+
+        private val icons =
+            BrightnessIcons(
+                brightnessLow = R.drawable.ic_brightness_low,
+                brightnessMid = R.drawable.ic_brightness_medium,
+                brightnessHigh = R.drawable.ic_brightness_full,
+            )
+
+        @DrawableRes
+        fun getIconForPercentage(@FloatRange(0.0, 100.0) percentage: Float): Int {
+            return when {
+                percentage <= 20f -> icons.brightnessLow
+                percentage >= 80f -> icons.brightnessHigh
+                else -> icons.brightnessMid
+            }
+        }
+    }
 }
 
 fun BrightnessSliderViewModel.Factory.create() = create(supportsMirroring = true)
@@ -143,3 +160,9 @@
 
     @JvmInline value class Stopped(override val brightness: GammaBrightness) : Drag
 }
+
+private data class BrightnessIcons(
+    @DrawableRes val brightnessLow: Int,
+    @DrawableRes val brightnessMid: Int,
+    @DrawableRes val brightnessHigh: Int,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt
index 8ddd1ed..f01a6db 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.kt
@@ -47,6 +47,7 @@
 import com.android.systemui.scene.shared.model.SceneContainerConfig
 import com.android.systemui.scene.shared.model.SceneDataSource
 import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
+import com.android.systemui.scene.ui.composable.ConstantSceneContainerTransitionsBuilder
 import dagger.Binds
 import dagger.Module
 import dagger.Provides
@@ -114,9 +115,9 @@
                 SceneContainerConfig(
                     sceneKeys = listOf(CommunalScenes.Blank, CommunalScenes.Communal),
                     initialSceneKey = CommunalScenes.Blank,
-                    transitions = sceneTransitions,
                     navigationDistances =
                         mapOf(CommunalScenes.Blank to 0, CommunalScenes.Communal to 1),
+                    transitionsBuilder = ConstantSceneContainerTransitionsBuilder(sceneTransitions),
                 )
             return SceneDataSourceDelegator(applicationScope, config)
         }
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 75f0bad..31ffbbd 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
@@ -22,15 +22,24 @@
  * The widget categories to display on communal hub (where categories is a bitfield with values that
  * match those in {@link AppWidgetProviderInfo}).
  */
-@JvmInline
-value class CommunalWidgetCategories(val categories: Int = defaultCategories) {
-    fun contains(category: Int) = (categories and category) == category
+object CommunalWidgetCategories {
+    /**
+     * Categories that are allowed on communal hub.
+     * - Use "or" operator for including multiple categories.
+     */
+    val includedCategories: Int
+        get() {
+            return AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN or
+                AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD
+        }
 
-    companion object {
-        val defaultCategories: Int
-            get() {
-                return AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD or
-                    AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN
-            }
-    }
+    /**
+     * Categories to further filter included widgets by excluding certain opt-out categories.
+     * - WIDGET_CATEGORY_NOT_KEYGUARD: widgets opted out of displaying on keyguard like surfaces.
+     * - Use "and" operator for excluding multiple opt-out categories.
+     */
+    val excludedCategories: Int
+        get() {
+            return AppWidgetProviderInfo.WIDGET_CATEGORY_NOT_KEYGUARD.inv()
+        }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt
index 643d185..8b63227 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt
@@ -16,7 +16,9 @@
 
 package com.android.systemui.communal.data.repository
 
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.OverlayKey
 import com.android.compose.animation.scene.SceneKey
 import com.android.compose.animation.scene.TransitionKey
 import com.android.systemui.communal.dagger.Communal
@@ -25,16 +27,17 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.scene.shared.model.SceneDataSource
+import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 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.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.stateIn
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 /** Encapsulates the state of communal mode. */
 interface CommunalSceneRepository {
@@ -52,6 +55,9 @@
     /** Immediately snaps to the desired scene. */
     fun snapToScene(toScene: SceneKey)
 
+    /** Shows the hub from a power button press. */
+    suspend fun showHubFromPowerButton()
+
     /**
      * Updates the transition state of the hub [SceneTransitionLayout].
      *
@@ -67,6 +73,7 @@
     @Application private val applicationScope: CoroutineScope,
     @Background backgroundScope: CoroutineScope,
     @Communal private val sceneDataSource: SceneDataSource,
+    @Communal private val delegator: SceneDataSourceDelegator,
 ) : CommunalSceneRepository {
 
     override val currentScene: StateFlow<SceneKey> = sceneDataSource.currentScene
@@ -98,6 +105,18 @@
         }
     }
 
+    override suspend fun showHubFromPowerButton() {
+        // If keyguard is not showing yet, the hub view is not ready and the
+        // [SceneDataSourceDelegator] will still be using the default [NoOpSceneDataSource]
+        // and initial key, which is Blank. This means that when the hub container loads, it
+        // will default to not showing the hub. Attempting to set the scene in this state
+        // is simply ignored by the [NoOpSceneDataSource]. Instead, we temporarily override
+        // it with a new one that defaults to Communal. This delegate will be overwritten
+        // once the [CommunalContainer] loads.
+        // TODO(b/392969914): show the hub first instead of forcing the scene.
+        delegator.setDelegate(NoOpSceneDataSource(CommunalScenes.Communal))
+    }
+
     /**
      * Updates the transition state of the hub [SceneTransitionLayout].
      *
@@ -106,4 +125,27 @@
     override fun setTransitionState(transitionState: Flow<ObservableTransitionState>?) {
         _transitionState.value = transitionState
     }
+
+    /** Noop implementation of a scene data source that always returns the initial [SceneKey]. */
+    private class NoOpSceneDataSource(initialSceneKey: SceneKey) : SceneDataSource {
+        override val currentScene: StateFlow<SceneKey> =
+            MutableStateFlow(initialSceneKey).asStateFlow()
+
+        override val currentOverlays: StateFlow<Set<OverlayKey>> =
+            MutableStateFlow(emptySet<OverlayKey>()).asStateFlow()
+
+        override fun changeScene(toScene: SceneKey, transitionKey: TransitionKey?) = Unit
+
+        override fun snapToScene(toScene: SceneKey) = Unit
+
+        override fun showOverlay(overlay: OverlayKey, transitionKey: TransitionKey?) = Unit
+
+        override fun hideOverlay(overlay: OverlayKey, transitionKey: TransitionKey?) = Unit
+
+        override fun replaceOverlay(
+            from: OverlayKey,
+            to: OverlayKey,
+            transitionKey: TransitionKey?,
+        ) = Unit
+    }
 }
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 abd1016..4c291a0 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
@@ -111,6 +111,18 @@
     @Named(DEFAULT_BACKGROUND_TYPE) private val defaultBackgroundType: CommunalBackgroundType,
 ) : CommunalSettingsRepository {
 
+    private val dreamsActivatedOnSleepByDefault by lazy {
+        resources.getBoolean(com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault)
+    }
+
+    private val dreamsActivatedOnDockByDefault by lazy {
+        resources.getBoolean(com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault)
+    }
+
+    private val dreamsActivatedOnPosturedByDefault by lazy {
+        resources.getBoolean(com.android.internal.R.bool.config_dreamsActivatedOnPosturedByDefault)
+    }
+
     override fun getFlagEnabled(): Boolean {
         return if (getV2FlagEnabled()) {
             true
@@ -178,27 +190,27 @@
             .emitOnStart()
             .map {
                 if (
-                    secureSettings.getIntForUser(
+                    secureSettings.getBoolForUser(
                         Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
-                        0,
+                        dreamsActivatedOnSleepByDefault,
                         user.id,
-                    ) == 1
+                    )
                 ) {
                     WhenToDream.WHILE_CHARGING
                 } else if (
-                    secureSettings.getIntForUser(
+                    secureSettings.getBoolForUser(
                         Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
-                        0,
+                        dreamsActivatedOnDockByDefault,
                         user.id,
-                    ) == 1
+                    )
                 ) {
                     WhenToDream.WHILE_DOCKED
                 } else if (
-                    secureSettings.getIntForUser(
+                    secureSettings.getBoolForUser(
                         Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED,
-                        0,
+                        dreamsActivatedOnPosturedByDefault,
                         user.id,
-                    ) == 1
+                    )
                 ) {
                     WhenToDream.WHILE_POSTURED
                 } else {
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 237a19c..de55c92 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
@@ -545,10 +545,16 @@
         }
 
     /** CTA tile to be displayed in the glanceable hub (view mode). */
-    val ctaTileContent: Flow<List<CommunalContentModel.CtaTileInViewMode>> =
-        communalPrefsInteractor.isCtaDismissed.map { isDismissed ->
-            if (isDismissed) emptyList() else listOf(CommunalContentModel.CtaTileInViewMode())
+    val ctaTileContent: Flow<List<CommunalContentModel.CtaTileInViewMode>> by lazy {
+        if (communalSettingsInteractor.isV2FlagEnabled()) {
+            flowOf(listOf<CommunalContentModel.CtaTileInViewMode>())
+        } else {
+            communalPrefsInteractor.isCtaDismissed.map { isDismissed ->
+                if (isDismissed) listOf<CommunalContentModel.CtaTileInViewMode>()
+                else listOf(CommunalContentModel.CtaTileInViewMode())
+            }
         }
+    }
 
     /** A list of tutorial content to be displayed in the communal hub in tutorial mode. */
     val tutorialContent: List<CommunalContentModel.Tutorial> =
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 4764932..3d9e930 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
@@ -148,6 +148,29 @@
         }
     }
 
+    fun showHubFromPowerButton() {
+        val loggingReason = "showing hub from power button"
+        applicationScope.launch("$TAG#showHubFromPowerButton") {
+            if (SceneContainerFlag.isEnabled) {
+                sceneInteractor.changeScene(
+                    toScene = CommunalScenes.Communal.toSceneContainerSceneKey(),
+                    loggingReason = loggingReason,
+                )
+                return@launch
+            }
+
+            if (currentScene.value == CommunalScenes.Communal) return@launch
+            logger.logSceneChangeRequested(
+                from = currentScene.value,
+                to = CommunalScenes.Communal,
+                reason = loggingReason,
+                isInstant = true,
+            )
+            notifyListeners(CommunalScenes.Communal, null)
+            repository.showHubFromPowerButton()
+        }
+    }
+
     private fun notifyListeners(newScene: SceneKey, keyguardState: KeyguardState?) {
         onSceneAboutToChangeListener.forEach { it.onSceneAboutToChange(newScene, keyguardState) }
     }
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 099a859..49003a7 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
@@ -45,7 +45,7 @@
     val mediaHost: MediaHost,
     val mediaCarouselController: MediaCarouselController,
 ) {
-    val currentScene: Flow<SceneKey> = communalSceneInteractor.currentScene
+    val currentScene: StateFlow<SceneKey> = communalSceneInteractor.currentScene
 
     /** Used to animate showing or hiding the communal content. */
     open val isCommunalContentVisible: Flow<Boolean> = MutableStateFlow(false)
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 52bf000..8aba111 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
@@ -241,8 +241,9 @@
             )
             putExtra(
                 AppWidgetManager.EXTRA_CATEGORY_FILTER,
-                CommunalWidgetCategories.defaultCategories,
+                CommunalWidgetCategories.includedCategories,
             )
+            putExtra(EXTRA_CATEGORY_EXCLUSION_FILTER, CommunalWidgetCategories.excludedCategories)
 
             communalSettingsInteractor.workProfileUserDisallowedByDevicePolicy.value?.let {
                 putExtra(EXTRA_USER_ID_FILTER, arrayListOf(it.id))
@@ -281,6 +282,7 @@
 
         private const val EXTRA_DESIRED_WIDGET_WIDTH = "desired_widget_width"
         private const val EXTRA_DESIRED_WIDGET_HEIGHT = "desired_widget_height"
+        private const val EXTRA_CATEGORY_EXCLUSION_FILTER = "category_exclusion_filter"
         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"
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModel.kt
index e35fdfe..29d9cac 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModel.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.shade.ui.viewmodel.dualShadeActions
 import com.android.systemui.shade.ui.viewmodel.singleShadeActions
@@ -41,6 +42,7 @@
 constructor(
     private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
     private val shadeInteractor: ShadeInteractor,
+    private val shadeModeInteractor: ShadeModeInteractor,
 ) : UserActionsViewModel() {
 
     override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
@@ -51,7 +53,7 @@
                 } else {
                     combine(
                         deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked },
-                        shadeInteractor.shadeMode,
+                        shadeModeInteractor.shadeMode,
                     ) { isDeviceUnlocked, shadeMode ->
                         buildList {
                                 val bouncerOrGone =
diff --git a/packages/SystemUI/src/com/android/systemui/complication/DreamClockTimeComplication.java b/packages/SystemUI/src/com/android/systemui/complication/DreamClockTimeComplication.java
index c709e34..8e6848a 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/DreamClockTimeComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/DreamClockTimeComplication.java
@@ -16,10 +16,13 @@
 
 package com.android.systemui.complication;
 
+import static android.text.format.DateFormat.getBestDateTimePattern;
+
 import static com.android.systemui.complication.dagger.DreamClockTimeComplicationComponent.DreamClockTimeComplicationModule.DREAM_CLOCK_TIME_COMPLICATION_VIEW;
 import static com.android.systemui.complication.dagger.RegisteredComplicationsModule.DREAM_CLOCK_TIME_COMPLICATION_LAYOUT_PARAMS;
 
 import android.view.View;
+import android.widget.TextClock;
 
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.CoreStartable;
@@ -92,18 +95,24 @@
      * {@link ViewHolder} to contain value/logic associated with {@link DreamClockTimeComplication}.
      */
     public static class DreamClockTimeViewHolder implements ViewHolder {
-        private final View mView;
+        private final TextClock mView;
         private final ComplicationLayoutParams mLayoutParams;
 
         @Inject
         DreamClockTimeViewHolder(
-                @Named(DREAM_CLOCK_TIME_COMPLICATION_VIEW) View view,
+                @Named(DREAM_CLOCK_TIME_COMPLICATION_VIEW) TextClock view,
                 @Named(DREAM_CLOCK_TIME_COMPLICATION_LAYOUT_PARAMS)
                         ComplicationLayoutParams layoutParams,
                 DreamClockTimeViewController viewController) {
             mView = view;
             mLayoutParams = layoutParams;
             viewController.init();
+
+            // Support localized AM/PM marker for 12h mode in content description.
+            String formatSkeleton = view.is24HourModeEnabled() ? "Hm" : "hm";
+            String pattern = getBestDateTimePattern(view.getTextLocale(), formatSkeleton);
+            view.setContentDescriptionFormat12Hour(pattern);
+            view.setContentDescriptionFormat24Hour(pattern);
         }
 
         @Override
@@ -122,7 +131,7 @@
 
         @Inject
         DreamClockTimeViewController(
-                @Named(DREAM_CLOCK_TIME_COMPLICATION_VIEW) View view,
+                @Named(DREAM_CLOCK_TIME_COMPLICATION_VIEW) TextClock view,
                 UiEventLogger uiEventLogger) {
             super(view);
 
diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamClockTimeComplicationComponent.kt b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamClockTimeComplicationComponent.kt
index 4b9ac1d..9d367c9 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamClockTimeComplicationComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/complication/dagger/DreamClockTimeComplicationComponent.kt
@@ -18,7 +18,6 @@
 package com.android.systemui.complication.dagger
 
 import android.view.LayoutInflater
-import android.view.View
 import android.widget.TextClock
 import com.android.internal.util.Preconditions
 import com.android.systemui.Flags
@@ -64,7 +63,7 @@
             @Provides
             @DreamClockTimeComplicationScope
             @Named(DREAM_CLOCK_TIME_COMPLICATION_VIEW)
-            fun provideComplicationView(layoutInflater: LayoutInflater): View {
+            fun provideComplicationView(layoutInflater: LayoutInflater): TextClock {
                 val view =
                     Preconditions.checkNotNull(
                         layoutInflater.inflate(
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt
index a5f29aa..f3eff60 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt
@@ -122,7 +122,7 @@
 
     init {
         Log.d(TAG, "Initializing")
-        dumpManager.registerDumpable(TAG, this)
+        dumpManager.registerNormalDumpable(TAG, this)
         serviceListing.addCallback(serviceListingCallback)
         serviceListing.setListening(true)
         serviceListing.reload()
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 5b68597..5fc924b1 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
@@ -16,7 +16,6 @@
 
 package com.android.systemui.deviceentry.domain.interactor
 
-import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.internal.policy.IKeyguardDismissCallback
 import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
@@ -36,11 +35,9 @@
 import com.android.systemui.utils.coroutines.flow.mapLatestConflated
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.filter
@@ -285,32 +282,7 @@
     }
 
     /** Locks the device instantly. */
-    fun lockNow() {
-        deviceUnlockedInteractor.lockNow()
-    }
-
-    suspend fun hydrateTableLogBuffer(tableLogBuffer: TableLogBuffer) {
-        coroutineScope {
-            launch {
-                isDeviceEntered
-                    .logDiffsForTable(
-                        tableLogBuffer = tableLogBuffer,
-                        columnName = "isDeviceEntered",
-                        initialValue = isDeviceEntered.value,
-                    )
-                    .collect()
-            }
-
-            launch {
-                canSwipeToEnter
-                    .map { it?.toString() ?: "" }
-                    .logDiffsForTable(
-                        tableLogBuffer = tableLogBuffer,
-                        columnName = "canSwipeToEnter",
-                        initialValue = canSwipeToEnter.value?.toString() ?: "",
-                    )
-                    .collect()
-            }
-        }
+    fun lockNow(debuggingReason: String) {
+        deviceUnlockedInteractor.lockNow(debuggingReason)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt
index b1be9a2..c6ae353 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt
@@ -59,6 +59,7 @@
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.merge
 import kotlinx.coroutines.flow.receiveAsFlow
@@ -70,7 +71,7 @@
 constructor(
     private val authenticationInteractor: AuthenticationInteractor,
     private val repository: DeviceEntryRepository,
-    trustInteractor: TrustInteractor,
+    private val trustInteractor: TrustInteractor,
     faceAuthInteractor: DeviceEntryFaceAuthInteractor,
     fingerprintAuthInteractor: DeviceEntryFingerprintAuthInteractor,
     private val powerInteractor: PowerInteractor,
@@ -181,7 +182,8 @@
     val deviceUnlockStatus: StateFlow<DeviceUnlockStatus> =
         repository.deviceUnlockStatus.asStateFlow()
 
-    private val lockNowRequests = Channel<Unit>()
+    /** A [Channel] of "lock now" requests where the values are the debugging reasons. */
+    private val lockNowRequests = Channel<String>()
 
     override suspend fun onActivated(): Nothing {
         coroutineScope {
@@ -218,8 +220,8 @@
     }
 
     /** Locks the device instantly. */
-    fun lockNow() {
-        lockNowRequests.trySend(Unit)
+    fun lockNow(debuggingReason: String) {
+        lockNowRequests.trySend(debuggingReason)
     }
 
     private suspend fun handleLockAndUnlockEvents() {
@@ -244,47 +246,70 @@
 
     private suspend fun handleLockEvents() {
         merge(
-                // Device wakefulness events.
-                powerInteractor.detailedWakefulness
-                    .map { Pair(it.isAsleep(), it.lastSleepReason) }
-                    .distinctUntilChangedBy { it.first }
-                    .map { (isAsleep, lastSleepReason) ->
-                        if (isAsleep) {
-                            if (
-                                (lastSleepReason == WakeSleepReason.POWER_BUTTON) &&
-                                    authenticationInteractor.getPowerButtonInstantlyLocks()
-                            ) {
-                                LockImmediately("locked instantly from power button")
-                            } else if (lastSleepReason == WakeSleepReason.SLEEP_BUTTON) {
-                                LockImmediately("locked instantly from sleep button")
-                            } else {
-                                LockWithDelay("entering sleep")
-                            }
-                        } else {
-                            CancelDelayedLock("waking up")
-                        }
-                    },
+                trustInteractor.isTrusted.flatMapLatestConflated { isTrusted ->
+                    if (isTrusted) {
+                        // When entering a trusted environment, power-related lock events are
+                        // ignored.
+                        Log.d(TAG, "In trusted environment, ignoring power-related lock events")
+                        flowOf(CancelDelayedLock("in trusted environment"))
+                    } else {
+                        // When not in a trusted environment, power-related lock events are treated
+                        // as normal.
+                        Log.d(
+                            TAG,
+                            "Not in trusted environment, power-related lock events treated as" +
+                                " normal",
+                        )
+                        merge(
+                            // Device wakefulness events.
+                            powerInteractor.detailedWakefulness
+                                .map { Pair(it.isAsleep(), it.lastSleepReason) }
+                                .distinctUntilChangedBy { it.first }
+                                .map { (isAsleep, lastSleepReason) ->
+                                    if (isAsleep) {
+                                        if (
+                                            (lastSleepReason == WakeSleepReason.POWER_BUTTON) &&
+                                                authenticationInteractor
+                                                    .getPowerButtonInstantlyLocks()
+                                        ) {
+                                            LockImmediately("locked instantly from power button")
+                                        } else if (
+                                            lastSleepReason == WakeSleepReason.SLEEP_BUTTON
+                                        ) {
+                                            LockImmediately("locked instantly from sleep button")
+                                        } else {
+                                            LockWithDelay("entering sleep")
+                                        }
+                                    } else {
+                                        CancelDelayedLock("waking up")
+                                    }
+                                },
+                            // Started dreaming
+                            powerInteractor.isInteractive.flatMapLatestConflated { isInteractive ->
+                                // Only respond to dream state changes while the device is
+                                // interactive.
+                                if (isInteractive) {
+                                    keyguardInteractor.isDreamingAny.distinctUntilChanged().map {
+                                        isDreaming ->
+                                        if (isDreaming) {
+                                            LockWithDelay("started dreaming")
+                                        } else {
+                                            CancelDelayedLock("stopped dreaming")
+                                        }
+                                    }
+                                } else {
+                                    emptyFlow()
+                                }
+                            },
+                        )
+                    }
+                },
                 // Device enters lockdown.
                 isInLockdown
                     .distinctUntilChanged()
                     .filter { it }
                     .map { LockImmediately("lockdown") },
-                // Started dreaming
-                powerInteractor.isInteractive.flatMapLatestConflated { isInteractive ->
-                    // Only respond to dream state changes while the device is interactive.
-                    if (isInteractive) {
-                        keyguardInteractor.isDreamingAny.distinctUntilChanged().map { isDreaming ->
-                            if (isDreaming) {
-                                LockWithDelay("started dreaming")
-                            } else {
-                                CancelDelayedLock("stopped dreaming")
-                            }
-                        }
-                    } else {
-                        emptyFlow()
-                    }
-                },
-                lockNowRequests.receiveAsFlow().map { LockImmediately("lockNow") },
+                lockNowRequests.receiveAsFlow().map { reason -> LockImmediately(reason) },
             )
             .collectLatest(::onLockEvent)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt
index 160574fa..9ce2ce0 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.shade.ui.viewmodel.dualShadeActions
 import com.android.systemui.shade.ui.viewmodel.singleShadeActions
@@ -42,6 +43,7 @@
     private val communalInteractor: CommunalInteractor,
     private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
     private val shadeInteractor: ShadeInteractor,
+    private val shadeModeInteractor: ShadeModeInteractor,
 ) : UserActionsViewModel() {
 
     override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
@@ -53,7 +55,7 @@
                     combine(
                         deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked },
                         communalInteractor.isCommunalAvailable,
-                        shadeInteractor.shadeMode,
+                        shadeModeInteractor.shadeMode,
                     ) { isDeviceUnlocked, isCommunalAvailable, shadeMode ->
                         buildList {
                                 if (isCommunalAvailable) {
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt
index 8b0accd..6d2d4ca 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt
@@ -18,8 +18,10 @@
 
 import android.content.Context
 import androidx.datastore.core.DataStore
+import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
 import androidx.datastore.preferences.core.Preferences
 import androidx.datastore.preferences.core.edit
+import androidx.datastore.preferences.core.emptyPreferences
 import androidx.datastore.preferences.core.longPreferencesKey
 import androidx.datastore.preferences.preferencesDataStore
 import com.android.systemui.dagger.SysUISingleton
@@ -45,7 +47,12 @@
     ) : this(applicationContext, backgroundScope, dataStoreName = DATASTORE_NAME)
 
     private val Context.dataStore: DataStore<Preferences> by
-        preferencesDataStore(name = dataStoreName, scope = backgroundScope)
+        preferencesDataStore(
+            name = dataStoreName,
+            corruptionHandler =
+                ReplaceFileCorruptionHandler(produceNewData = { emptyPreferences() }),
+            scope = backgroundScope,
+        )
 
     suspend fun setScheduledTutorialLaunchTime(device: DeviceType, time: Instant) {
         updateData(key = getLaunchedKey(device), value = time.epochSecond)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 1d36076..c1a59f1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -671,7 +671,7 @@
             checkPermission();
 
             if (SceneContainerFlag.isEnabled()) {
-                mDeviceEntryInteractorLazy.get().lockNow();
+                mDeviceEntryInteractorLazy.get().lockNow("doKeyguardTimeout");
             } else if (KeyguardWmStateRefactor.isEnabled()) {
                 mKeyguardServiceLockNowInteractor.onKeyguardServiceDoKeyguardTimeout(options);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
index df3633be..869edfa 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
@@ -29,12 +29,14 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
 import com.android.systemui.keyguard.domain.interactor.WallpaperFocalAreaInteractor
 import com.android.systemui.keyguard.ui.binder.KeyguardBlueprintViewBinder
+import com.android.systemui.keyguard.ui.binder.KeyguardJankBinder
 import com.android.systemui.keyguard.ui.binder.KeyguardRootViewBinder
 import com.android.systemui.keyguard.ui.binder.LightRevealScrimViewBinder
 import com.android.systemui.keyguard.ui.view.KeyguardIndicationArea
 import com.android.systemui.keyguard.ui.view.KeyguardRootView
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBlueprintViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardJankViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel
 import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel
@@ -65,6 +67,7 @@
 constructor(
     private val keyguardRootView: KeyguardRootView,
     private val keyguardRootViewModel: KeyguardRootViewModel,
+    private val keyguardJankViewModel: KeyguardJankViewModel,
     private val screenOffAnimationController: ScreenOffAnimationController,
     private val occludingAppDeviceEntryMessageViewModel: OccludingAppDeviceEntryMessageViewModel,
     private val chipbarCoordinator: ChipbarCoordinator,
@@ -93,9 +96,11 @@
 ) : CoreStartable {
 
     private var rootViewHandle: DisposableHandle? = null
+    private var jankHandle: DisposableHandle? = null
 
     override fun start() {
         bindKeyguardRootView()
+        bindJankViewModel()
         initializeViews()
 
         if (lightRevealMigration()) {
@@ -145,11 +150,9 @@
                 clockInteractor,
                 wallpaperFocalAreaInteractor,
                 keyguardClockViewModel,
-                interactionJankMonitor,
                 deviceEntryHapticsInteractor,
                 vibratorHelper,
                 falsingManager,
-                keyguardViewMediator,
                 statusBarKeyguardViewManager,
                 mainDispatcher,
                 msdlPlayer,
@@ -157,5 +160,22 @@
             )
     }
 
+    private fun bindJankViewModel() {
+        if (SceneContainerFlag.isEnabled) {
+            return
+        }
+
+        jankHandle?.dispose()
+        jankHandle =
+            KeyguardJankBinder.bind(
+                keyguardRootView,
+                keyguardJankViewModel,
+                interactionJankMonitor,
+                clockInteractor,
+                keyguardViewMediator,
+                mainDispatcher,
+            )
+    }
+
     fun getKeyguardRootView() = keyguardRootView
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 5baef91..372fdca 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard;
 
+import static android.app.KeyguardManager.LOCK_ON_USER_SWITCH_CALLBACK;
 import static android.app.StatusBarManager.SESSION_KEYGUARD;
 import static android.provider.Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT;
 import static android.provider.Settings.System.LOCKSCREEN_SOUNDS_ENABLED;
@@ -75,6 +76,7 @@
 import android.os.DeadObjectException;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.IRemoteCallback;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
@@ -190,6 +192,8 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
@@ -271,6 +275,9 @@
     private static final int SYSTEM_READY = 18;
     private static final int CANCEL_KEYGUARD_EXIT_ANIM = 19;
     private static final int BOOT_INTERACTOR = 20;
+    private static final int BEFORE_USER_SWITCHING = 21;
+    private static final int USER_SWITCHING = 22;
+    private static final int USER_SWITCH_COMPLETE = 23;
 
     /** Enum for reasons behind updating wakeAndUnlock state. */
     @Retention(RetentionPolicy.SOURCE)
@@ -288,6 +295,8 @@
         int WAKE_AND_UNLOCK = 3;
     }
 
+    private final List<LockNowCallback> mLockNowCallbacks = new ArrayList<>();
+
     /**
      * The default amount of time we stay awake (used for all key input)
      */
@@ -345,6 +354,11 @@
     private final ScreenOffAnimationController mScreenOffAnimationController;
     private final Lazy<NotificationShadeDepthController> mNotificationShadeDepthController;
     private final Lazy<ShadeController> mShadeController;
+    /*
+     * Records the user id on request to go away, for validation when WM calls back to start the
+     * exit animation.
+     */
+    private int mGoingAwayRequestedForUserId = -1;
 
     private boolean mSystemReady;
     private boolean mBootCompleted;
@@ -352,7 +366,6 @@
     private boolean mShuttingDown;
     private boolean mDozing;
     private boolean mAnimatingScreenOff;
-    private boolean mIgnoreDismiss;
     private final Context mContext;
     private final FalsingCollector mFalsingCollector;
 
@@ -615,6 +628,78 @@
                 }
             };
 
+    @VisibleForTesting
+    protected UserTracker.Callback mUserChangedCallback = new UserTracker.Callback() {
+
+        @Override
+        public void onBeforeUserSwitching(int newUser, @NonNull Runnable resultCallback) {
+            mHandler.sendMessage(mHandler.obtainMessage(BEFORE_USER_SWITCHING,
+                    newUser, 0, resultCallback));
+        }
+
+        @Override
+        public void onUserChanging(int newUser, @NonNull Context userContext,
+                @NonNull Runnable resultCallback) {
+            mHandler.sendMessage(mHandler.obtainMessage(USER_SWITCHING,
+                    newUser, 0, resultCallback));
+        }
+
+        @Override
+        public void onUserChanged(int newUser, Context userContext) {
+            mHandler.sendMessage(mHandler.obtainMessage(USER_SWITCH_COMPLETE,
+                    newUser, 0));
+        }
+    };
+
+    /**
+     * Handle {@link #BEFORE_USER_SWITCHING}
+     */
+    @VisibleForTesting
+    void handleBeforeUserSwitching(int userId, Runnable resultCallback) {
+        Log.d(TAG, String.format("onBeforeUserSwitching %d", userId));
+        synchronized (KeyguardViewMediator.this) {
+            mHandler.removeMessages(DISMISS);
+            notifyTrustedChangedLocked(mUpdateMonitor.getUserHasTrust(userId));
+            resetKeyguardDonePendingLocked();
+            adjustStatusBarLocked();
+            mKeyguardStateController.notifyKeyguardGoingAway(false);
+            if (mLockPatternUtils.isSecure(userId) && !mShowing) {
+                doKeyguardLocked(null);
+            } else {
+                resetStateLocked();
+            }
+            resultCallback.run();
+        }
+    }
+
+    /**
+     * Handle {@link #USER_SWITCHING}
+     */
+    @VisibleForTesting
+    void handleUserSwitching(int userId, Runnable resultCallback) {
+        Log.d(TAG, String.format("onUserSwitching %d", userId));
+        synchronized (KeyguardViewMediator.this) {
+            if (!mLockPatternUtils.isSecure(userId)) {
+                dismiss(null, null);
+            }
+            resultCallback.run();
+        }
+    }
+
+    /**
+     * Handle {@link #USER_SWITCH_COMPLETE}
+     */
+    @VisibleForTesting
+    void handleUserSwitchComplete(int userId) {
+        Log.d(TAG, String.format("onUserSwitchComplete %d", userId));
+        // Calling dismiss on a secure user will show the bouncer
+        if (mLockPatternUtils.isSecure(userId)) {
+            // We are calling dismiss with a delay as there are race conditions in some scenarios
+            // caused by async layout listeners
+            mHandler.postDelayed(() -> dismiss(null /* callback */, null /* message */), 500);
+        }
+    }
+
     KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
 
         @Override
@@ -631,27 +716,6 @@
         }
 
         @Override
-        public void onUserSwitching(int userId) {
-            Log.d(TAG, String.format("onUserSwitching %d", userId));
-            synchronized (KeyguardViewMediator.this) {
-                mIgnoreDismiss = true;
-                notifyTrustedChangedLocked(mUpdateMonitor.getUserHasTrust(userId));
-                resetKeyguardDonePendingLocked();
-                resetStateLocked();
-                adjustStatusBarLocked();
-            }
-        }
-
-        @Override
-        public void onUserSwitchComplete(int userId) {
-            mIgnoreDismiss = false;
-            Log.d(TAG, String.format("onUserSwitchComplete %d", userId));
-            // We are calling dismiss with a delay as there are race conditions in some scenarios
-            // caused by async layout listeners
-            mHandler.postDelayed(() -> dismiss(null /* callback */, null /* message */), 500);
-        }
-
-        @Override
         public void onDeviceProvisioned() {
             sendUserPresentBroadcast();
         }
@@ -1658,7 +1722,13 @@
                 com.android.internal.R.anim.lock_screen_behind_enter);
 
         mWorkLockController = new WorkLockActivityController(mContext, mUserTracker);
-
+        mUserTracker.addCallback(mUserChangedCallback, mContext.getMainExecutor());
+        // start() can be invoked in the middle of user switching, so check for this state and issue
+        // the call manually as that important event was missed.
+        if (mUserTracker.isUserSwitching()) {
+            handleBeforeUserSwitching(mUserTracker.getUserId(), () -> {});
+            handleUserSwitching(mUserTracker.getUserId(), () -> {});
+        }
         mJavaAdapter.alwaysCollectFlow(
                 mWallpaperRepository.getWallpaperSupportsAmbientMode(),
                 this::setWallpaperSupportsAmbientMode);
@@ -1707,7 +1777,7 @@
             // System ready can be invoked in the middle of user switching, so check for this state
             // and issue the call manually as that important event was missed.
             if (mUserTracker.isUserSwitching()) {
-                mUpdateCallback.onUserSwitching(mUserTracker.getUserId());
+                mUserChangedCallback.onUserChanging(mUserTracker.getUserId(), mContext, () -> {});
             }
         }
         // Most services aren't available until the system reaches the ready state, so we
@@ -2341,12 +2411,23 @@
      * Enable the keyguard if the settings are appropriate.
      */
     private void doKeyguardLocked(Bundle options) {
+        int currentUserId = mSelectedUserInteractor.getSelectedUserId();
+        if (options != null && options.getBinder(LOCK_ON_USER_SWITCH_CALLBACK) != null) {
+            LockNowCallback callback = new LockNowCallback(currentUserId,
+                    IRemoteCallback.Stub.asInterface(
+                            options.getBinder(LOCK_ON_USER_SWITCH_CALLBACK)));
+            synchronized (mLockNowCallbacks) {
+                mLockNowCallbacks.add(callback);
+            }
+            Log.d(TAG, "LockNowCallback required for user: " + callback.mUserId);
+        }
+
         // if another app is disabling us, don't show
         if (!mExternallyEnabled
                 && !mLockPatternUtils.isUserInLockdown(
                         mSelectedUserInteractor.getSelectedUserId())) {
             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
-
+            notifyLockNowCallback();
             mNeedToReshowWhenReenabled = true;
             return;
         }
@@ -2364,6 +2445,7 @@
                     // We're removing "reset" in the refactor - "resetting" the views will happen
                     // as a reaction to the root cause of the "reset" signal.
                     if (KeyguardWmStateRefactor.isEnabled()) {
+                        notifyLockNowCallback();
                         return;
                     }
 
@@ -2376,6 +2458,7 @@
                                     + "previously hiding. It should be safe to short-circuit "
                                     + "here.");
                     resetStateLocked(/* hideBouncer= */ false);
+                    notifyLockNowCallback();
                     return;
                 }
             } else {
@@ -2402,6 +2485,7 @@
                 Log.d(TAG, "doKeyguard: not showing because device isn't provisioned and the sim is"
                         + " not locked or missing");
             }
+            notifyLockNowCallback();
             return;
         }
 
@@ -2409,6 +2493,7 @@
         if (mLockPatternUtils.isLockScreenDisabled(mSelectedUserInteractor.getSelectedUserId())
                 && !lockedOrMissing && !forceShow) {
             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
+            notifyLockNowCallback();
             return;
         }
 
@@ -2456,11 +2541,6 @@
     }
 
     public void dismiss(IKeyguardDismissCallback callback, CharSequence message) {
-        if (mIgnoreDismiss) {
-            android.util.Log.i(TAG, "Ignoring request to dismiss (user switch in progress?)");
-            return;
-        }
-
         if (mKeyguardStateController.isKeyguardGoingAway()) {
             Log.i(TAG, "Ignoring dismiss because we're already going away.");
             return;
@@ -2478,7 +2558,7 @@
     }
 
     private void resetStateLocked(boolean hideBouncer) {
-        if (DEBUG) Log.e(TAG, "resetStateLocked");
+        if (DEBUG) Log.d(TAG, "resetStateLocked");
         Message msg = mHandler.obtainMessage(RESET, hideBouncer ? 1 : 0, 0);
         mHandler.sendMessage(msg);
     }
@@ -2726,6 +2806,18 @@
                     message = "BOOT_INTERACTOR";
                     handleBootInteractor();
                     break;
+                case BEFORE_USER_SWITCHING:
+                    message = "BEFORE_USER_SWITCHING";
+                    handleBeforeUserSwitching(msg.arg1, (Runnable) msg.obj);
+                    break;
+                case USER_SWITCHING:
+                    message = "USER_SWITCHING";
+                    handleUserSwitching(msg.arg1, (Runnable) msg.obj);
+                    break;
+                case USER_SWITCH_COMPLETE:
+                    message = "USER_SWITCH_COMPLETE";
+                    handleUserSwitchComplete(msg.arg1);
+                    break;
             }
             Log.d(TAG, "KeyguardViewMediator queue processing message: " + message);
         }
@@ -2867,6 +2959,9 @@
         mUiBgExecutor.execute(() -> {
             Log.d(TAG, "updateActivityLockScreenState(" + showing + ", " + aodShowing + ", "
                     + reason + ")");
+            if (showing) {
+                notifyLockNowCallback();
+            }
 
             if (KeyguardWmStateRefactor.isEnabled()) {
                 // Handled in WmLockscreenVisibilityManager if flag is enabled.
@@ -2911,6 +3006,7 @@
         synchronized (KeyguardViewMediator.this) {
             if (!mSystemReady) {
                 if (DEBUG) Log.d(TAG, "ignoring handleShow because system is not ready.");
+                notifyLockNowCallback();
                 return;
             }
             if (DEBUG) Log.d(TAG, "handleShow");
@@ -2969,12 +3065,11 @@
         }
     }
 
-    private final Runnable mKeyguardGoingAwayRunnable = new Runnable() {
+    final Runnable mKeyguardGoingAwayRunnable = new Runnable() {
         @SuppressLint("MissingPermission")
         @Override
         public void run() {
             Trace.beginSection("KeyguardViewMediator.mKeyGuardGoingAwayRunnable");
-            Log.d(TAG, "keyguardGoingAwayRunnable");
             mKeyguardViewControllerLazy.get().keyguardGoingAway();
 
             int flags = 0;
@@ -3011,6 +3106,10 @@
 
             // Handled in WmLockscreenVisibilityManager if flag is enabled.
             if (!KeyguardWmStateRefactor.isEnabled()) {
+                mGoingAwayRequestedForUserId = mSelectedUserInteractor.getSelectedUserId();
+                Log.d(TAG, "keyguardGoingAway requested for userId: "
+                        + mGoingAwayRequestedForUserId);
+
                 // Don't actually hide the Keyguard at the moment, wait for window manager
                 // until it tells us it's safe to do so with startKeyguardExitAnimation.
                 // Posting to mUiOffloadThread to ensure that calls to ActivityTaskManager
@@ -3149,6 +3248,30 @@
             RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) {
         Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime
                 + " fadeoutDuration=" + fadeoutDuration);
+        int currentUserId = mSelectedUserInteractor.getSelectedUserId();
+        if (!KeyguardWmStateRefactor.isEnabled() && mGoingAwayRequestedForUserId != currentUserId) {
+            Log.e(TAG, "Not executing handleStartKeyguardExitAnimationInner() due to userId "
+                    + "mismatch. Requested: " + mGoingAwayRequestedForUserId + ", current: "
+                    + currentUserId);
+            if (finishedCallback != null) {
+                // There will not execute animation, send a finish callback to ensure the remote
+                // animation won't hang there.
+                try {
+                    finishedCallback.onAnimationFinished();
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Failed to call onAnimationFinished", e);
+                }
+            }
+            mHiding = false;
+            if (mLockPatternUtils.isSecure(currentUserId)) {
+                doKeyguardLocked(null);
+            } else {
+                resetStateLocked();
+                dismiss(null, null);
+            }
+            return;
+        }
+
         synchronized (KeyguardViewMediator.this) {
             mIsKeyguardExitAnimationCanceled = false;
             // Tell ActivityManager that we canceled the keyguard animation if
@@ -3393,6 +3516,13 @@
      * app transition before finishing the current RemoteAnimation, or the keyguard being re-shown).
      */
     private void handleCancelKeyguardExitAnimation() {
+        if (!KeyguardWmStateRefactor.isEnabled()
+                && mGoingAwayRequestedForUserId != mSelectedUserInteractor.getSelectedUserId()) {
+            Log.e(TAG, "Setting pendingLock = true due to userId mismatch. Requested: "
+                    + mGoingAwayRequestedForUserId + ", current: "
+                    + mSelectedUserInteractor.getSelectedUserId());
+            setPendingLock(true);
+        }
         if (mPendingLock) {
             Log.d(TAG, "#handleCancelKeyguardExitAnimation: keyguard exit animation cancelled. "
                     + "There's a pending lock, so we were cancelled because the device was locked "
@@ -3493,6 +3623,7 @@
         mSurfaceBehindRemoteAnimationRequested = true;
 
         if (ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS && !KeyguardWmStateRefactor.isEnabled()) {
+            mGoingAwayRequestedForUserId = mSelectedUserInteractor.getSelectedUserId();
             startKeyguardTransition(false /* keyguardShowing */, false /* aodShowing */);
             return;
         }
@@ -3513,6 +3644,9 @@
 
             if (!KeyguardWmStateRefactor.isEnabled()) {
                 // Handled in WmLockscreenVisibilityManager.
+                mGoingAwayRequestedForUserId = mSelectedUserInteractor.getSelectedUserId();
+                Log.d(TAG, "keyguardGoingAway requested for userId: "
+                        + mGoingAwayRequestedForUserId);
                 mActivityTaskManagerService.keyguardGoingAway(flags);
             }
         } catch (RemoteException e) {
@@ -3594,12 +3728,13 @@
             // windows that appear on top, ever
             int flags = StatusBarManager.DISABLE_NONE;
 
-            // TODO (b/155663717) After restart, status bar will not properly hide home button
+            // TODO(b/155663717): After restart, status bar will not properly hide home button
             //  unless disable is called to show un-hide it once first
             if (forceClearFlags) {
                 if (UserManager.isVisibleBackgroundUsersEnabled()
-                        && !mProcessWrapper.isSystemUser() && !mProcessWrapper.isForegroundUser()) {
-                    // TODO: b/341604160 - Support visible background users properly.
+                        && !mProcessWrapper.isSystemUser()
+                        && !mProcessWrapper.isForegroundUserOrProfile()) {
+                    // TODO(b/341604160): Support visible background users properly.
                     if (DEBUG) {
                         Log.d(TAG, "Status bar manager is disabled for visible background users");
                     }
@@ -3635,8 +3770,9 @@
 
             if (!SceneContainerFlag.isEnabled()) {
                 if (UserManager.isVisibleBackgroundUsersEnabled()
-                        && !mProcessWrapper.isSystemUser() && !mProcessWrapper.isForegroundUser()) {
-                    // TODO: b/341604160 - Support visible background users properly.
+                        && !mProcessWrapper.isSystemUser()
+                        && !mProcessWrapper.isForegroundUserOrProfile()) {
+                    // TODO(b/341604160): Support visible background users properly.
                     if (DEBUG) {
                         Log.d(TAG, "Status bar manager is disabled for visible background users");
                     }
@@ -3966,6 +4102,29 @@
         mUiBgExecutor.execute(mTrustManager::reportKeyguardShowingChanged);
     }
 
+    private void notifyLockNowCallback() {
+        List<LockNowCallback> callbacks;
+        synchronized (mLockNowCallbacks) {
+            callbacks = new ArrayList<LockNowCallback>(mLockNowCallbacks);
+            mLockNowCallbacks.clear();
+        }
+        Iterator<LockNowCallback> iter = callbacks.listIterator();
+        while (iter.hasNext()) {
+            LockNowCallback callback = iter.next();
+            iter.remove();
+            if (callback.mUserId != mSelectedUserInteractor.getSelectedUserId()) {
+                Log.i(TAG, "Not notifying lockNowCallback due to user mismatch");
+                continue;
+            }
+            Log.i(TAG, "Notifying lockNowCallback");
+            try {
+                callback.mRemoteCallback.sendResult(null);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Could not issue LockNowCallback sendResult", e);
+            }
+        }
+    }
+
     private void notifyTrustedChangedLocked(boolean trusted) {
         int size = mKeyguardStateCallbacks.size();
         for (int i = size - 1; i >= 0; i--) {
@@ -4130,4 +4289,14 @@
             }
         };
     }
+
+    private class LockNowCallback {
+        final int mUserId;
+        final IRemoteCallback mRemoteCallback;
+
+        LockNowCallback(int userId, IRemoteCallback remoteCallback) {
+            mUserId = userId;
+            mRemoteCallback = remoteCallback;
+        }
+    }
 }
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 3968b49..ad79177 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
@@ -24,7 +24,6 @@
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
-import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.res.R
 import com.android.systemui.settings.UserFileManager
@@ -49,7 +48,6 @@
     @ShadeDisplayAware private val context: Context,
     private val userFileManager: UserFileManager,
     private val userTracker: UserTracker,
-    private val communalSettingsInteractor: CommunalSettingsInteractor,
     broadcastDispatcher: BroadcastDispatcher,
 ) : KeyguardQuickAffordanceSelectionManager {
 
@@ -127,11 +125,7 @@
 
     override fun getSelections(): Map<String, List<String>> {
         // If the custom shortcuts feature is not enabled, ignore prior selections and use defaults
-        // TODO(b/383391342): remove isV2FlagEnabled check and just depend on the resource
-        if (
-            !(context.resources.getBoolean(R.bool.custom_lockscreen_shortcuts_enabled) ||
-                communalSettingsInteractor.isV2FlagEnabled())
-        ) {
+        if (!context.resources.getBoolean(R.bool.custom_lockscreen_shortcuts_enabled)) {
             return defaults
         }
 
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 dd2bec1..0f5f313 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
@@ -55,6 +55,7 @@
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.callbackFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.filter
@@ -289,7 +290,7 @@
         }
 
     private val areBiometricsEnabledForDeviceEntryFromUserSetting: Flow<Triple<Int, Boolean, Int>> =
-        conflatedCallbackFlow {
+        callbackFlow {
                 val callback =
                     object : IBiometricEnabledOnKeyguardCallback.Stub() {
                         override fun onChanged(enabled: Boolean, userId: Int, modality: Int) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
index aa28c5b..a9729ea 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
@@ -124,7 +124,7 @@
 
     init {
         legacySettingSyncer.startSyncing()
-        dumpManager.registerDumpable("KeyguardQuickAffordances", Dumpster())
+        dumpManager.registerNormalDumpable("KeyguardQuickAffordances", Dumpster())
     }
 
     /**
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 621cc46..4b36e7a 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
@@ -79,6 +79,8 @@
 
     val panelAlpha: MutableStateFlow<Float>
 
+    val zoomOut: StateFlow<Float>
+
     /**
      * Observable for whether the keyguard is showing.
      *
@@ -278,6 +280,9 @@
     /** Temporary shim for fading out content when the brightness slider is used */
     fun setPanelAlpha(alpha: Float)
 
+    /** Sets the zoom out scale of spatial model pushback from e.g. pulling down the shade. */
+    fun setZoomOut(zoomOutFromShadeRadius: Float)
+
     /** Whether the device is actively dreaming */
     fun setDreaming(isDreaming: Boolean)
 
@@ -326,10 +331,7 @@
 
     fun setShortcutAbsoluteTop(top: Float)
 
-    /**
-     * Set bottom of notifications from notification stack, and Magic Portrait will layout base on
-     * this value
-     */
+    /** Set bottom of notifications from notification stack */
     fun setNotificationStackAbsoluteBottom(bottom: Float)
 
     fun setWallpaperFocalAreaBounds(bounds: RectF)
@@ -384,6 +386,7 @@
     override val onCameraLaunchDetected = MutableStateFlow(CameraLaunchSourceModel())
 
     override val panelAlpha: MutableStateFlow<Float> = MutableStateFlow(1f)
+    override val zoomOut: MutableStateFlow<Float> = MutableStateFlow(0f)
     override val topClippingBounds = MutableStateFlow<Int?>(null)
 
     override val isKeyguardShowing: MutableStateFlow<Boolean> =
@@ -665,6 +668,10 @@
         panelAlpha.value = alpha
     }
 
+    override fun setZoomOut(zoomOutFromShadeRadius: Float) {
+        zoomOut.value = zoomOutFromShadeRadius
+    }
+
     override fun setDreaming(isDreaming: Boolean) {
         this.isDreaming.value = isDreaming
     }
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 3739d17..3652c17 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
@@ -337,6 +337,9 @@
     @Deprecated("SceneContainer uses NotificationStackAppearanceInteractor")
     val panelAlpha: StateFlow<Float> = repository.panelAlpha.asStateFlow()
 
+    /** Sets the zoom out scale of spatial model pushback from e.g. pulling down the shade. */
+    val zoomOut: StateFlow<Float> = repository.zoomOut
+
     /**
      * 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.
@@ -475,6 +478,10 @@
         repository.setPanelAlpha(alpha)
     }
 
+    fun setZoomOut(zoomOutFromShadeRadius: Float) {
+        repository.setZoomOut(zoomOutFromShadeRadius)
+    }
+
     fun setAnimateDozingTransitions(animate: Boolean) {
         repository.setAnimateDozingTransitions(animate)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
index 898b68d..65ceb88 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
@@ -29,7 +29,6 @@
 import com.android.keyguard.logging.KeyguardQuickAffordancesLogger
 import com.android.systemui.animation.DialogTransitionAnimator
 import com.android.systemui.animation.Expandable
-import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
@@ -90,7 +89,6 @@
     private val devicePolicyManager: DevicePolicyManager,
     private val dockManager: DockManager,
     private val biometricSettingsRepository: BiometricSettingsRepository,
-    private val communalSettingsInteractor: CommunalSettingsInteractor,
     private val accessibilityManager: AccessibilityManager,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
     @ShadeDisplayAware private val appContext: Context,
@@ -467,10 +465,7 @@
                 name = Contract.FlagsTable.FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED,
                 value =
                     !isFeatureDisabledByDevicePolicy() &&
-                        // TODO(b/383391342): remove isV2FlagEnabled check once trunkfood is reached
-                        (appContext.resources.getBoolean(
-                            R.bool.custom_lockscreen_shortcuts_enabled
-                        ) || communalSettingsInteractor.isV2FlagEnabled()),
+                        appContext.resources.getBoolean(R.bool.custom_lockscreen_shortcuts_enabled),
             ),
             KeyguardPickerFlag(
                 name = Contract.FlagsTable.FLAG_NAME_CUSTOM_CLOCKS_ENABLED,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StatusBarDisableFlagsInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StatusBarDisableFlagsInteractor.kt
index d6a110a..cb602f1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StatusBarDisableFlagsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StatusBarDisableFlagsInteractor.kt
@@ -22,7 +22,10 @@
 import android.os.Binder
 import android.os.IBinder
 import android.os.RemoteException
+import android.os.UserManager
 import android.provider.DeviceConfig
+import android.util.Log
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
 import com.android.internal.statusbar.IStatusBarService
 import com.android.systemui.CoreStartable
@@ -39,6 +42,7 @@
 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.process.ProcessWrapper
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor
@@ -49,9 +53,10 @@
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
-import com.android.app.tracing.coroutines.launchTraced as launch
 import kotlinx.coroutines.withContext
 
+private val TAG = StatusBarDisableFlagsInteractor::class.simpleName
+
 /**
  * Logic around StatusBarService#disableForUser, which is used to disable the home and recents
  * button in certain device states.
@@ -67,6 +72,7 @@
     @Background private val backgroundDispatcher: CoroutineDispatcher,
     private val deviceEntryFaceAuthInteractor: DeviceEntryFaceAuthInteractor,
     private val statusBarService: IStatusBarService,
+    private val processWrapper: ProcessWrapper,
     keyguardTransitionInteractor: KeyguardTransitionInteractor,
     selectedUserInteractor: SelectedUserInteractor,
     deviceConfigInteractor: DeviceConfigInteractor,
@@ -141,6 +147,24 @@
             return
         }
 
+        //  TODO(b/341604160): Remove this blocking logic once StatusBarManagerService supports
+        //  visible background users properly.
+        if (
+            UserManager.isVisibleBackgroundUsersEnabled() &&
+                !processWrapper.isSystemUser() &&
+                !processWrapper.isForegroundUserOrProfile()
+        ) {
+            // Currently, only one SysUI process can register with IStatusBarService to listen
+            // for the CommandQueue events.
+            // In the Multi Display configuration with concurrent multi users (primarily used
+            // in Automotive), a visible background user (Automotive Multi Display passengers)
+            // could also access this code path. Given this limitation and we only allow the
+            // current user's SysUI process to register with IStatusBarService, we need to prevent
+            // calls into IStatusBarService from visible background users.
+            Log.d(TAG, "Status bar manager is disabled for visible background users")
+            return
+        }
+
         scope.launch {
             disableFlagsForUserId.collect { (selectedUserId, flags) ->
                 if (context.getSystemService(Context.STATUS_BAR_SERVICE) == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WallpaperFocalAreaInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WallpaperFocalAreaInteractor.kt
index 934afe2..9c744d6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WallpaperFocalAreaInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WallpaperFocalAreaInteractor.kt
@@ -50,8 +50,7 @@
     keyguardClockRepository: KeyguardClockRepository,
     wallpaperRepository: WallpaperRepository,
 ) {
-    // When there's notifications in splitshade, magic portrait shape effects should be left
-    // aligned in foldable
+    // When there's notifications in splitshade, the focal area shape effect should be left aligned
     private val notificationInShadeWideLayout: Flow<Boolean> =
         combine(
             shadeRepository.isShadeLayoutWide,
@@ -104,7 +103,7 @@
                     )
                 val (left, right) =
                 // tablet landscape
-                if (context.resources.getBoolean(R.bool.center_align_magic_portrait_shape)) {
+                if (context.resources.getBoolean(R.bool.center_align_focal_area_shape)) {
                         Pair(
                             scaledBounds.centerX() - maxFocalAreaWidth / 2F,
                             scaledBounds.centerX() + maxFocalAreaWidth / 2F,
@@ -129,7 +128,7 @@
                         wallpaperZoomedInScale
                 val top =
                     // tablet landscape
-                    if (context.resources.getBoolean(R.bool.center_align_magic_portrait_shape)) {
+                    if (context.resources.getBoolean(R.bool.center_align_focal_area_shape)) {
                         // no strict constraints for top, use bottom margin to make it symmetric
                         // vertically
                         scaledBounds.top + scaledBottomMargin
@@ -169,8 +168,8 @@
             )
         }
 
-        // A max width for magic portrait shape effects bounds, to avoid it going too large
-        // in large screen portrait mode
+        // A max width for focal area shape effects bounds, to avoid
+        // it becoming too large in large screen portrait mode
         const val FOCAL_AREA_MAX_WIDTH_DP = 500
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardJankBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardJankBinder.kt
new file mode 100644
index 0000000..0cb684a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardJankBinder.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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.view.ViewGroup
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.internal.jank.Cuj.CUJ_LOCKSCREEN_TRANSITION_FROM_AOD
+import com.android.internal.jank.Cuj.CUJ_LOCKSCREEN_TRANSITION_TO_AOD
+import com.android.internal.jank.Cuj.CUJ_SCREEN_OFF_SHOW_AOD
+import com.android.internal.jank.InteractionJankMonitor
+import com.android.systemui.keyguard.KeyguardViewMediator
+import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardJankViewModel
+import com.android.systemui.lifecycle.repeatWhenAttached
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.DisposableHandle
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+/** Jank monitoring related to keyguard and transitions. */
+@OptIn(ExperimentalCoroutinesApi::class)
+object KeyguardJankBinder {
+    @JvmStatic
+    fun bind(
+        view: ViewGroup,
+        viewModel: KeyguardJankViewModel,
+        jankMonitor: InteractionJankMonitor?,
+        clockInteractor: KeyguardClockInteractor,
+        keyguardViewMediator: KeyguardViewMediator?,
+        mainImmediateDispatcher: CoroutineDispatcher,
+    ): DisposableHandle? {
+        if (jankMonitor == null) {
+            return null
+        }
+
+        fun processStep(step: TransitionStep, cuj: Int) {
+            val clockId = clockInteractor.renderedClockId
+            when (step.transitionState) {
+                TransitionState.STARTED -> {
+                    val builder =
+                        InteractionJankMonitor.Configuration.Builder.withView(cuj, view)
+                            .setTag(clockId)
+                    jankMonitor.begin(builder)
+                }
+
+                TransitionState.CANCELED -> jankMonitor.cancel(cuj)
+
+                TransitionState.FINISHED -> jankMonitor.end(cuj)
+
+                TransitionState.RUNNING -> Unit
+            }
+        }
+
+        return view.repeatWhenAttached(mainImmediateDispatcher) {
+            repeatOnLifecycle(Lifecycle.State.CREATED) {
+                launch {
+                    viewModel.goneToAodTransition.collect {
+                        processStep(it, CUJ_SCREEN_OFF_SHOW_AOD)
+                        if (it.transitionState == TransitionState.FINISHED) {
+                            keyguardViewMediator?.maybeHandlePendingLock()
+                        }
+                    }
+                }
+
+                launch {
+                    viewModel.lockscreenToAodTransition.collect {
+                        processStep(it, CUJ_LOCKSCREEN_TRANSITION_TO_AOD)
+                    }
+                }
+
+                launch {
+                    viewModel.aodToLockscreenTransition.collect {
+                        processStep(it, CUJ_LOCKSCREEN_TRANSITION_FROM_AOD)
+                    }
+                }
+            }
+        }
+    }
+}
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 017fe16..b8020b1 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,8 +37,6 @@
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.app.tracing.coroutines.launchTraced as launch
-import com.android.internal.jank.InteractionJankMonitor
-import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF_SHOW_AOD
 import com.android.keyguard.AuthInteractionProperties
 import com.android.systemui.Flags
 import com.android.systemui.Flags.msdlFeedback
@@ -51,11 +49,9 @@
 import com.android.systemui.common.ui.view.onTouchListener
 import com.android.systemui.customization.R as customR
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor
-import com.android.systemui.keyguard.KeyguardViewMediator
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
 import com.android.systemui.keyguard.domain.interactor.WallpaperFocalAreaInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.ui.view.layout.sections.AodPromotedNotificationSection
 import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBlueprintViewModel
@@ -110,11 +106,9 @@
         clockInteractor: KeyguardClockInteractor,
         wallpaperFocalAreaInteractor: WallpaperFocalAreaInteractor,
         clockViewModel: KeyguardClockViewModel,
-        interactionJankMonitor: InteractionJankMonitor?,
         deviceEntryHapticsInteractor: DeviceEntryHapticsInteractor?,
         vibratorHelper: VibratorHelper?,
         falsingManager: FalsingManager?,
-        keyguardViewMediator: KeyguardViewMediator?,
         statusBarKeyguardViewManager: StatusBarKeyguardViewManager?,
         mainImmediateDispatcher: CoroutineDispatcher,
         msdlPlayer: MSDLPlayer?,
@@ -178,6 +172,13 @@
                         }
                     }
 
+                    launch("$TAG#zoomOut") {
+                        viewModel.scaleFromZoomOut.collect { scaleFromZoomOut ->
+                            view.scaleX = scaleFromZoomOut
+                            view.scaleY = scaleFromZoomOut
+                        }
+                    }
+
                     launch("$TAG#translationY") {
                         // When translation happens in burnInLayer, it won't be weather clock large
                         // clock isn't added to burnInLayer due to its scale transition so we also
@@ -308,35 +309,6 @@
                         }
                     }
 
-                    interactionJankMonitor?.let { jankMonitor ->
-                        launch {
-                            viewModel.goneToAodTransition.collect {
-                                when (it.transitionState) {
-                                    TransitionState.STARTED -> {
-                                        val clockId = clockInteractor.renderedClockId
-                                        val builder =
-                                            InteractionJankMonitor.Configuration.Builder.withView(
-                                                    CUJ_SCREEN_OFF_SHOW_AOD,
-                                                    view,
-                                                )
-                                                .setTag(clockId)
-                                        jankMonitor.begin(builder)
-                                    }
-
-                                    TransitionState.CANCELED ->
-                                        jankMonitor.cancel(CUJ_SCREEN_OFF_SHOW_AOD)
-
-                                    TransitionState.FINISHED -> {
-                                        keyguardViewMediator?.maybeHandlePendingLock()
-                                        jankMonitor.end(CUJ_SCREEN_OFF_SHOW_AOD)
-                                    }
-
-                                    TransitionState.RUNNING -> Unit
-                                }
-                            }
-                        }
-                    }
-
                     launch {
                         shadeInteractor.isAnyFullyExpanded.collect { isFullyAnyExpanded ->
                             view.visibility =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt
index 856e1d6..8b213be 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.keyguard.ui.view.layout.sections.AccessibilityActionsSection
 import com.android.systemui.keyguard.ui.view.layout.sections.AodBurnInSection
 import com.android.systemui.keyguard.ui.view.layout.sections.AodNotificationIconsSection
+import com.android.systemui.keyguard.ui.view.layout.sections.AodPromotedNotificationSection
 import com.android.systemui.keyguard.ui.view.layout.sections.ClockSection
 import com.android.systemui.keyguard.ui.view.layout.sections.DefaultDeviceEntrySection
 import com.android.systemui.keyguard.ui.view.layout.sections.DefaultIndicationAreaSection
@@ -58,6 +59,7 @@
     defaultStatusBarSection: DefaultStatusBarSection,
     splitShadeNotificationStackScrollLayoutSection: SplitShadeNotificationStackScrollLayoutSection,
     splitShadeGuidelines: SplitShadeGuidelines,
+    aodPromotedNotificationSection: AodPromotedNotificationSection,
     aodNotificationIconsSection: AodNotificationIconsSection,
     aodBurnInSection: AodBurnInSection,
     clockSection: ClockSection,
@@ -76,6 +78,7 @@
             defaultStatusBarSection,
             splitShadeNotificationStackScrollLayoutSection,
             splitShadeGuidelines,
+            aodPromotedNotificationSection,
             aodNotificationIconsSection,
             smartspaceSection,
             aodBurnInSection,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodPromotedNotificationSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodPromotedNotificationSection.kt
index ed1bdb0..6c9a755 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodPromotedNotificationSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodPromotedNotificationSection.kt
@@ -26,6 +26,7 @@
 import androidx.constraintlayout.widget.ConstraintSet.TOP
 import com.android.systemui.keyguard.shared.model.KeyguardSection
 import com.android.systemui.res.R
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.statusbar.notification.promoted.AODPromotedNotification
 import com.android.systemui.statusbar.notification.promoted.PromotedNotificationLogger
 import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUiAod
@@ -36,10 +37,15 @@
 @Inject
 constructor(
     private val viewModelFactory: AODPromotedNotificationViewModel.Factory,
+    private val shadeInteractor: ShadeInteractor,
     private val logger: PromotedNotificationLogger,
 ) : KeyguardSection() {
     var view: ComposeView? = null
 
+    init {
+        logger.logSectionCreated(this)
+    }
+
     override fun addViews(constraintLayout: ConstraintLayout) {
         if (!PromotedNotificationUiAod.isEnabled) {
             return
@@ -54,7 +60,7 @@
                 constraintLayout.addView(this)
             }
 
-        logger.logSectionAddedViews()
+        logger.logSectionAddedViews(this)
     }
 
     override fun bindData(constraintLayout: ConstraintLayout) {
@@ -66,7 +72,7 @@
 
         // Do nothing; the binding happens in the AODPromotedNotification Composable.
 
-        logger.logSectionBoundData()
+        logger.logSectionBoundData(this)
     }
 
     override fun applyConstraints(constraintSet: ConstraintSet) {
@@ -74,18 +80,22 @@
             return
         }
 
-        checkNotNull(view)
+        // view may have been created by a different instance of the section (!), and we don't
+        // actually *need* it to set constraints, so don't check for it here.
 
         constraintSet.apply {
+            val isShadeLayoutWide = shadeInteractor.isShadeLayoutWide.value
+            val endGuidelineId = if (isShadeLayoutWide) R.id.split_shade_guideline else PARENT_ID
+
             connect(viewId, TOP, R.id.smart_space_barrier_bottom, BOTTOM, 0)
             connect(viewId, START, PARENT_ID, START, 0)
-            connect(viewId, END, PARENT_ID, END, 0)
+            connect(viewId, END, endGuidelineId, END, 0)
 
             constrainWidth(viewId, ConstraintSet.MATCH_CONSTRAINT)
             constrainHeight(viewId, ConstraintSet.WRAP_CONTENT)
         }
 
-        logger.logSectionAppliedConstraints()
+        logger.logSectionAppliedConstraints(this)
     }
 
     override fun removeViews(constraintLayout: ConstraintLayout) {
@@ -97,7 +107,7 @@
 
         view = null
 
-        logger.logSectionRemovedViews()
+        logger.logSectionRemovedViews(this)
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardJankViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardJankViewModel.kt
new file mode 100644
index 0000000..2642505
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardJankViewModel.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.Edge
+import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
+import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
+import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
+import com.android.systemui.scene.shared.model.Scenes
+import javax.inject.Inject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
+class KeyguardJankViewModel
+@Inject
+constructor(
+    private val keyguardInteractor: KeyguardInteractor,
+    private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
+) {
+    val goneToAodTransition =
+        keyguardTransitionInteractor.transition(
+            edge = Edge.create(Scenes.Gone, AOD),
+            edgeWithoutSceneContainer = Edge.create(GONE, AOD),
+        )
+
+    val lockscreenToAodTransition =
+        keyguardTransitionInteractor.transition(
+            edge = Edge.create(Scenes.Lockscreen, AOD),
+            edgeWithoutSceneContainer = Edge.create(LOCKSCREEN, AOD),
+        )
+
+    val aodToLockscreenTransition =
+        keyguardTransitionInteractor.transition(
+            edge = Edge.create(AOD, Scenes.Lockscreen),
+            edgeWithoutSceneContainer = Edge.create(AOD, LOCKSCREEN),
+        )
+}
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 11a509a..47a76a0 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
@@ -287,6 +287,9 @@
             .distinctUntilChanged()
     }
 
+    val scaleFromZoomOut: Flow<Float> =
+        keyguardInteractor.zoomOut.map { 1 - it * PUSHBACK_SCALE_FOR_LOCKSCREEN }
+
     val translationY: Flow<Float> = aodBurnInViewModel.movement.map { it.translationY.toFloat() }
 
     val translationX: Flow<StateToValue> =
@@ -418,5 +421,6 @@
 
     companion object {
         private const val TAG = "KeyguardRootViewModel"
+        private const val PUSHBACK_SCALE_FOR_LOCKSCREEN = 0.05f
     }
 }
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 ef6ae0d..b6a3b6a 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
@@ -24,10 +24,11 @@
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.ClockSize
+import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.lifecycle.ExclusiveActivatable
 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.unfold.domain.interactor.UnfoldTransitionInteractor
 import dagger.assisted.AssistedFactory
@@ -54,8 +55,8 @@
     val touchHandling: KeyguardTouchHandlingViewModel,
     private val shadeInteractor: ShadeInteractor,
     private val unfoldTransitionInteractor: UnfoldTransitionInteractor,
-    private val occlusionInteractor: SceneContainerOcclusionInteractor,
     private val deviceEntryInteractor: DeviceEntryInteractor,
+    private val transitionInteractor: KeyguardTransitionInteractor,
 ) : ExclusiveActivatable() {
     @VisibleForTesting val clockSize = clockInteractor.clockSize
 
@@ -89,9 +90,15 @@
             }
 
             launch {
-                occlusionInteractor.isOccludingActivityShown
-                    .map { !it }
-                    .collect { _isContentVisible.value = it }
+                transitionInteractor
+                    .transitionValue(KeyguardState.OCCLUDED)
+                    .map { it > 0f }
+                    .collect { fullyOrPartiallyOccluded ->
+                        // Content is visible unless we're OCCLUDED. Currently, we don't have nice
+                        // animations into and out of OCCLUDED, so the lockscreen/AOD content is
+                        // hidden immediately upon entering/exiting OCCLUDED.
+                        _isContentVisible.value = !fullyOrPartiallyOccluded
+                    }
             }
 
             awaitCancellation()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt
index b7e3e2b..3353983 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt
@@ -25,23 +25,27 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.shade.ui.viewmodel.dualShadeActions
 import com.android.systemui.shade.ui.viewmodel.singleShadeActions
 import com.android.systemui.shade.ui.viewmodel.splitShadeActions
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
 
 /** Models UI state and handles user input for the lockscreen scene. */
+@OptIn(ExperimentalCoroutinesApi::class)
 class LockscreenUserActionsViewModel
 @AssistedInject
 constructor(
     private val deviceEntryInteractor: DeviceEntryInteractor,
     private val communalInteractor: CommunalInteractor,
     private val shadeInteractor: ShadeInteractor,
+    private val shadeModeInteractor: ShadeModeInteractor,
     private val occlusionInteractor: SceneContainerOcclusionInteractor,
 ) : UserActionsViewModel() {
 
@@ -55,7 +59,7 @@
                 combine(
                     deviceEntryInteractor.isUnlocked,
                     communalInteractor.isCommunalAvailable,
-                    shadeInteractor.shadeMode,
+                    shadeModeInteractor.shadeMode,
                     occlusionInteractor.isOccludingActivityShown,
                 ) { isDeviceUnlocked, isCommunalAvailable, shadeMode, isOccluded ->
                     buildList {
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 34c87fe..9968bc9 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
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
+import android.util.MathUtils
 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
 import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
 import com.android.systemui.dagger.SysUISingleton
@@ -63,10 +64,12 @@
     val showAllNotifications: Flow<Boolean> =
         bouncerToGoneFlows.showAllNotifications(TO_GONE_DURATION, PRIMARY_BOUNCER)
 
-    val notificationAlpha: Flow<Float> =
-        transitionAnimation.sharedFlow(
+    fun notificationAlpha(viewState: ViewStateAccessor): Flow<Float> {
+        var startAlpha = 1f
+        return transitionAnimation.sharedFlow(
             duration = 200.milliseconds,
             onStart = {
+                startAlpha = viewState.alpha()
                 leaveShadeOpen = statusBarStateController.leaveOpenOnKeyguardHide()
                 willRunDismissFromKeyguard = primaryBouncerInteractor.willRunDismissFromKeyguard()
             },
@@ -74,11 +77,12 @@
                 if (willRunDismissFromKeyguard || leaveShadeOpen) {
                     1f
                 } else {
-                    1f - it
+                    MathUtils.lerp(startAlpha, 0f, it)
                 }
             },
             onFinish = { 1f },
         )
+    }
 
     /** Bouncer container alpha */
     val bouncerAlpha: Flow<Float> =
diff --git a/packages/SystemUI/src/com/android/systemui/log/SessionTracker.java b/packages/SystemUI/src/com/android/systemui/log/SessionTracker.java
index e8ded03..ad30669 100644
--- a/packages/SystemUI/src/com/android/systemui/log/SessionTracker.java
+++ b/packages/SystemUI/src/com/android/systemui/log/SessionTracker.java
@@ -116,8 +116,8 @@
         mSessionToInstanceId.put(type, instanceId);
 
         if (UserManager.isVisibleBackgroundUsersEnabled() && !mProcessWrapper.isSystemUser()
-                && !mProcessWrapper.isForegroundUser()) {
-            // TODO: b/341604160 - Support visible background users properly.
+                && !mProcessWrapper.isForegroundUserOrProfile()) {
+            // TODO(b/341604160): Support visible background users properly.
             if (DEBUG) {
                 Log.d(TAG, "Status bar manager is disabled for visible background users");
             }
@@ -155,8 +155,8 @@
                 mUiEventLogger.log(endSessionUiEvent, instanceId);
             }
             if (UserManager.isVisibleBackgroundUsersEnabled() && !mProcessWrapper.isSystemUser()
-                    && !mProcessWrapper.isForegroundUser()) {
-                // TODO: b/341604160 - Support visible background users properly.
+                    && !mProcessWrapper.isForegroundUserOrProfile()) {
+                // TODO(b/341604160): Support visible background users properly.
                 if (DEBUG) {
                     Log.d(TAG, "Status bar manager is disabled for visible background users");
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/AmbientLightModeMonitor.kt b/packages/SystemUI/src/com/android/systemui/lowlightclock/AmbientLightModeMonitor.kt
index ece97bd..9e32dd8 100644
--- a/packages/SystemUI/src/com/android/systemui/lowlightclock/AmbientLightModeMonitor.kt
+++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/AmbientLightModeMonitor.kt
@@ -29,6 +29,7 @@
 import java.util.Optional
 import javax.inject.Inject
 import javax.inject.Named
+import javax.inject.Provider
 
 /**
  * Monitors ambient light signals, applies a debouncing algorithm, and produces the current ambient
@@ -43,7 +44,7 @@
 constructor(
     private val algorithm: Optional<DebounceAlgorithm>,
     private val sensorManager: AsyncSensorManager,
-    @Named(LIGHT_SENSOR) private val lightSensor: Optional<Sensor>,
+    @Named(LIGHT_SENSOR) private val lightSensor: Optional<Provider<Sensor>>,
 ) : Dumpable {
     companion object {
         private const val TAG = "AmbientLightModeMonitor"
@@ -67,7 +68,7 @@
     fun start(callback: Callback) {
         if (DEBUG) Log.d(TAG, "start monitoring ambient light mode")
 
-        if (lightSensor.isEmpty) {
+        if (lightSensor.isEmpty || lightSensor.get().get() == null) {
             if (DEBUG) Log.w(TAG, "light sensor not available")
             return
         }
@@ -80,7 +81,7 @@
         algorithm.get().start(callback)
         sensorManager.registerListener(
             mSensorEventListener,
-            lightSensor.get(),
+            lightSensor.get().get(),
             SensorManager.SENSOR_DELAY_NORMAL,
         )
     }
diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/dagger/LowLightModule.java b/packages/SystemUI/src/com/android/systemui/lowlightclock/dagger/LowLightModule.java
index c08be51..8469cb4 100644
--- a/packages/SystemUI/src/com/android/systemui/lowlightclock/dagger/LowLightModule.java
+++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/dagger/LowLightModule.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.lowlightclock.dagger;
 
+import android.annotation.Nullable;
 import android.content.res.Resources;
 import android.hardware.Sensor;
 
@@ -100,6 +101,7 @@
     abstract LowLightDisplayController bindsLowLightDisplayController();
 
     @BindsOptionalOf
+    @Nullable
     @Named(LIGHT_SENSOR)
     abstract Sensor bindsLightSensor();
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImpl.kt
index 3eac12d..ea5f81c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImpl.kt
@@ -306,7 +306,7 @@
         }
 
     init {
-        dumpManager.registerDumpable(TAG, this)
+        dumpManager.registerNormalDumpable(TAG, this)
 
         // Initialize the internal processing pipeline. The listeners at the front of the pipeline
         // are set as internal listeners so that they receive events. From there, events are
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/resume/MediaResumeListener.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/resume/MediaResumeListener.kt
index ad84a5e..0a70e78 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/resume/MediaResumeListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/resume/MediaResumeListener.kt
@@ -141,7 +141,7 @@
 
     init {
         if (useMediaResumption) {
-            dumpManager.registerDumpable(TAG, this)
+            dumpManager.registerNormalDumpable(TAG, this)
             val unlockFilter = IntentFilter()
             unlockFilter.addAction(Intent.ACTION_USER_UNLOCKED)
             broadcastDispatcher.registerReceiver(
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 f05029b..c604bfb 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
@@ -343,7 +343,7 @@
             .stateIn(applicationScope, SharingStarted.Eagerly, true)
 
     init {
-        dumpManager.registerDumpable(TAG, this)
+        dumpManager.registerNormalDumpable(TAG, this)
         mediaFrame = inflateMediaCarousel()
         mediaCarousel = mediaFrame.requireViewById(R.id.media_carousel_scroller)
         pageIndicator = mediaFrame.requireViewById(R.id.media_page_indicator)
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 c00e14c..6501c43 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
@@ -983,13 +983,20 @@
         val overrideSize = mediaHostStatesManager.carouselSizes[location]
         var overridden = false
         overrideSize?.let {
-            // To be safe we're using a maximum here. The override size should always be set
-            // properly though.
-            if (
+            if (SceneContainerFlag.isEnabled) {
+                result.measureWidth = widthInSceneContainerPx
+                result.measureHeight = heightInSceneContainerPx
+                overridden = true
+            } else if (
                 result.measureHeight != it.measuredHeight || result.measureWidth != it.measuredWidth
             ) {
+                // To be safe we're using a maximum here. The override size should always be set
+                // properly though.
                 result.measureHeight = Math.max(it.measuredHeight, result.measureHeight)
                 result.measureWidth = Math.max(it.measuredWidth, result.measureWidth)
+                overridden = true
+            }
+            if (overridden) {
                 // The measureHeight and the shown height should both be set to the overridden
                 // height
                 result.height = result.measureHeight
@@ -1001,7 +1008,6 @@
                         state.width = result.width
                     }
                 }
-                overridden = true
             }
         }
         if (overridden && state != null && state.squishFraction <= 1f) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index 52b3c3ec..bc6b2be 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -156,6 +156,34 @@
             boolean isMutingExpectedDeviceExist = mController.hasMutingExpectedDevice();
             final boolean currentlyConnected = isCurrentlyConnected(device);
             boolean isCurrentSeekbarInvisible = mSeekBar.getVisibility() == View.GONE;
+            boolean isSelected = isDeviceIncluded(mController.getSelectedMediaDevice(), device);
+            boolean isDeselectable =
+                    isDeviceIncluded(mController.getDeselectableMediaDevice(), device);
+            boolean isSelectable = isDeviceIncluded(mController.getSelectableMediaDevice(), device);
+            boolean isTransferable =
+                    isDeviceIncluded(mController.getTransferableMediaDevices(), device);
+            boolean hasRouteListingPreferenceItem = device.hasRouteListingPreferenceItem();
+
+            if (DEBUG) {
+                Log.d(
+                        TAG,
+                        "["
+                                + position
+                                + "] "
+                                + device.getName()
+                                + " ["
+                                + (isDeselectable ? "deselectable" : "")
+                                + "] ["
+                                + (isSelected ? "selected" : "")
+                                + "] ["
+                                + (isSelectable ? "selectable" : "")
+                                + "] ["
+                                + (isTransferable ? "transferable" : "")
+                                + "] ["
+                                + (hasRouteListingPreferenceItem ? "hasListingPreference" : "")
+                                + "]");
+            }
+
             if (mCurrentActivePosition == position) {
                 mCurrentActivePosition = -1;
             }
@@ -210,8 +238,7 @@
                     }
                 } else if (device.hasSubtext()) {
                     boolean isActiveWithOngoingSession =
-                            (device.hasOngoingSession() && (currentlyConnected || isDeviceIncluded(
-                                    mController.getSelectedMediaDevice(), device)));
+                            device.hasOngoingSession() && (currentlyConnected || isSelected);
                     boolean isHost = device.isHostForOngoingSession()
                             && isActiveWithOngoingSession;
                     if (isActiveWithOngoingSession) {
@@ -266,16 +293,12 @@
                     setSingleLineLayout(device.getName(), false /* showSeekBar*/,
                             true /* showProgressBar */, false /* showCheckBox */,
                             false /* showEndTouchArea */);
-                } else if (mController.getSelectedMediaDevice().size() > 1
-                        && isDeviceIncluded(mController.getSelectedMediaDevice(), device)) {
+                } else if (mController.getSelectedMediaDevice().size() > 1 && isSelected) {
                     // selected device in group
-                    boolean isDeviceDeselectable = isDeviceIncluded(
-                            mController.getDeselectableMediaDevice(), device);
-                    boolean showEndArea = !Flags.enableOutputSwitcherSessionGrouping()
-                            || isDeviceDeselectable;
+                    boolean showEndArea =
+                            !Flags.enableOutputSwitcherSessionGrouping() || isDeselectable;
                     updateUnmutedVolumeIcon(device);
-                    updateGroupableCheckBox(true, isDeviceDeselectable, device);
-                    updateEndClickArea(device, isDeviceDeselectable);
+                    updateEndAreaForGroupCheckbox(device, true /* isSelected */, isDeselectable);
                     disableFocusPropertyForView(mContainerLayout);
                     setUpContentDescriptionForView(mSeekBar, device);
                     setSingleLineLayout(device.getName(), true /* showSeekBar */,
@@ -307,10 +330,8 @@
                         //If device is connected and there's other selectable devices, layout as
                         // one of selected devices.
                         updateUnmutedVolumeIcon(device);
-                        boolean isDeviceDeselectable = isDeviceIncluded(
-                                mController.getDeselectableMediaDevice(), device);
-                        updateGroupableCheckBox(true, isDeviceDeselectable, device);
-                        updateEndClickArea(device, isDeviceDeselectable);
+                        updateEndAreaForGroupCheckbox(device, true /* isSelected */,
+                                isDeselectable);
                         disableFocusPropertyForView(mContainerLayout);
                         setUpContentDescriptionForView(mSeekBar, device);
                         setSingleLineLayout(device.getName(), true /* showSeekBar */,
@@ -327,12 +348,16 @@
                                 false /* showEndTouchArea */);
                         initSeekbar(device, isCurrentSeekbarInvisible);
                     }
-                } else if (isDeviceIncluded(mController.getSelectableMediaDevice(), device)) {
+                } else if (isSelectable) {
                     //groupable device
                     setUpDeviceIcon(device);
-                    updateGroupableCheckBox(false, true, device);
-                    updateEndClickArea(device, true);
-                    updateFullItemClickListener(v -> onItemClick(v, device));
+                    updateEndAreaForGroupCheckbox(device, false /* isSelected */,
+                            true /* isDeselectable */);
+                    if (!Flags.disableTransferWhenAppsDoNotSupport()
+                            || isTransferable
+                            || hasRouteListingPreferenceItem) {
+                        updateFullItemClickListener(v -> onItemClick(v, device));
+                    }
                     setSingleLineLayout(device.getName(), false /* showSeekBar */,
                             false /* showProgressBar */, true /* showCheckBox */,
                             true /* showEndTouchArea */);
@@ -380,7 +405,7 @@
         private void updateEndClickAreaWithIcon(View.OnClickListener clickListener,
                 @DrawableRes int iconDrawableId,
                 @StringRes int accessibilityStringId) {
-            updateEndClickAreaColor(mController.getColorSeekbarProgress());
+            updateEndAreaColor(mController.getColorSeekbarProgress());
             mEndClickIcon.setImageTintList(
                     ColorStateList.valueOf(mController.getColorItemContent()));
             mEndClickIcon.setOnClickListener(clickListener);
@@ -396,7 +421,7 @@
             }
         }
 
-        public void updateEndClickAreaColor(int color) {
+        public void updateEndAreaColor(int color) {
             mEndTouchArea.setBackgroundTintList(
                     ColorStateList.valueOf(color));
         }
@@ -429,25 +454,22 @@
                     ColorStateList.valueOf(mController.getColorItemContent()));
         }
 
-        public void updateEndClickArea(MediaDevice device, boolean isDeviceDeselectable) {
+        public void updateEndAreaForGroupCheckbox(MediaDevice device, boolean isSelected,
+                boolean isDeselectable) {
             mEndTouchArea.setOnClickListener(null);
             mEndTouchArea.setOnClickListener(
-                    isDeviceDeselectable ? (v) -> mCheckBox.performClick() : null);
+                    isDeselectable ? (v) -> mCheckBox.performClick() : null);
             mEndTouchArea.setImportantForAccessibility(
                     View.IMPORTANT_FOR_ACCESSIBILITY_YES);
-            mEndTouchArea.setBackgroundTintList(
-                    ColorStateList.valueOf(mController.getColorItemBackground()));
+            updateEndAreaColor(isSelected ? mController.getColorSeekbarProgress()
+                    : mController.getColorItemBackground());
             setUpContentDescriptionForView(mEndTouchArea, device);
-        }
-
-        private void updateGroupableCheckBox(boolean isSelected, boolean isGroupable,
-                MediaDevice device) {
             mCheckBox.setOnCheckedChangeListener(null);
             mCheckBox.setChecked(isSelected);
             mCheckBox.setOnCheckedChangeListener(
-                    isGroupable ? (buttonView, isChecked) -> onGroupActionTriggered(!isSelected,
+                    isDeselectable ? (buttonView, isChecked) -> onGroupActionTriggered(!isSelected,
                             device) : null);
-            mCheckBox.setEnabled(isGroupable);
+            mCheckBox.setEnabled(isDeselectable);
             setCheckBoxColor(mCheckBox, mController.getColorItemContent());
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
index ee2d8aa..a7786c8 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -141,6 +141,8 @@
         final ImageView mEndClickIcon;
         @VisibleForTesting
         MediaOutputSeekbar mSeekBar;
+        private final float mInactiveRadius;
+        private final float mActiveRadius;
         private String mDeviceId;
         private ValueAnimator mCornerAnimator;
         private ValueAnimator mVolumeAnimator;
@@ -161,6 +163,10 @@
             mEndClickIcon = view.requireViewById(R.id.media_output_item_end_click_icon);
             mVolumeValueText = view.requireViewById(R.id.volume_value);
             mIconAreaLayout = view.requireViewById(R.id.icon_area);
+            mInactiveRadius = mContext.getResources().getDimension(
+                    R.dimen.media_output_dialog_background_radius);
+            mActiveRadius = mContext.getResources().getDimension(
+                    R.dimen.media_output_dialog_active_background_radius);
             initAnimator();
         }
 
@@ -216,10 +222,6 @@
                 mEndClickIcon.setVisibility(
                         !showCheckBox && showEndTouchArea ? View.VISIBLE : View.GONE);
             }
-            ViewGroup.MarginLayoutParams params =
-                    (ViewGroup.MarginLayoutParams) mItemLayout.getLayoutParams();
-            params.rightMargin = showEndTouchArea ? mController.getItemMarginEndSelectable()
-                    : mController.getItemMarginEndDefault();
         }
 
         void setTwoLineLayout(CharSequence title, boolean showSeekBar,
@@ -247,10 +249,6 @@
             //update end click area by isActive
             mEndTouchArea.setVisibility(showEndTouchArea ? View.VISIBLE : View.GONE);
             mEndClickIcon.setVisibility(showEndTouchArea ? View.VISIBLE : View.GONE);
-            ViewGroup.MarginLayoutParams params =
-                    (ViewGroup.MarginLayoutParams) mItemLayout.getLayoutParams();
-            params.rightMargin = showEndTouchArea ? mController.getItemMarginEndSelectable()
-                    : mController.getItemMarginEndDefault();
             mItemLayout.setBackground(backgroundDrawable);
             mProgressBar.setVisibility(showProgressBar ? View.VISIBLE : View.GONE);
             mSubTitleText.setVisibility(showSubtitle ? View.VISIBLE : View.GONE);
@@ -264,10 +262,10 @@
             final GradientDrawable progressDrawable =
                     (GradientDrawable) clipDrawable.getDrawable();
             progressDrawable.setCornerRadii(
-                    new float[]{0, 0, mController.getActiveRadius(),
-                            mController.getActiveRadius(),
-                            mController.getActiveRadius(),
-                            mController.getActiveRadius(), 0, 0});
+                    new float[]{0, 0, mActiveRadius,
+                            mActiveRadius,
+                            mActiveRadius,
+                            mActiveRadius, 0, 0});
         }
 
         private void initializeSeekbarVolume(
@@ -431,8 +429,7 @@
         }
 
         private void initAnimator() {
-            mCornerAnimator = ValueAnimator.ofFloat(mController.getInactiveRadius(),
-                    mController.getActiveRadius());
+            mCornerAnimator = ValueAnimator.ofFloat(mInactiveRadius, mActiveRadius);
             mCornerAnimator.setDuration(ANIM_DURATION);
             mCornerAnimator.setInterpolator(new LinearInterpolator());
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java
index 35c872f..19409b3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java
@@ -171,10 +171,6 @@
     private int mColorConnectedItemBackground;
     private int mColorPositiveButtonText;
     private int mColorDialogBackground;
-    private int mItemMarginEndDefault;
-    private int mItemMarginEndSelectable;
-    private float mInactiveRadius;
-    private float mActiveRadius;
     private FeatureFlags mFeatureFlags;
     private UserTracker mUserTracker;
     private VolumePanelGlobalStateInteractor mVolumePanelGlobalStateInteractor;
@@ -246,16 +242,8 @@
                 R.color.media_dialog_connected_item_background);
         mColorPositiveButtonText = Utils.getColorStateListDefaultColor(mContext,
                 R.color.media_dialog_solid_button_text);
-        mInactiveRadius = mContext.getResources().getDimension(
-                R.dimen.media_output_dialog_background_radius);
-        mActiveRadius = mContext.getResources().getDimension(
-                R.dimen.media_output_dialog_active_background_radius);
         mColorDialogBackground = Utils.getColorStateListDefaultColor(mContext,
                 R.color.media_dialog_background);
-        mItemMarginEndDefault = (int) mContext.getResources().getDimension(
-                R.dimen.media_output_dialog_default_margin_end);
-        mItemMarginEndSelectable = (int) mContext.getResources().getDimension(
-                R.dimen.media_output_dialog_selectable_margin_end);
 
         if (enableInputRouting()) {
             mInputRouteManager = new InputRouteManager(mContext, audioManager);
@@ -638,22 +626,6 @@
         return mColorItemBackground;
     }
 
-    public float getInactiveRadius() {
-        return mInactiveRadius;
-    }
-
-    public float getActiveRadius() {
-        return mActiveRadius;
-    }
-
-    public int getItemMarginEndDefault() {
-        return mItemMarginEndDefault;
-    }
-
-    public int getItemMarginEndSelectable() {
-        return mItemMarginEndSelectable;
-    }
-
     private void buildMediaItems(List<MediaDevice> devices) {
         synchronized (mMediaDevicesLock) {
             List<MediaItem> updatedMediaItems = buildMediaItems(mOutputMediaItemList, devices);
@@ -941,6 +913,10 @@
         return mLocalMediaManager.getSelectableMediaDevice();
     }
 
+    List<MediaDevice> getTransferableMediaDevices() {
+        return mLocalMediaManager.getTransferableMediaDevices();
+    }
+
     public List<MediaDevice> getSelectedMediaDevice() {
         if (!enableInputRouting()) {
             return mLocalMediaManager.getSelectedMediaDevice();
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/INoteTaskBubblesService.aidl b/packages/SystemUI/src/com/android/systemui/notetask/INoteTaskBubblesService.aidl
index 7803f22..d803ebe 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/INoteTaskBubblesService.aidl
+++ b/packages/SystemUI/src/com/android/systemui/notetask/INoteTaskBubblesService.aidl
@@ -26,6 +26,6 @@
 
     boolean areBubblesAvailable();
 
-    void showOrHideAppBubble(in Intent intent, in UserHandle userHandle, in Icon icon,
+    void showOrHideNoteBubble(in Intent intent, in UserHandle userHandle, in Icon icon,
      in NoteTaskBubbleExpandBehavior bubbleExpandBehavior);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubblesController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubblesController.kt
index 169285f..e20ccfa 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubblesController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskBubblesController.kt
@@ -76,8 +76,8 @@
             }
         }
 
-    /** Calls the [Bubbles.showOrHideAppBubble] API as [UserHandle.USER_SYSTEM]. */
-    open suspend fun showOrHideAppBubble(
+    /** Calls the [Bubbles.showOrHideNoteBubble] API as [UserHandle.USER_SYSTEM]. */
+    open suspend fun showOrHideNoteBubble(
         intent: Intent,
         userHandle: UserHandle,
         icon: Icon,
@@ -85,7 +85,7 @@
     ) {
         withContext(bgDispatcher) {
             serviceConnector
-                .post { it.showOrHideAppBubble(intent, userHandle, icon, bubbleExpandBehavior) }
+                .post { it.showOrHideNoteBubble(intent, userHandle, icon, bubbleExpandBehavior) }
                 .whenComplete { _, error ->
                     if (error != null) {
                         debugLog(error = error) {
@@ -119,7 +119,7 @@
             return object : INoteTaskBubblesService.Stub() {
                 override fun areBubblesAvailable() = mOptionalBubbles.isPresent
 
-                override fun showOrHideAppBubble(
+                override fun showOrHideNoteBubble(
                     intent: Intent,
                     userHandle: UserHandle,
                     icon: Icon,
@@ -131,12 +131,12 @@
                                 bubbleExpandBehavior ==
                                     NoteTaskBubbleExpandBehavior.KEEP_IF_EXPANDED &&
                                     bubbles.isBubbleExpanded(
-                                        Bubble.getAppBubbleKeyForApp(intent.`package`, userHandle)
+                                        Bubble.getNoteBubbleKeyForApp(intent.`package`, userHandle)
                                     )
                             ) {
                                 return@ifPresentOrElse
                             }
-                            bubbles.showOrHideAppBubble(intent, userHandle, icon)
+                            bubbles.showOrHideNoteBubble(intent, userHandle, icon)
                         },
                         {
                             debugLog {
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index ad1f370..7e0128a 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -96,7 +96,7 @@
 
         val info = infoReference.getAndSet(null) ?: return
 
-        if (key != Bubble.getAppBubbleKeyForApp(info.packageName, info.user)) return
+        if (key != Bubble.getNoteBubbleKeyForApp(info.packageName, info.user)) return
 
         // Safe guard mechanism, this callback should only be called for app bubbles.
         if (info.launchMode !is NoteTaskLaunchMode.AppBubble) return
@@ -219,7 +219,7 @@
                     val intent = createNoteTaskIntent(info, useStylusMode)
                     val icon =
                         Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget)
-                    noteTaskBubblesController.showOrHideAppBubble(
+                    noteTaskBubblesController.showOrHideNoteBubble(
                         intent,
                         user,
                         icon,
diff --git a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt
index 8aad61a..c7b1654 100644
--- a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModel.kt
@@ -52,18 +52,11 @@
 
     private val hydrator = Hydrator("NotificationsShadeOverlayContentViewModel.hydrator")
 
-    val isShadeLayoutWide: Boolean by
+    val showClock: Boolean by
         hydrator.hydratedStateOf(
-            traceName = "isShadeLayoutWide",
-            initialValue = shadeInteractor.isShadeLayoutWide.value,
-            source = shadeInteractor.isShadeLayoutWide,
-        )
-
-    val showHeader: Boolean by
-        hydrator.hydratedStateOf(
-            traceName = "showHeader",
+            traceName = "showClock",
             initialValue =
-                shouldShowHeader(
+                shouldShowClock(
                     isShadeLayoutWide = shadeInteractor.isShadeLayoutWide.value,
                     areAnyNotificationsPresent =
                         activeNotificationsInteractor.areAnyNotificationsPresentValue,
@@ -72,7 +65,7 @@
                 combine(
                     shadeInteractor.isShadeLayoutWide,
                     activeNotificationsInteractor.areAnyNotificationsPresent,
-                    this::shouldShowHeader,
+                    this::shouldShowClock,
                 ),
         )
 
@@ -110,7 +103,7 @@
         shadeInteractor.collapseNotificationsShade(loggingReason = "shade scrim clicked")
     }
 
-    private fun shouldShowHeader(
+    private fun shouldShowClock(
         isShadeLayoutWide: Boolean,
         areAnyNotificationsPresent: Boolean,
     ): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt b/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt
index f8d442d..25d53e6 100644
--- a/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt
@@ -50,7 +50,7 @@
     @FalsingCollectorActual private val falsingCollector: FalsingCollector,
     private val screenOffAnimationController: ScreenOffAnimationController,
     private val statusBarStateController: StatusBarStateController,
-    private val cameraGestureHelper: Provider<CameraGestureHelper>,
+    private val cameraGestureHelper: Provider<CameraGestureHelper?>,
 ) {
     /** Whether the screen is on or off. */
     val isInteractive: Flow<Boolean> = repository.isInteractive
@@ -154,8 +154,9 @@
         // or onFinishedGoingToSleep(), carry that state forward. It will be reset by the next
         // onStartedGoingToSleep.
         val powerButtonLaunchGestureTriggered =
-            powerButtonLaunchGestureTriggeredOnWakeUp ||
-                repository.wakefulness.value.powerButtonLaunchGestureTriggered
+            !isPowerButtonGestureSuppressed() &&
+                (powerButtonLaunchGestureTriggeredOnWakeUp ||
+                    repository.wakefulness.value.powerButtonLaunchGestureTriggered)
 
         repository.updateWakefulness(
             rawState = WakefulnessState.STARTING_TO_WAKE,
@@ -204,8 +205,9 @@
         // If the launch gesture was previously detected via onCameraLaunchGestureDetected, carry
         // that state forward. It will be reset by the next onStartedGoingToSleep.
         val powerButtonLaunchGestureTriggered =
-            powerButtonLaunchGestureTriggeredDuringSleep ||
-                repository.wakefulness.value.powerButtonLaunchGestureTriggered
+            !isPowerButtonGestureSuppressed() &&
+                (powerButtonLaunchGestureTriggeredDuringSleep ||
+                    repository.wakefulness.value.powerButtonLaunchGestureTriggered)
 
         repository.updateWakefulness(
             rawState = WakefulnessState.ASLEEP,
@@ -218,11 +220,7 @@
     }
 
     fun onCameraLaunchGestureDetected() {
-        if (
-            cameraGestureHelper
-                .get()
-                .canCameraGestureBeLaunched(statusBarStateController.getState())
-        ) {
+        if (!isPowerButtonGestureSuppressed()) {
             repository.updateWakefulness(powerButtonLaunchGestureTriggered = true)
         }
     }
@@ -240,6 +238,16 @@
             .collect()
     }
 
+    /**
+     * Whether the power button gesture isn't allowed to launch anything even if a double tap is
+     * detected.
+     */
+    private fun isPowerButtonGestureSuppressed(): Boolean {
+        return cameraGestureHelper
+            .get()
+            ?.canCameraGestureBeLaunched(statusBarStateController.state) == false
+    }
+
     companion object {
         private const val FSI_WAKE_WHY = "full_screen_intent"
 
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyConfig.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyConfig.kt
index 67d390d..79a513f 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyConfig.kt
@@ -85,7 +85,7 @@
             }
 
     init {
-        dumpManager.registerDumpable(TAG, this)
+        dumpManager.registerNormalDumpable(TAG, this)
         deviceConfigProxy.addOnPropertiesChangedListener(
                 DeviceConfig.NAMESPACE_PRIVACY,
                 uiExecutor,
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
index eb8ef9b..f9a7205 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
@@ -98,7 +98,7 @@
     }
 
     init {
-        dumpManager.registerDumpable(TAG, this)
+        dumpManager.registerNormalDumpable(TAG, this)
         privacyConfig.addCallback(optionsCallback)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java b/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java
index 294d0c7..f3a3a3a2 100644
--- a/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java
@@ -27,8 +27,12 @@
  * providing a mockable target around these details.
  */
 public class ProcessWrapper {
+    private final ActivityManager mActivityManager;
+
     @Inject
-    public ProcessWrapper() {}
+    public ProcessWrapper(ActivityManager activityManager) {
+        mActivityManager = activityManager;
+    }
 
     /**
      * Returns {@code true} if System User is running the current process.
@@ -38,10 +42,10 @@
     }
 
     /**
-     * Returns {@code true} if the foreground user is running the current process.
+     * Returns {@code true} if the foreground user or profile is running the current process.
      */
-    public boolean isForegroundUser() {
-        return ActivityManager.getCurrentUser() == myUserHandle().getIdentifier();
+    public boolean isForegroundUserOrProfile() {
+        return mActivityManager.isProfileForeground(myUserHandle());
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
index 85b677b..cf3b496 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
@@ -573,8 +573,7 @@
             onDispose { qqsVisible.value = false }
         }
         val squishiness by
-            viewModel.containerViewModel.quickQuickSettingsViewModel.squishinessViewModel
-                .squishiness
+            viewModel.quickQuickSettingsViewModel.squishinessViewModel.squishiness
                 .collectAsStateWithLifecycle()
 
         Column(modifier = modifier.sysuiResTag(ResIdTags.quickQsPanel)) {
@@ -607,9 +606,7 @@
             ) {
                 val Tiles =
                     @Composable {
-                        QuickQuickSettings(
-                            viewModel = viewModel.containerViewModel.quickQuickSettingsViewModel
-                        )
+                        QuickQuickSettings(viewModel = viewModel.quickQuickSettingsViewModel)
                     }
                 val Media =
                     @Composable {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
index 219fc2f..0dade74 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
@@ -59,6 +59,7 @@
 import com.android.systemui.qs.panels.domain.interactor.TileSquishinessInteractor
 import com.android.systemui.qs.panels.ui.viewmodel.InFirstPageViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.MediaInRowInLandscapeViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.QuickQuickSettingsViewModel
 import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel
 import com.android.systemui.res.R
 import com.android.systemui.scene.shared.model.Scenes
@@ -94,6 +95,7 @@
 @AssistedInject
 constructor(
     containerViewModelFactory: QuickSettingsContainerViewModel.Factory,
+    quickQuickSettingsViewModelFactory: QuickQuickSettingsViewModel.Factory,
     @Main private val resources: Resources,
     footerActionsViewModelFactory: FooterActionsViewModel.Factory,
     private val footerActionsController: FooterActionsController,
@@ -102,7 +104,7 @@
     DisableFlagsInteractor: DisableFlagsInteractor,
     keyguardTransitionInteractor: KeyguardTransitionInteractor,
     private val largeScreenShadeInterpolator: LargeScreenShadeInterpolator,
-    private val shadeInteractor: ShadeInteractor,
+    shadeInteractor: ShadeInteractor,
     @ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
     private val largeScreenHeaderHelper: LargeScreenHeaderHelper,
     private val squishinessInteractor: TileSquishinessInteractor,
@@ -118,6 +120,8 @@
 ) : Dumpable, ExclusiveActivatable() {
 
     val containerViewModel = containerViewModelFactory.create(true)
+    val quickQuickSettingsViewModel = quickQuickSettingsViewModelFactory.create()
+
     private val qqsMediaInRowViewModel = mediaInRowInLandscapeViewModelFactory.create(LOCATION_QQS)
     private val qsMediaInRowViewModel = mediaInRowInLandscapeViewModelFactory.create(LOCATION_QS)
 
@@ -475,6 +479,7 @@
             }
             launch { hydrator.activate() }
             launch { containerViewModel.activate() }
+            launch { quickQuickSettingsViewModel.activate() }
             launch { qqsMediaInRowViewModel.activate() }
             launch { qsMediaInRowViewModel.activate() }
             awaitCancellation()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt b/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt
index c302cb2..3afaef5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt
@@ -20,7 +20,6 @@
 import com.android.systemui.flags.FlagToken
 import com.android.systemui.flags.RefactorFlagUtils
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.shade.shared.flag.DualShade
 
 /** Helper for reading or using the QS Detailed View flag state. */
 @Suppress("NOTHING_TO_INLINE")
@@ -37,7 +36,6 @@
     inline val isEnabled
         get() =
             Flags.qsTileDetailedView() && // mainAconfigFlag
-                DualShade.isEnabled &&
                 SceneContainerFlag.isEnabled
 
     // NOTE: Changes should also be made in getSecondaryFlags
@@ -47,10 +45,8 @@
 
     /** The set of secondary flags which must be enabled for qs detailed view to work properly */
     inline fun getSecondaryFlags(): Sequence<FlagToken> =
-        sequenceOf(
-            DualShade.token
-            // NOTE: Changes should also be made in isEnabled
-        ) + SceneContainerFlag.getAllRequirements()
+        // NOTE: Changes should also be made in isEnabled
+        SceneContainerFlag.getAllRequirements()
 
     /** The full set of requirements for QsDetailedView */
     inline fun getAllRequirements(): Sequence<FlagToken> {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/flags/QsInCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/flags/QsInCompose.kt
index 3067ccb..3140df8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/flags/QsInCompose.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/flags/QsInCompose.kt
@@ -17,11 +17,11 @@
 package com.android.systemui.qs.flags
 
 import com.android.systemui.flags.RefactorFlagUtils
-import com.android.systemui.shade.shared.flag.DualShade
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 
 /**
  * Object to help check if the new QS ui should be used. This is true if either [QSComposeFragment]
- * or [DualShade] are enabled.
+ * or [SceneContainerFlag] are enabled.
  */
 object QsInCompose {
 
@@ -29,11 +29,12 @@
      * This is not a real flag name, but a representation of the allowed flag names. Should not be
      * used with test annotations.
      */
-    private val flagName = "${QSComposeFragment.FLAG_NAME}|${DualShade.FLAG_NAME}"
+    private val flagName =
+        "${QSComposeFragment.FLAG_NAME}|${SceneContainerFlag.getMainAconfigFlag().name}"
 
     @JvmStatic
     inline val isEnabled: Boolean
-        get() = QSComposeFragment.isEnabled || DualShade.isEnabled
+        get() = QSComposeFragment.isEnabled || SceneContainerFlag.isEnabled
 
     @JvmStatic
     fun isUnexpectedlyInLegacyMode() =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QSColumnsInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QSColumnsInteractor.kt
index 2b2a63b..e6b89fc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QSColumnsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QSColumnsInteractor.kt
@@ -19,25 +19,27 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.qs.panels.data.repository.QSColumnsRepository
-import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 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.flatMapLatest
 import kotlinx.coroutines.flow.stateIn
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SysUISingleton
 class QSColumnsInteractor
 @Inject
 constructor(
     @Application scope: CoroutineScope,
     repo: QSColumnsRepository,
-    shadeInteractor: ShadeInteractor,
+    shadeModeInteractor: ShadeModeInteractor,
 ) {
     val columns: StateFlow<Int> =
-        shadeInteractor.shadeMode
+        shadeModeInteractor.shadeMode
             .flatMapLatest {
                 when (it) {
                     ShadeMode.Dual -> repo.dualShadeColumns
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt
index 30fb50d..1233a2f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt
@@ -38,8 +38,17 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.dp
+import com.android.systemui.bluetooth.qsdialog.BluetoothDetailsContent
+import com.android.systemui.bluetooth.qsdialog.BluetoothDetailsViewModel
+import com.android.systemui.plugins.qs.TileDetailsViewModel
 import com.android.systemui.qs.flags.QsDetailedView
 import com.android.systemui.qs.panels.ui.viewmodel.DetailsViewModel
+import com.android.systemui.qs.tiles.dialog.InternetDetailsContent
+import com.android.systemui.qs.tiles.dialog.InternetDetailsViewModel
+import com.android.systemui.qs.tiles.dialog.ModesDetailsContent
+import com.android.systemui.qs.tiles.dialog.ModesDetailsViewModel
+import com.android.systemui.qs.tiles.dialog.ScreenRecordDetailsContent
+import com.android.systemui.qs.tiles.dialog.ScreenRecordDetailsViewModel
 
 @Composable
 fun TileDetails(modifier: Modifier = Modifier, detailsViewModel: DetailsViewModel) {
@@ -107,7 +116,17 @@
                 style = MaterialTheme.typography.titleSmall,
             )
         }
-        tileDetailedViewModel.GetContentView()
+        MapTileDetailsContent(tileDetailedViewModel)
+    }
+}
+
+@Composable
+private fun MapTileDetailsContent(tileDetailsViewModel: TileDetailsViewModel) {
+    when (tileDetailsViewModel) {
+        is InternetDetailsViewModel -> InternetDetailsContent(tileDetailsViewModel)
+        is ScreenRecordDetailsViewModel -> ScreenRecordDetailsContent(tileDetailsViewModel)
+        is BluetoothDetailsViewModel -> BluetoothDetailsContent()
+        is ModesDetailsViewModel -> ModesDetailsContent(tileDetailsViewModel)
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
index 1f4f9f9..7701b90 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
@@ -31,6 +31,7 @@
 import androidx.compose.foundation.ScrollState
 import androidx.compose.foundation.background
 import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
 import androidx.compose.foundation.clipScrollableContainer
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.Arrangement.spacedBy
@@ -49,7 +50,6 @@
 import androidx.compose.foundation.layout.requiredHeightIn
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.wrapContentHeight
-import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.foundation.lazy.grid.GridCells
 import androidx.compose.foundation.lazy.grid.LazyGridScope
 import androidx.compose.foundation.lazy.grid.rememberLazyGridState
@@ -101,7 +101,6 @@
 import androidx.compose.ui.semantics.CustomAccessibilityAction
 import androidx.compose.ui.semantics.contentDescription
 import androidx.compose.ui.semantics.customActions
-import androidx.compose.ui.semantics.onClick
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.semantics.stateDescription
 import androidx.compose.ui.text.style.TextAlign
@@ -138,7 +137,6 @@
 import com.android.systemui.qs.panels.ui.compose.selection.ResizingState.ResizeOperation
 import com.android.systemui.qs.panels.ui.compose.selection.ResizingState.ResizeOperation.FinalResizeOperation
 import com.android.systemui.qs.panels.ui.compose.selection.ResizingState.ResizeOperation.TemporaryResizeOperation
-import com.android.systemui.qs.panels.ui.compose.selection.clearSelectionTile
 import com.android.systemui.qs.panels.ui.compose.selection.rememberResizingState
 import com.android.systemui.qs.panels.ui.compose.selection.rememberSelectionState
 import com.android.systemui.qs.panels.ui.compose.selection.selectableTile
@@ -190,6 +188,7 @@
     columns: Int,
     largeTilesSpan: Int,
     modifier: Modifier,
+    onAddTile: (TileSpec) -> Unit,
     onRemoveTile: (TileSpec) -> Unit,
     onSetTiles: (List<TileSpec>) -> Unit,
     onResize: (TileSpec, toIcon: Boolean) -> Unit,
@@ -230,20 +229,26 @@
                     modifier
                         .fillMaxSize()
                         // Apply top padding before the scroll so the scrollable doesn't show under
-                        // the
-                        // top bar
+                        // the top bar
                         .padding(top = innerPadding.calculateTopPadding())
                         .clipScrollableContainer(Orientation.Vertical)
                         .verticalScroll(scrollState),
             ) {
                 AnimatedContent(
-                    targetState = listState.dragInProgress,
-                    modifier = Modifier.wrapContentSize(),
+                    targetState = listState.dragInProgress || selectionState.selected,
                     label = "QSEditHeader",
-                ) { dragIsInProgress ->
-                    EditGridHeader(Modifier.dragAndDropRemoveZone(listState, onRemoveTile)) {
-                        if (dragIsInProgress) {
-                            RemoveTileTarget()
+                ) { showRemoveTarget ->
+                    EditGridHeader(
+                        Modifier.dragAndDropRemoveZone(listState, onRemoveTile)
+                            .padding(bottom = 26.dp)
+                    ) {
+                        if (showRemoveTarget) {
+                            RemoveTileTarget {
+                                selectionState.selection?.let {
+                                    selectionState.unSelect()
+                                    onRemoveTile(it.tileSpec)
+                                }
+                            }
                         } else {
                             Text(text = stringResource(id = R.string.drag_to_rearrange_tiles))
                         }
@@ -283,7 +288,13 @@
                                 Text(text = stringResource(id = R.string.drag_to_add_tiles))
                             }
 
-                            AvailableTileGrid(otherTiles, selectionState, columns, listState)
+                            AvailableTileGrid(
+                                otherTiles,
+                                selectionState,
+                                columns,
+                                onAddTile,
+                                listState,
+                            )
                         }
                     }
                 }
@@ -347,22 +358,18 @@
     CompositionLocalProvider(
         LocalContentColor provides MaterialTheme.colorScheme.onBackground.copy(alpha = .5f)
     ) {
-        Box(
-            contentAlignment = Alignment.Center,
-            modifier = modifier.fillMaxWidth().wrapContentHeight(),
-        ) {
-            content()
-        }
+        Box(contentAlignment = Alignment.Center, modifier = modifier.fillMaxWidth()) { content() }
     }
 }
 
 @Composable
-private fun RemoveTileTarget() {
+private fun RemoveTileTarget(onClick: () -> Unit) {
     Row(
         verticalAlignment = Alignment.CenterVertically,
         horizontalArrangement = tileHorizontalArrangement(),
         modifier =
             Modifier.fillMaxHeight()
+                .clickable(onClick = onClick)
                 .border(1.dp, LocalContentColor.current, shape = CircleShape)
                 .padding(10.dp),
     ) {
@@ -441,6 +448,7 @@
     tiles: List<SizedTile<EditTileViewModel>>,
     selectionState: MutableSelectionState,
     columns: Int,
+    onAddTile: (TileSpec) -> Unit,
     dragAndDropState: DragAndDropState,
 ) {
     // Available tiles aren't visible during drag and drop, so the row/col isn't needed
@@ -478,6 +486,7 @@
                                     index = index,
                                     dragAndDropState = dragAndDropState,
                                     selectionState = selectionState,
+                                    onAddTile = onAddTile,
                                     modifier = Modifier.weight(1f).fillMaxHeight(),
                                 )
                             }
@@ -682,11 +691,16 @@
     index: Int,
     dragAndDropState: DragAndDropState,
     selectionState: MutableSelectionState,
+    onAddTile: (TileSpec) -> Unit,
     modifier: Modifier = Modifier,
 ) {
     val onClickActionName = stringResource(id = R.string.accessibility_qs_edit_tile_add_action)
     val stateDescription = stringResource(id = R.string.accessibility_qs_edit_position, index + 1)
     val colors = EditModeTileDefaults.editTileColors()
+    val onClick = {
+        onAddTile(cell.tile.tileSpec)
+        selectionState.select(cell.tile.tileSpec, manual = false)
+    }
 
     // Displays the tile as an icon tile with the label underneath
     Column(
@@ -697,11 +711,8 @@
         Box(
             Modifier.fillMaxWidth()
                 .height(TileHeight)
-                .clearSelectionTile(selectionState)
-                .semantics(mergeDescendants = true) {
-                    onClick(onClickActionName) { false }
-                    this.stateDescription = stateDescription
-                }
+                .clickable(onClick = onClick, onClickLabel = onClickActionName)
+                .semantics(mergeDescendants = true) { this.stateDescription = stateDescription }
                 .dragAndDropTileSource(
                     SizedTileImpl(cell.tile, cell.width),
                     dragAndDropState,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
index cc4c3af..1c540ee 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
@@ -42,6 +42,7 @@
 import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.InfiniteGridViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
+import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor.Companion.POSITION_AT_END
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.shared.ui.ElementKeys.toElementKey
 import com.android.systemui.res.R
@@ -155,6 +156,7 @@
             otherTiles = otherTiles,
             columns = columns,
             modifier = modifier,
+            onAddTile = { onAddTile(it, POSITION_AT_END) },
             onRemoveTile = onRemoveTile,
             onSetTiles = onSetTiles,
             onResize = iconTilesViewModel::resize,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionState.kt
index c6c6dca..26dfc72 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionState.kt
@@ -21,6 +21,7 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.input.pointer.pointerInput
 import com.android.systemui.qs.pipeline.shared.TileSpec
@@ -39,17 +40,19 @@
 
 /** Holds the state of the current selection. */
 class MutableSelectionState {
-    private var _selection = mutableStateOf<Selection?>(null)
-
     /** The [Selection] if a tile is selected, null if not. */
-    val selection by _selection
+    var selection by mutableStateOf<Selection?>(null)
+        private set
+
+    val selected: Boolean
+        get() = selection != null
 
     fun select(tileSpec: TileSpec, manual: Boolean) {
-        _selection.value = Selection(tileSpec, manual)
+        selection = Selection(tileSpec, manual)
     }
 
     fun unSelect() {
-        _selection.value = null
+        selection = null
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 0109e70a..1cfa663 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -158,7 +158,7 @@
 
     private void handleClickEvent(@Nullable Expandable expandable) {
         if (mFeatureFlags.isEnabled(Flags.BLUETOOTH_QS_TILE_DIALOG)) {
-            mDialogViewModel.showDialog(expandable);
+            mDialogViewModel.showDetailsContent(expandable, /* view= */ null);
         } else {
             // Secondary clicks are header clicks, just toggle.
             toggleBluetooth();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContent.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContent.kt
new file mode 100644
index 0000000..7d396c5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContent.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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.dialog
+
+import android.view.LayoutInflater
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.viewinterop.AndroidView
+import com.android.systemui.res.R
+
+@Composable
+fun InternetDetailsContent(viewModel: InternetDetailsViewModel) {
+    val coroutineScope = rememberCoroutineScope()
+    val context = LocalContext.current
+
+    val internetDetailsContentManager = remember {
+        viewModel.contentManagerFactory.create(
+            canConfigMobileData = viewModel.getCanConfigMobileData(),
+            canConfigWifi = viewModel.getCanConfigWifi(),
+            coroutineScope = coroutineScope,
+            context = context,
+        )
+    }
+
+    AndroidView(
+        modifier = Modifier.fillMaxSize(),
+        factory = { context ->
+            // Inflate with the existing dialog xml layout and bind it with the manager
+            val view =
+                LayoutInflater.from(context).inflate(R.layout.internet_connectivity_dialog, null)
+            internetDetailsContentManager.bind(view)
+
+            view
+            // TODO: b/377388104 - Polish the internet details view UI
+        },
+        onRelease = { internetDetailsContentManager.unBind() },
+    )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsViewModel.kt
index df4dddb..0ed56f6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsViewModel.kt
@@ -16,18 +16,7 @@
 
 package com.android.systemui.qs.tiles.dialog
 
-import android.util.Log
-import android.view.LayoutInflater
-import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberCoroutineScope
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.viewinterop.AndroidView
 import com.android.systemui.plugins.qs.TileDetailsViewModel
-import com.android.systemui.res.R
 import com.android.systemui.statusbar.connectivity.AccessPointController
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
@@ -37,45 +26,9 @@
 @AssistedInject
 constructor(
     private val accessPointController: AccessPointController,
-    private val contentManagerFactory: InternetDetailsContentManager.Factory,
+    val contentManagerFactory: InternetDetailsContentManager.Factory,
     @Assisted private val onLongClick: () -> Unit,
 ) : TileDetailsViewModel() {
-    private lateinit var internetDetailsContentManager: InternetDetailsContentManager
-
-    @Composable
-    override fun GetContentView() {
-        val coroutineScope = rememberCoroutineScope()
-        val context = LocalContext.current
-
-        internetDetailsContentManager = remember {
-            contentManagerFactory.create(
-                canConfigMobileData = accessPointController.canConfigMobileData(),
-                canConfigWifi = accessPointController.canConfigWifi(),
-                coroutineScope = coroutineScope,
-                context = context,
-            )
-        }
-        AndroidView(
-            modifier = Modifier.fillMaxWidth().fillMaxHeight(),
-            factory = { context ->
-                // Inflate with the existing dialog xml layout and bind it with the manager
-                val view =
-                    LayoutInflater.from(context)
-                        .inflate(R.layout.internet_connectivity_dialog, null)
-                internetDetailsContentManager.bind(view)
-
-                view
-                // TODO: b/377388104 - Polish the internet details view UI
-            },
-            onRelease = {
-                internetDetailsContentManager.unBind()
-                if (DEBUG) {
-                    Log.d(TAG, "onRelease")
-                }
-            },
-        )
-    }
-
     override fun clickOnSettingsButton() {
         onLongClick()
     }
@@ -96,13 +49,16 @@
         return "Tab a network to connect"
     }
 
+    fun getCanConfigMobileData(): Boolean {
+        return accessPointController.canConfigMobileData()
+    }
+
+    fun getCanConfigWifi(): Boolean {
+        return accessPointController.canConfigWifi()
+    }
+
     @AssistedFactory
     interface Factory {
         fun create(onLongClick: () -> Unit): InternetDetailsViewModel
     }
-
-    companion object {
-        private const val TAG = "InternetDetailsVModel"
-        private val DEBUG: Boolean = Log.isLoggable(TAG, Log.DEBUG)
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ModesDetailsContent.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ModesDetailsContent.kt
new file mode 100644
index 0000000..c5ecaff
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ModesDetailsContent.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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.dialog
+
+import androidx.compose.runtime.Composable
+import com.android.systemui.statusbar.policy.ui.dialog.composable.ModeTileGrid
+
+@Composable
+fun ModesDetailsContent(viewModel: ModesDetailsViewModel) {
+    // TODO(b/378513940): Finish implementing this function.
+    ModeTileGrid(viewModel = viewModel.viewModel)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ModesDetailsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ModesDetailsViewModel.kt
index 511597d..9a39c3c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ModesDetailsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ModesDetailsViewModel.kt
@@ -16,22 +16,14 @@
 
 package com.android.systemui.qs.tiles.dialog
 
-import androidx.compose.runtime.Composable
 import com.android.systemui.plugins.qs.TileDetailsViewModel
-import com.android.systemui.statusbar.policy.ui.dialog.composable.ModeTileGrid
 import com.android.systemui.statusbar.policy.ui.dialog.viewmodel.ModesDialogViewModel
 
 /** The view model used for the modes details view in the Quick Settings */
 class ModesDetailsViewModel(
     private val onSettingsClick: () -> Unit,
-    private val viewModel: ModesDialogViewModel,
+    val viewModel: ModesDialogViewModel,
 ) : TileDetailsViewModel() {
-    @Composable
-    override fun GetContentView() {
-        // TODO(b/378513940): Finish implementing this function.
-        ModeTileGrid(viewModel = viewModel)
-    }
-
     override fun clickOnSettingsButton() {
         onSettingsClick()
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsContent.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsContent.kt
new file mode 100644
index 0000000..bf1a51d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsContent.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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.dialog
+
+import android.view.LayoutInflater
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.viewinterop.AndroidView
+import com.android.systemui.res.R
+import com.android.systemui.screenrecord.ScreenRecordPermissionViewBinder
+
+@Composable
+fun ScreenRecordDetailsContent(viewModel: ScreenRecordDetailsViewModel) {
+    // TODO(b/378514312): Finish implementing this function.
+
+    if (viewModel.recordingController.isScreenCaptureDisabled) {
+        // TODO(b/388345506): Show disabled page here.
+        return
+    }
+
+    val viewBinder: ScreenRecordPermissionViewBinder = remember {
+        viewModel.recordingController.createScreenRecordPermissionViewBinder(
+            viewModel.onStartRecordingClicked
+        )
+    }
+
+    AndroidView(
+        modifier = Modifier.fillMaxWidth().fillMaxHeight(),
+        factory = { context ->
+            // Inflate with the existing dialog xml layout
+            val view = LayoutInflater.from(context).inflate(R.layout.screen_share_dialog, null)
+            viewBinder.bind(view)
+
+            view
+            // TODO(b/378514473): Revamp the details view according to the spec.
+        },
+        onRelease = { viewBinder.unbind() },
+    )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt
index 54e4a52..c84ddb6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt
@@ -16,49 +16,15 @@
 
 package com.android.systemui.qs.tiles.dialog
 
-import android.view.LayoutInflater
-import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.viewinterop.AndroidView
 import com.android.systemui.plugins.qs.TileDetailsViewModel
-import com.android.systemui.res.R
 import com.android.systemui.screenrecord.RecordingController
-import com.android.systemui.screenrecord.ScreenRecordPermissionViewBinder
 
 /** The view model used for the screen record details view in the Quick Settings */
 class ScreenRecordDetailsViewModel(
-    private val recordingController: RecordingController,
-    private val onStartRecordingClicked: Runnable,
+    val recordingController: RecordingController,
+    val onStartRecordingClicked: Runnable,
 ) : TileDetailsViewModel() {
 
-    private var viewBinder: ScreenRecordPermissionViewBinder =
-        recordingController.createScreenRecordPermissionViewBinder(onStartRecordingClicked)
-
-    @Composable
-    override fun GetContentView() {
-        // TODO(b/378514312): Finish implementing this function.
-
-        if (recordingController.isScreenCaptureDisabled) {
-            // TODO(b/388345506): Show disabled page here.
-            return
-        }
-
-        AndroidView(
-            modifier = Modifier.fillMaxWidth().fillMaxHeight(),
-            factory = { context ->
-                // Inflate with the existing dialog xml layout
-                val view = LayoutInflater.from(context).inflate(R.layout.screen_share_dialog, null)
-                viewBinder.bind(view)
-
-                view
-                // TODO(b/378514473): Revamp the details view according to the spec.
-            },
-            onRelease = { viewBinder.unbind() },
-        )
-    }
-
     override fun clickOnSettingsButton() {
         // No settings button in this tile.
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt
index b5da044..ab1326a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt
@@ -21,6 +21,7 @@
 import android.util.Log
 import com.android.systemui.animation.Expandable
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.qs.flags.QSComposeFragment
 import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
 import com.android.systemui.qs.tiles.base.interactor.QSTileInput
@@ -31,11 +32,14 @@
 import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogDelegate
 import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogEventLogger
 import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.withContext
 
 @SysUISingleton
 class ModesTileUserActionInteractor
 @Inject
 constructor(
+    @Main private val mainContext: CoroutineContext,
     private val qsTileIntentUserInputHandler: QSTileIntentUserInputHandler,
     // TODO(b/353896370): The domain layer should not have to depend on the UI layer.
     private val dialogDelegate: ModesDialogDelegate,
@@ -65,7 +69,7 @@
         dialogDelegate.showDialog(expandable)
     }
 
-    fun handleToggleClick(modesTileModel: ModesTileModel) {
+    suspend fun handleToggleClick(modesTileModel: ModesTileModel) {
         if (QSComposeFragment.isUnexpectedlyInLegacyMode()) {
             return
         }
@@ -83,9 +87,11 @@
 
             if (zenModeInteractor.shouldAskForZenDuration(dnd)) {
                 dialogEventLogger.logOpenDurationDialog(dnd)
-                // NOTE: The dialog handles turning on the mode itself.
-                val dialog = dialogDelegate.makeDndDurationDialog()
-                dialog.show()
+                withContext(mainContext) {
+                    // NOTE: The dialog handles turning on the mode itself.
+                    val dialog = dialogDelegate.makeDndDurationDialog()
+                    dialog.show()
+                }
             } else {
                 dialogEventLogger.logModeOn(dnd)
                 zenModeInteractor.activateMode(dnd)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt
index d4adcdd..a97bb61 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt
@@ -38,7 +38,7 @@
 import com.android.systemui.res.R
 import com.android.systemui.settings.brightness.MirrorController
 import com.android.systemui.shade.ShadeDisplayAware
-import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.util.kotlin.sample
 import java.io.PrintWriter
@@ -202,7 +202,7 @@
 constructor(
     private val qsSceneComponentFactory: QSSceneComponent.Factory,
     private val qsImplProvider: Provider<QSImpl>,
-    shadeInteractor: ShadeInteractor,
+    shadeModeInteractor: ShadeModeInteractor,
     displayStateInteractor: DisplayStateInteractor,
     dumpManager: DumpManager,
     @Main private val mainDispatcher: CoroutineDispatcher,
@@ -215,7 +215,7 @@
     constructor(
         qsSceneComponentFactory: QSSceneComponent.Factory,
         qsImplProvider: Provider<QSImpl>,
-        shadeInteractor: ShadeInteractor,
+        shadeModeInteractor: ShadeModeInteractor,
         displayStateInteractor: DisplayStateInteractor,
         dumpManager: DumpManager,
         @Main dispatcher: CoroutineDispatcher,
@@ -224,7 +224,7 @@
     ) : this(
         qsSceneComponentFactory,
         qsImplProvider,
-        shadeInteractor,
+        shadeModeInteractor,
         displayStateInteractor,
         dumpManager,
         dispatcher,
@@ -331,8 +331,8 @@
                 }
             }
             launch {
-                shadeInteractor.shadeMode.collect {
-                    qsImpl.value?.setInSplitShade(it == ShadeMode.Split)
+                shadeModeInteractor.shadeMode.collect {
+                    qsImpl.value?.setInSplitShade(it is ShadeMode.Split)
                 }
             }
             launch {
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 c7db04a..aa8e424 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,43 +19,52 @@
 import androidx.compose.runtime.getValue
 import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel
 import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.lifecycle.Hydrator
 import com.android.systemui.qs.panels.ui.viewmodel.DetailsViewModel
 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 com.android.systemui.qs.panels.ui.viewmodel.toolbar.ToolbarViewModel
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import kotlinx.coroutines.awaitCancellation
 import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.launch
 
 class QuickSettingsContainerViewModel
 @AssistedInject
 constructor(
     brightnessSliderViewModelFactory: BrightnessSliderViewModel.Factory,
-    quickQuickSettingsViewModelFactory: QuickQuickSettingsViewModel.Factory,
     shadeHeaderViewModelFactory: ShadeHeaderViewModel.Factory,
     @Assisted supportsBrightnessMirroring: Boolean,
     val tileGridViewModel: TileGridViewModel,
     val editModeViewModel: EditModeViewModel,
     val detailsViewModel: DetailsViewModel,
     val toolbarViewModelFactory: ToolbarViewModel.Factory,
+    shadeModeInteractor: ShadeModeInteractor,
 ) : ExclusiveActivatable() {
 
+    private val hydrator = Hydrator("QuickSettingsContainerViewModel.hydrator")
+
     val brightnessSliderViewModel =
         brightnessSliderViewModelFactory.create(supportsBrightnessMirroring)
 
-    val quickQuickSettingsViewModel = quickQuickSettingsViewModelFactory.create()
-
     val shadeHeaderViewModel = shadeHeaderViewModelFactory.create()
 
+    val showHeader: Boolean by
+        hydrator.hydratedStateOf(
+            traceName = "showHeader",
+            initialValue = !shadeModeInteractor.isShadeLayoutWide.value,
+            source = shadeModeInteractor.isShadeLayoutWide.map { !it },
+        )
+
     override suspend fun onActivated(): Nothing {
         coroutineScope {
+            launch { hydrator.activate() }
             launch { brightnessSliderViewModel.activate() }
-            launch { quickQuickSettingsViewModel.activate() }
             launch { shadeHeaderViewModel.activate() }
             awaitCancellation()
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneContentViewModel.kt
index 06d3e4a..acd091e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneContentViewModel.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.qs.ui.viewmodel
 
 import androidx.lifecycle.LifecycleOwner
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
 import com.android.systemui.qs.FooterActionsController
@@ -25,7 +26,7 @@
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.settings.brightness.ui.viewModel.BrightnessMirrorViewModel
-import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel
 import dagger.assisted.AssistedFactory
@@ -34,7 +35,6 @@
 import kotlinx.coroutines.awaitCancellation
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.flow.StateFlow
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 /**
  * Models UI state needed for rendering the content of the quick settings scene.
@@ -51,7 +51,7 @@
     private val footerActionsViewModelFactory: FooterActionsViewModel.Factory,
     private val footerActionsController: FooterActionsController,
     val mediaCarouselInteractor: MediaCarouselInteractor,
-    private val shadeInteractor: ShadeInteractor,
+    private val shadeModeInteractor: ShadeModeInteractor,
     private val sceneInteractor: SceneInteractor,
 ) : ExclusiveActivatable() {
 
@@ -69,8 +69,8 @@
     override suspend fun onActivated(): Nothing {
         coroutineScope {
             launch {
-                shadeInteractor.shadeMode.collect { shadeMode ->
-                    if (shadeMode == ShadeMode.Split) {
+                shadeModeInteractor.shadeMode.collect { shadeMode ->
+                    if (shadeMode is ShadeMode.Split) {
                         sceneInteractor.snapToScene(Scenes.Shade, "Unfold while on QS")
                     }
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModel.kt
index d9df1ef..0add3f5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModel.kt
@@ -16,13 +16,10 @@
 
 package com.android.systemui.qs.ui.viewmodel
 
-import androidx.compose.runtime.getValue
 import com.android.systemui.lifecycle.ExclusiveActivatable
-import com.android.systemui.lifecycle.Hydrator
 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.shade.ui.viewmodel.ShadeHeaderViewModel
 import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
 import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape
 import dagger.assisted.AssistedFactory
@@ -31,7 +28,6 @@
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.filter
-import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.launch
 
 /**
@@ -46,39 +42,10 @@
     val shadeInteractor: ShadeInteractor,
     val sceneInteractor: SceneInteractor,
     val notificationStackAppearanceInteractor: NotificationStackAppearanceInteractor,
-    val shadeHeaderViewModelFactory: ShadeHeaderViewModel.Factory,
-    quickSettingsContainerViewModelFactory: QuickSettingsContainerViewModel.Factory,
 ) : ExclusiveActivatable() {
 
-    private val hydrator = Hydrator("QuickSettingsContainerViewModel.hydrator")
-
-    val isShadeLayoutWide: Boolean by
-        hydrator.hydratedStateOf(
-            traceName = "isShadeLayoutWide",
-            initialValue = shadeInteractor.isShadeLayoutWide.value,
-            source = shadeInteractor.isShadeLayoutWide,
-        )
-
-    val showHeader: Boolean by
-        hydrator.hydratedStateOf(
-            traceName = "showHeader",
-            initialValue = !shadeInteractor.isShadeLayoutWide.value,
-            source = shadeInteractor.isShadeLayoutWide.map { !it },
-        )
-
-    val quickSettingsContainerViewModel = quickSettingsContainerViewModelFactory.create(false)
-
-    val showQuickSettingsOverlayHeader: Boolean by
-        hydrator.hydratedStateOf(
-            traceName = "showQuickSettingsOverlayHeader",
-            initialValue = shadeInteractor.isShadeLayoutWide.value,
-            source = shadeInteractor.isShadeLayoutWide,
-        )
-
     override suspend fun onActivated(): Nothing {
         coroutineScope {
-            launch { hydrator.activate() }
-
             launch {
                 sceneInteractor.currentScene.collect { currentScene ->
                     when (currentScene) {
@@ -101,8 +68,6 @@
                         )
                     }
             }
-
-            launch { quickSettingsContainerViewModel.activate() }
         }
 
         awaitCancellation()
diff --git a/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
index e36e40d..a4949ad 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.scene.ui.composable.SceneContainerTransitions
 import com.android.systemui.scene.ui.viewmodel.SplitEdgeDetector
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
-import com.android.systemui.shade.shared.flag.DualShade
 import dagger.Binds
 import dagger.Module
 import dagger.Provides
@@ -90,29 +89,14 @@
         @Provides
         fun containerConfig(): SceneContainerConfig {
             return SceneContainerConfig(
-                // Note that this list is in z-order. The first one is the bottom-most and the
-                // last one is top-most.
-                sceneKeys =
-                    listOfNotNull(
-                        Scenes.Gone,
-                        Scenes.QuickSettings.takeUnless { DualShade.isEnabled },
-                        Scenes.Shade.takeUnless { DualShade.isEnabled },
-                    ),
+                // Note that this list is in z-order. The first one is the bottom-most and the last
+                // one is top-most.
+                sceneKeys = listOf(Scenes.Gone, Scenes.QuickSettings, Scenes.Shade),
                 initialSceneKey = Scenes.Gone,
-                transitions = SceneContainerTransitions,
-                overlayKeys =
-                    listOfNotNull(
-                        Overlays.NotificationsShade.takeIf { DualShade.isEnabled },
-                        Overlays.QuickSettingsShade.takeIf { DualShade.isEnabled },
-                    ),
+                overlayKeys = listOf(Overlays.NotificationsShade, Overlays.QuickSettingsShade),
                 navigationDistances =
-                    mapOf(
-                            Scenes.Gone to 0,
-                            Scenes.Shade to 1.takeUnless { DualShade.isEnabled },
-                            Scenes.QuickSettings to 2.takeUnless { DualShade.isEnabled },
-                        )
-                        .filterValues { it != null }
-                        .mapValues { checkNotNull(it.value) },
+                    mapOf(Scenes.Gone to 0, Scenes.Shade to 1, Scenes.QuickSettings to 2),
+                transitionsBuilder = SceneContainerTransitions(),
             )
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
index fe01452..a018283 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.scene.ui.composable.SceneContainerTransitions
 import com.android.systemui.scene.ui.viewmodel.SplitEdgeDetector
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
-import com.android.systemui.shade.shared.flag.DualShade
 import dagger.Binds
 import dagger.Module
 import dagger.Provides
@@ -103,28 +102,23 @@
                         Scenes.Dream,
                         Scenes.Lockscreen,
                         Scenes.Bouncer,
-                        Scenes.QuickSettings.takeUnless { DualShade.isEnabled },
-                        Scenes.Shade.takeUnless { DualShade.isEnabled },
+                        Scenes.QuickSettings,
+                        Scenes.Shade,
                     ),
                 initialSceneKey = Scenes.Lockscreen,
-                transitions = SceneContainerTransitions,
                 overlayKeys =
-                    listOfNotNull(
-                        Overlays.NotificationsShade.takeIf { DualShade.isEnabled },
-                        Overlays.QuickSettingsShade.takeIf { DualShade.isEnabled },
-                    ),
+                    listOfNotNull(Overlays.NotificationsShade, Overlays.QuickSettingsShade),
                 navigationDistances =
                     mapOf(
-                            Scenes.Gone to 0,
-                            Scenes.Lockscreen to 0,
-                            Scenes.Communal to 1,
-                            Scenes.Dream to 2,
-                            Scenes.Shade to 3.takeUnless { DualShade.isEnabled },
-                            Scenes.QuickSettings to 4.takeUnless { DualShade.isEnabled },
-                            Scenes.Bouncer to 5,
-                        )
-                        .filterValues { it != null }
-                        .mapValues { checkNotNull(it.value) },
+                        Scenes.Gone to 0,
+                        Scenes.Lockscreen to 0,
+                        Scenes.Communal to 1,
+                        Scenes.Dream to 2,
+                        Scenes.Shade to 3,
+                        Scenes.QuickSettings to 4,
+                        Scenes.Bouncer to 5,
+                    ),
+                transitionsBuilder = SceneContainerTransitions(),
             )
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
index c1646b8..8845bb7 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
@@ -45,14 +45,14 @@
     @Provides
     fun containerConfig(): SceneContainerConfig {
         return SceneContainerConfig(
-            // Note that this list is in z-order. The first one is the bottom-most and the
-            // last one is top-most.
+            // Note that this list is in z-order. The first one is the bottom-most and the last one
+            // is top-most.
             sceneKeys = listOf(Scenes.Gone, Scenes.Lockscreen, Scenes.Bouncer),
             initialSceneKey = Scenes.Lockscreen,
-            transitions = SceneContainerTransitions,
             overlayKeys = emptyList(),
             navigationDistances =
                 mapOf(Scenes.Gone to 0, Scenes.Lockscreen to 0, Scenes.Bouncer to 1),
+            transitionsBuilder = SceneContainerTransitions(),
         )
     }
 }
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 2fd5841..94e32fc 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
@@ -44,6 +44,7 @@
 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.TrustInteractor
 import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor.Companion.keyguardScenes
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.model.SceneContainerPlugin
@@ -148,6 +149,7 @@
     private val activityTransitionAnimator: ActivityTransitionAnimator,
     private val shadeModeInteractor: ShadeModeInteractor,
     @SceneFrameworkTableLog private val tableLogBuffer: TableLogBuffer,
+    private val trustInteractor: TrustInteractor,
 ) : CoreStartable {
     private val centralSurfaces: CentralSurfaces?
         get() = centralSurfacesOptLazy.get().getOrNull()
@@ -173,6 +175,7 @@
             notifyKeyguardDismissCancelledCallbacks()
             refreshLockscreenEnabled()
             hydrateActivityTransitionAnimationState()
+            lockWhenDeviceBecomesUntrusted()
         } else {
             sceneLogger.logFrameworkEnabled(
                 isEnabled = false,
@@ -998,6 +1001,18 @@
         )
     }
 
+    private fun lockWhenDeviceBecomesUntrusted() {
+        applicationScope.launch {
+            trustInteractor.isTrusted.pairwise().collect { (wasTrusted, isTrusted) ->
+                if (wasTrusted && !isTrusted && !deviceEntryInteractor.isDeviceEntered.value) {
+                    deviceEntryInteractor.lockNow(
+                        "Exited trusted environment while not device not entered"
+                    )
+                }
+            }
+        }
+    }
+
     companion object {
         private const val TAG = "SceneContainerStartable"
     }
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfig.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfig.kt
index ce7be83..c7ceea2 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfig.kt
@@ -18,7 +18,7 @@
 
 import com.android.compose.animation.scene.OverlayKey
 import com.android.compose.animation.scene.SceneKey
-import com.android.compose.animation.scene.SceneTransitions
+import com.android.systemui.scene.ui.composable.SceneContainerTransitionsBuilder
 
 /** Models the configuration of the scene container. */
 data class SceneContainerConfig(
@@ -39,9 +39,6 @@
      */
     val initialSceneKey: SceneKey,
 
-    /** Transition definitions to be used when animating between scene transitions. */
-    val transitions: SceneTransitions,
-
     /**
      * The keys to all overlays in the container, sorted by z-order such that the last one renders
      * on top of all previous ones. Overlay keys within the same container must not repeat but it's
@@ -66,6 +63,12 @@
      * of scenes in the [sceneKeys] list.
      */
     val navigationDistances: Map<SceneKey, Int>,
+
+    /**
+     * Builds the comprehensive definition of all transitions between scenes and overlays in the
+     * scene container.
+     */
+    val transitionsBuilder: SceneContainerTransitionsBuilder,
 ) {
     init {
         check(sceneKeys.isNotEmpty()) { "A container must have at least one scene key." }
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
index ffc8268..7977387 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
@@ -183,7 +183,7 @@
                             sceneByKey = sceneByKey,
                             overlayByKey = overlayByKey,
                             initialSceneKey = containerConfig.initialSceneKey,
-                            sceneTransitions = containerConfig.transitions,
+                            transitionsBuilder = containerConfig.transitionsBuilder,
                             dataSourceDelegator = dataSourceDelegator,
                             qsSceneAdapter = qsSceneAdapter,
                             sceneJankMonitorFactory = sceneJankMonitorFactory,
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModel.kt
index fc172e8..8eac63c 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneUserActionsViewModel.kt
@@ -18,7 +18,7 @@
 
 import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
-import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.shade.ui.viewmodel.dualShadeActions
 import com.android.systemui.shade.ui.viewmodel.singleShadeActions
@@ -28,10 +28,10 @@
 
 class GoneUserActionsViewModel
 @AssistedInject
-constructor(private val shadeInteractor: ShadeInteractor) : UserActionsViewModel() {
+constructor(private val shadeModeInteractor: ShadeModeInteractor) : UserActionsViewModel() {
 
     override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
-        shadeInteractor.shadeMode.collect { shadeMode ->
+        shadeModeInteractor.shadeMode.collect { shadeMode ->
             setActions(
                 buildList {
                         addAll(
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerHapticsViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerHapticsViewModel.kt
index 4ef8e0f..66ff6f9 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerHapticsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerHapticsViewModel.kt
@@ -18,12 +18,16 @@
 
 import android.view.HapticFeedbackConstants
 import android.view.View
+import androidx.compose.ui.hapticfeedback.HapticFeedback
+import androidx.compose.ui.hapticfeedback.HapticFeedbackType
 import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.reveal.ContainerRevealHaptics
 import com.android.systemui.Flags
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.model.Overlays
 import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.ui.composable.SceneContainer
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.google.android.msdl.data.model.MSDLToken
 import com.google.android.msdl.domain.MSDLPlayer
@@ -34,6 +38,7 @@
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.filter
 
 /**
  * Models haptics UI state for the scene container.
@@ -60,16 +65,36 @@
             .distinctUntilChanged()
 
     override suspend fun onActivated(): Nothing {
-        isShadePullHapticsRequired.collect { playShadePullHaptics ->
-            if (!playShadePullHaptics) return@collect
+        playShadePullHaptics()
+        awaitCancellation()
+    }
 
-            if (Flags.msdlFeedback()) {
-                msdlPlayer.playToken(MSDLToken.SWIPE_THRESHOLD_INDICATOR)
-            } else {
-                view.performHapticFeedback(HapticFeedbackConstants.GESTURE_START)
+    /**
+     * Returns a handler for reveal transition haptics in [SceneContainer] for the given
+     * [hapticFeedback] target.
+     */
+    fun getRevealHaptics(hapticFeedback: HapticFeedback): ContainerRevealHaptics {
+        return object : ContainerRevealHaptics {
+            override fun onRevealThresholdCrossed(revealed: Boolean) {
+                if (revealed) {
+                    hapticFeedback.performHapticFeedback(
+                        HapticFeedbackType.GestureThresholdActivate
+                    )
+                }
             }
         }
-        awaitCancellation()
+    }
+
+    private suspend fun playShadePullHaptics() {
+        isShadePullHapticsRequired
+            .filter { it }
+            .collect {
+                if (Flags.msdlFeedback()) {
+                    msdlPlayer.playToken(MSDLToken.SWIPE_THRESHOLD_INDICATOR)
+                } else {
+                    view.performHapticFeedback(HapticFeedbackConstants.GESTURE_START)
+                }
+            }
     }
 
     private fun ObservableTransitionState.isValidForShadePullHaptics(): Boolean {
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 40e6d28..fbcd8ea 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
@@ -30,6 +30,7 @@
 import com.android.compose.animation.scene.UserActionResult
 import com.android.systemui.classifier.Classifier
 import com.android.systemui.classifier.domain.interactor.FalsingInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.lifecycle.Hydrator
@@ -38,7 +39,7 @@
 import com.android.systemui.scene.shared.logger.SceneLogger
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.composable.Overlay
-import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.statusbar.domain.interactor.RemoteInputInteractor
 import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
@@ -59,13 +60,14 @@
     private val sceneInteractor: SceneInteractor,
     private val falsingInteractor: FalsingInteractor,
     private val powerInteractor: PowerInteractor,
-    shadeInteractor: ShadeInteractor,
+    shadeModeInteractor: ShadeModeInteractor,
     private val remoteInputInteractor: RemoteInputInteractor,
     private val splitEdgeDetector: SplitEdgeDetector,
     private val logger: SceneLogger,
     hapticsViewModelFactory: SceneContainerHapticsViewModel.Factory,
     val lightRevealScrim: LightRevealScrimViewModel,
     val wallpaperViewModel: WallpaperViewModel,
+    keyguardInteractor: KeyguardInteractor,
     @Assisted view: View,
     @Assisted private val motionEventHandlerReceiver: (MotionEventHandler?) -> Unit,
 ) : ExclusiveActivatable() {
@@ -80,7 +82,7 @@
 
     val allContentKeys: List<ContentKey> = sceneInteractor.allContentKeys
 
-    private val hapticsViewModel = hapticsViewModelFactory.create(view)
+    val hapticsViewModel: SceneContainerHapticsViewModel = hapticsViewModelFactory.create(view)
 
     /**
      * The [SwipeSourceDetector] to use for defining which edges of the screen can be defined in the
@@ -91,11 +93,19 @@
             traceName = "edgeDetector",
             initialValue = DefaultEdgeDetector,
             source =
-                shadeInteractor.shadeMode.map {
+                shadeModeInteractor.shadeMode.map {
                     if (it is ShadeMode.Dual) splitEdgeDetector else DefaultEdgeDetector
                 },
         )
 
+    /** Amount of color saturation for the Flexi🥃 ribbon. */
+    val ribbonColorSaturation: Float by
+        hydrator.hydratedStateOf(
+            traceName = "ribbonColorSaturation",
+            source = keyguardInteractor.dozeAmount.map { 1 - it },
+            initialValue = 1f,
+        )
+
     override suspend fun onActivated(): Nothing {
         try {
             // Sends a MotionEventHandler to the owner of the view-model so they can report
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsService.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsService.java
index 3bca4e4..1a91afc 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsService.java
@@ -152,8 +152,8 @@
                     return CAPTURE_CONTENT_FOR_NOTE_FAILED;
                 }
 
-                if (!mOptionalBubbles.get().isAppBubbleTaskId(taskId)) {
-                    Log.d(TAG, String.format("Taskid %d is not app bubble task", taskId));
+                if (!mOptionalBubbles.get().isNoteBubbleTaskId(taskId)) {
+                    Log.d(TAG, String.format("Taskid %d is not note bubble task", taskId));
                     return CAPTURE_CONTENT_FOR_NOTE_WINDOW_MODE_UNSUPPORTED;
                 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
index a48d4d4..1f02d5a 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
@@ -151,7 +151,7 @@
 
         registerUserSwitchObserver()
 
-        dumpManager.registerDumpable(TAG, this)
+        dumpManager.registerNormalDumpable(TAG, this)
     }
 
     override fun onReceive(context: Context, intent: Intent) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 28f5694..e535019 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -527,6 +527,9 @@
     private final ActivityStarter mActivityStarter;
     private final BrightnessMirrorShowingInteractor mBrightnessMirrorShowingInteractor;
 
+    @Nullable
+    private RenderEffect mBlurRenderEffect = null;
+
     @Inject
     public NotificationPanelViewController(NotificationPanelView view,
             NotificationWakeUpCoordinator coordinator,
@@ -912,13 +915,14 @@
 
     private void handleBouncerShowingChanged(Boolean isBouncerShowing) {
         if (!com.android.systemui.Flags.bouncerUiRevamp()) return;
-
         if (isBouncerShowing && isExpanded()) {
-            float shadeBlurEffect = mDepthController.getMaxBlurRadiusPx();
-            mView.setRenderEffect(RenderEffect.createBlurEffect(
-                    shadeBlurEffect,
-                    shadeBlurEffect,
-                    Shader.TileMode.CLAMP));
+            if (mBlurRenderEffect == null) {
+                mBlurRenderEffect = RenderEffect.createBlurEffect(
+                        mDepthController.getMaxBlurRadiusPx(),
+                        mDepthController.getMaxBlurRadiusPx(),
+                        Shader.TileMode.CLAMP);
+            }
+            mView.setRenderEffect(mBlurRenderEffect);
         } else {
             mView.setRenderEffect(null);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
index cf310dd..5b44c08 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
@@ -39,6 +39,7 @@
 import com.android.systemui.res.R
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shared.system.QuickStepContract
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.statusbar.policy.SplitShadeStateController
 import com.android.systemui.util.LargeScreenUtils
@@ -155,8 +156,7 @@
         val splitShadeEnabledChanged = newSplitShadeEnabled != splitShadeEnabled
         splitShadeEnabled = newSplitShadeEnabled
         largeScreenShadeHeaderActive = LargeScreenUtils.shouldUseLargeScreenShadeHeader(resources)
-        notificationsBottomMargin =
-            resources.getDimensionPixelSize(R.dimen.notification_panel_margin_bottom)
+        notificationsBottomMargin = NotificationStackScrollLayout.getBottomMargin(context)
         largeScreenShadeHeaderHeight = calculateLargeShadeHeaderHeight()
         shadeHeaderHeight = calculateShadeHeaderHeight()
         panelMarginHorizontal =
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeStateTraceLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeStateTraceLogger.kt
index 39703ab..6b183ac 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeStateTraceLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeStateTraceLogger.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.shade.data.repository.ShadeDisplaysRepository
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
 import dagger.Lazy
 import javax.inject.Inject
@@ -36,6 +37,7 @@
 @Inject
 constructor(
     private val shadeInteractor: ShadeInteractor,
+    private val shadeModeInteractor: ShadeModeInteractor,
     private val shadeDisplaysRepository: Lazy<ShadeDisplaysRepository>,
     @Application private val scope: CoroutineScope,
 ) : CoreStartable {
@@ -47,7 +49,7 @@
             }
             launch {
                 val stateLogger = createTraceStateLogger("shadeMode")
-                shadeInteractor.shadeMode.collect { stateLogger.log(it.toString()) }
+                shadeModeInteractor.shadeMode.collect { stateLogger.log(it.toString()) }
             }
             launch {
                 shadeInteractor.shadeExpansion.collect {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImpl.kt
index 5a63034..6eaedd7 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImpl.kt
@@ -20,7 +20,6 @@
 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.shared.model.ShadeMode
 import javax.inject.Inject
 
 /** Implementation of ShadeBackActionInteractor backed by scenes. */
@@ -28,13 +27,14 @@
 @Inject
 constructor(
     val shadeInteractor: ShadeInteractor,
+    val shadeModeInteractor: ShadeModeInteractor,
     val sceneInteractor: SceneInteractor,
     val deviceEntryInteractor: DeviceEntryInteractor,
 ) : ShadeBackActionInteractor {
     override fun animateCollapseQs(fullyCollapse: Boolean) {
         if (shadeInteractor.isQsExpanded.value) {
             val key =
-                if (fullyCollapse || shadeInteractor.shadeMode.value is ShadeMode.Dual) {
+                if (fullyCollapse || shadeModeInteractor.isDualShade) {
                     SceneFamilies.Home
                 } else {
                     Scenes.Shade
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 f1765e7..c8ce316 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
@@ -18,7 +18,6 @@
 
 import androidx.annotation.FloatRange
 import com.android.compose.animation.scene.TransitionKey
-import com.android.systemui.shade.shared.model.ShadeMode
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
@@ -60,13 +59,6 @@
     val isExpandToQsEnabled: Flow<Boolean>
 
     /**
-     * The version of the shade layout to use.
-     *
-     * Note: Most likely, you want to read [isShadeLayoutWide] instead of this.
-     */
-    val shadeMode: StateFlow<ShadeMode>
-
-    /**
      * Whether the shade layout should be wide (true) or narrow (false).
      *
      * In a wide layout, notifications and quick settings each take up only half the screen width
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 322fca3..b1129a9 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
@@ -18,7 +18,6 @@
 
 import com.android.compose.animation.scene.TransitionKey
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.shade.shared.model.ShadeMode
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -47,7 +46,6 @@
     override val isUserInteracting: StateFlow<Boolean> = inactiveFlowBoolean
     override val isShadeTouchable: Flow<Boolean> = inactiveFlowBoolean
     override val isExpandToQsEnabled: Flow<Boolean> = inactiveFlowBoolean
-    override val shadeMode: StateFlow<ShadeMode> = MutableStateFlow(ShadeMode.Single)
     override val isShadeLayoutWide: StateFlow<Boolean> = inactiveFlowBoolean
 
     override fun getTopEdgeSplitFraction(): Float = 0.5f
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 b5e1710..9d81be2 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
@@ -42,7 +42,7 @@
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.stateIn
 
-/** The non-empty SceneInteractor implementation. */
+/** The non-empty [ShadeInteractor] implementation. */
 @SysUISingleton
 class ShadeInteractorImpl
 @Inject
@@ -100,30 +100,25 @@
 
     override val isShadeTouchable: Flow<Boolean> =
         combine(
-            powerInteractor.isAsleep
-                .onEach { Log.d(TAG, "isShadeTouchable: upstream isAsleep=$it") },
+            powerInteractor.isAsleep.onEach {
+                Log.d(TAG, "isShadeTouchable: upstream isAsleep=$it")
+            },
             keyguardTransitionInteractor
                 .isInTransition(Edge.create(to = KeyguardState.AOD))
-                .onEach {
-                    Log.d(
-                        TAG,
-                        "isShadeTouchable: upstream isTransitioningToAod=$it",
-                    )
-                },
+                .onEach { Log.d(TAG, "isShadeTouchable: upstream isTransitioningToAod=$it") },
             keyguardRepository.dozeTransitionModel
                 .map { it.to == DozeStateModel.DOZE_PULSING }
-                .onEach {
-                    Log.d(TAG, "isShadeTouchable: upstream isPulsing=$it")
-                },
+                .onEach { Log.d(TAG, "isShadeTouchable: upstream isPulsing=$it") },
         ) { isAsleep, isTransitioningToAod, isPulsing ->
-            val downstream = when {
-                // If the device is transitioning to AOD, only accept touches if
-                // still animating.
-                isTransitioningToAod -> dozeParams.shouldControlScreenOff()
-                // If the device is asleep, only accept touches if there's a pulse
-                isAsleep -> isPulsing
-                else -> true
-            }
+            val downstream =
+                when {
+                    // If the device is transitioning to AOD, only accept touches if
+                    // still animating.
+                    isTransitioningToAod -> dozeParams.shouldControlScreenOff()
+                    // If the device is asleep, only accept touches if there's a pulse
+                    isAsleep -> isPulsing
+                    else -> true
+                }
             Log.d(TAG, "isShadeTouchable emitting $downstream, values:")
             Log.d(TAG, "  isAsleep=$isAsleep")
             Log.d(TAG, "  isTransitioningToAod=$isTransitioningToAod")
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt
index 661f2ae..246177e 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt
@@ -35,6 +35,7 @@
 import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
 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.StateFlow
@@ -45,6 +46,7 @@
 import kotlinx.coroutines.flow.stateIn
 
 /** ShadeInteractor implementation for Scene Container. */
+@OptIn(ExperimentalCoroutinesApi::class)
 @SysUISingleton
 class ShadeInteractorSceneContainerImpl
 @Inject
@@ -137,20 +139,18 @@
 
     override fun expandNotificationsShade(loggingReason: String, transitionKey: TransitionKey?) {
         if (shadeModeInteractor.isDualShade) {
-            if (Overlays.QuickSettingsShade in sceneInteractor.currentOverlays.value) {
-                sceneInteractor.replaceOverlay(
-                    from = Overlays.QuickSettingsShade,
-                    to = Overlays.NotificationsShade,
-                    loggingReason = loggingReason,
-                    transitionKey = transitionKey,
-                )
-            } else {
-                sceneInteractor.showOverlay(
-                    overlay = Overlays.NotificationsShade,
-                    loggingReason = loggingReason,
-                    transitionKey = transitionKey,
-                )
-            }
+            // Collapse the quick settings shade if it's expanded (no-op if it isn't).
+            sceneInteractor.hideOverlay(
+                overlay = Overlays.QuickSettingsShade,
+                loggingReason = loggingReason,
+                transitionKey = transitionKey,
+            )
+            // Expand the notifications shade.
+            sceneInteractor.showOverlay(
+                overlay = Overlays.NotificationsShade,
+                loggingReason = loggingReason,
+                transitionKey = transitionKey,
+            )
         } else {
             sceneInteractor.changeScene(
                 toScene = Scenes.Shade,
@@ -163,20 +163,18 @@
 
     override fun expandQuickSettingsShade(loggingReason: String, transitionKey: TransitionKey?) {
         if (shadeModeInteractor.isDualShade) {
-            if (Overlays.NotificationsShade in sceneInteractor.currentOverlays.value) {
-                sceneInteractor.replaceOverlay(
-                    from = Overlays.NotificationsShade,
-                    to = Overlays.QuickSettingsShade,
-                    loggingReason = loggingReason,
-                    transitionKey = transitionKey,
-                )
-            } else {
-                sceneInteractor.showOverlay(
-                    overlay = Overlays.QuickSettingsShade,
-                    loggingReason = loggingReason,
-                    transitionKey = transitionKey,
-                )
-            }
+            // Collapse the notifications shade if it's expanded (no-op if it isn't).
+            sceneInteractor.hideOverlay(
+                overlay = Overlays.NotificationsShade,
+                loggingReason = loggingReason,
+                transitionKey = transitionKey,
+            )
+            // Expand the quick settings shade.
+            sceneInteractor.showOverlay(
+                overlay = Overlays.QuickSettingsShade,
+                loggingReason = loggingReason,
+                transitionKey = transitionKey,
+            )
         } else {
             val isSplitShade = shadeModeInteractor.isSplitShade
             sceneInteractor.changeScene(
@@ -199,12 +197,12 @@
             // TODO(b/356596436): Define instant transition instead of snapToScene().
             sceneInteractor.snapToScene(
                 toScene = SceneFamilies.Home,
-                loggingReason = loggingReason + " (collapseNotificationsShade)",
+                loggingReason = "$loggingReason (collapseNotificationsShade)",
             )
         } else {
             sceneInteractor.changeScene(
                 toScene = SceneFamilies.Home,
-                loggingReason = loggingReason + " (collapseNotificationsShade)",
+                loggingReason = "$loggingReason (collapseNotificationsShade)",
                 transitionKey =
                     transitionKey ?: ToSplitShade.takeIf { shadeModeInteractor.isSplitShade },
             )
@@ -233,12 +231,12 @@
             // TODO(b/356596436): Define instant transition instead of snapToScene().
             sceneInteractor.snapToScene(
                 toScene = targetScene,
-                loggingReason = loggingReason + " (collapseQuickSettingsShade)",
+                loggingReason = "$loggingReason (collapseQuickSettingsShade)",
             )
         } else {
             sceneInteractor.changeScene(
                 toScene = targetScene,
-                loggingReason = loggingReason + " (collapseQuickSettingsShade)",
+                loggingReason = "$loggingReason (collapseQuickSettingsShade)",
                 transitionKey = transitionKey ?: ToSplitShade.takeIf { isSplitShade },
             )
         }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt
index e38e53d..e5349de 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt
@@ -43,7 +43,7 @@
             shadeExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged)
         onPanelExpansionChanged(currentState)
         shadeExpansionStateManager.addStateListener(this::onPanelStateChanged)
-        dumpManager.registerDumpable(
+        dumpManager.registerNormalDumpable(
             ScrimShadeTransitionController::class.java.simpleName,
             this::dump
         )
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt
index 96128df..8c38d2e 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt
@@ -23,8 +23,10 @@
 import android.icu.text.DisplayContext
 import android.os.UserHandle
 import android.provider.Settings
+import android.view.ViewGroup
 import androidx.compose.runtime.getValue
 import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.systemui.battery.BatteryMeterViewController
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.lifecycle.Hydrator
@@ -39,7 +41,11 @@
 import com.android.systemui.shade.domain.interactor.PrivacyChipInteractor
 import com.android.systemui.shade.domain.interactor.ShadeHeaderClockInteractor
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
-import com.android.systemui.shade.shared.model.ShadeMode
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
+import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerStatusBarViewBinder
+import com.android.systemui.statusbar.phone.StatusBarLocation
+import com.android.systemui.statusbar.phone.ui.StatusBarIconController
+import com.android.systemui.statusbar.phone.ui.TintedIconManager
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel
 import dagger.assisted.AssistedFactory
@@ -63,31 +69,51 @@
     private val activityStarter: ActivityStarter,
     private val sceneInteractor: SceneInteractor,
     private val shadeInteractor: ShadeInteractor,
+    private val shadeModeInteractor: ShadeModeInteractor,
     private val mobileIconsInteractor: MobileIconsInteractor,
     val mobileIconsViewModel: MobileIconsViewModel,
     private val privacyChipInteractor: PrivacyChipInteractor,
     private val clockInteractor: ShadeHeaderClockInteractor,
+    private val tintedIconManagerFactory: TintedIconManager.Factory,
+    private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory,
+    val statusBarIconController: StatusBarIconController,
+    val notificationIconContainerStatusBarViewBinder: NotificationIconContainerStatusBarViewBinder,
     private val broadcastDispatcher: BroadcastDispatcher,
 ) : ExclusiveActivatable() {
     private val hydrator = Hydrator("ShadeHeaderViewModel.hydrator")
 
-    val highlightNotificationIcons: Boolean by
+    val createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager =
+        tintedIconManagerFactory::create
+
+    val createBatteryMeterViewController:
+        (ViewGroup, StatusBarLocation) -> BatteryMeterViewController =
+        batteryMeterViewControllerFactory::create
+
+    val notificationsChipHighlight: HeaderChipHighlight by
         hydrator.hydratedStateOf(
-            traceName = "highlightNotificationIcons",
-            initialValue = false,
+            traceName = "notificationsChipHighlight",
+            initialValue = HeaderChipHighlight.None,
             source =
                 sceneInteractor.currentOverlays.map { overlays ->
-                    Overlays.NotificationsShade in overlays
+                    when {
+                        Overlays.NotificationsShade in overlays -> HeaderChipHighlight.Strong
+                        Overlays.QuickSettingsShade in overlays -> HeaderChipHighlight.Weak
+                        else -> HeaderChipHighlight.None
+                    }
                 },
         )
 
-    val highlightQuickSettingsIcons: Boolean by
+    val quickSettingsChipHighlight: HeaderChipHighlight by
         hydrator.hydratedStateOf(
-            traceName = "highlightQuickSettingsIcons",
-            initialValue = false,
+            traceName = "quickSettingsChipHighlight",
+            initialValue = HeaderChipHighlight.None,
             source =
                 sceneInteractor.currentOverlays.map { overlays ->
-                    Overlays.QuickSettingsShade in overlays
+                    when {
+                        Overlays.QuickSettingsShade in overlays -> HeaderChipHighlight.Strong
+                        Overlays.NotificationsShade in overlays -> HeaderChipHighlight.Weak
+                        else -> HeaderChipHighlight.None
+                    }
                 },
         )
 
@@ -181,7 +207,7 @@
 
     /** Notifies that the system icons container was clicked. */
     fun onNotificationIconChipClicked() {
-        if (shadeInteractor.shadeMode.value !is ShadeMode.Dual) {
+        if (!shadeModeInteractor.isDualShade) {
             return
         }
         val loggingReason = "ShadeHeaderViewModel.onNotificationIconChipClicked"
@@ -199,7 +225,7 @@
     /** Notifies that the system icons container was clicked. */
     fun onSystemIconChipClicked() {
         val loggingReason = "ShadeHeaderViewModel.onSystemIconChipClicked"
-        if (shadeInteractor.shadeMode.value is ShadeMode.Dual) {
+        if (shadeModeInteractor.isDualShade) {
             val currentOverlays = sceneInteractor.currentOverlays.value
             if (Overlays.QuickSettingsShade in currentOverlays) {
                 shadeInteractor.collapseQuickSettingsShade(
@@ -225,6 +251,15 @@
         )
     }
 
+    /** Represents the background highlight of a header icons chip. */
+    sealed interface HeaderChipHighlight {
+        data object None : HeaderChipHighlight
+
+        data object Weak : HeaderChipHighlight
+
+        data object Strong : HeaderChipHighlight
+    }
+
     private fun updateDateTexts(invalidateFormats: Boolean) {
         if (invalidateFormats) {
             longerDateFormat.value = getFormatFromPattern(longerPattern)
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModel.kt
index 7fd0e4e..35031e3 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModel.kt
@@ -26,7 +26,7 @@
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.settings.brightness.ui.viewModel.BrightnessMirrorViewModel
-import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.statusbar.disableflags.domain.interactor.DisableFlagsInteractor
 import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
@@ -56,7 +56,7 @@
     val shadeHeaderViewModelFactory: ShadeHeaderViewModel.Factory,
     val brightnessMirrorViewModelFactory: BrightnessMirrorViewModel.Factory,
     val mediaCarouselInteractor: MediaCarouselInteractor,
-    shadeInteractor: ShadeInteractor,
+    shadeModeInteractor: ShadeModeInteractor,
     private val disableFlagsInteractor: DisableFlagsInteractor,
     private val footerActionsViewModelFactory: FooterActionsViewModel.Factory,
     private val footerActionsController: FooterActionsController,
@@ -65,7 +65,7 @@
     private val sceneInteractor: SceneInteractor,
 ) : ExclusiveActivatable() {
 
-    val shadeMode: StateFlow<ShadeMode> = shadeInteractor.shadeMode
+    val shadeMode: StateFlow<ShadeMode> = shadeModeInteractor.shadeMode
 
     private val _isEmptySpaceClickable =
         MutableStateFlow(!deviceEntryInteractor.isDeviceEntered.value)
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModel.kt
index 7d6b1a3..d0e0de9 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModel.kt
@@ -25,7 +25,7 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade
 import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
-import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
@@ -42,13 +42,13 @@
 @AssistedInject
 constructor(
     private val qsSceneAdapter: QSSceneAdapter,
-    private val shadeInteractor: ShadeInteractor,
+    private val shadeModeInteractor: ShadeModeInteractor,
     private val sceneBackInteractor: SceneBackInteractor,
 ) : UserActionsViewModel() {
 
     override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
         combine(
-                shadeInteractor.shadeMode,
+                shadeModeInteractor.shadeMode,
                 qsSceneAdapter.isCustomizerShowing,
                 sceneBackInteractor.backScene
                     .filter { it != Scenes.Shade }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index a2a8409..e3b36df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -40,6 +40,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.shade.ShadeExpansionChangeEvent
 import com.android.systemui.shade.ShadeExpansionListener
@@ -74,6 +75,7 @@
     private val blurUtils: BlurUtils,
     private val biometricUnlockController: BiometricUnlockController,
     private val keyguardStateController: KeyguardStateController,
+    private val keyguardInteractor: KeyguardInteractor,
     private val choreographer: Choreographer,
     private val wallpaperController: WallpaperController,
     private val notificationShadeWindowController: NotificationShadeWindowController,
@@ -281,6 +283,7 @@
             appZoomOutOptional.ifPresent { appZoomOut ->
                 appZoomOut.setProgress(zoomOutFromShadeRadius)
             }
+            keyguardInteractor.setZoomOut(zoomOutFromShadeRadius)
         }
         listeners.forEach {
             it.onWallpaperZoomOutChanged(zoomOutFromShadeRadius)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index ead8f6a..0dfc63e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -16,13 +16,9 @@
 
 package com.android.systemui.statusbar;
 
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_TRANSITION_FROM_AOD;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_TRANSITION_TO_AOD;
 import static com.android.systemui.keyguard.shared.model.KeyguardState.GONE;
 import static com.android.systemui.util.kotlin.JavaAdapterKt.combineFlows;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.os.SystemProperties;
@@ -30,7 +26,6 @@
 import android.text.format.DateFormat;
 import android.util.FloatProperty;
 import android.util.Log;
-import android.view.Choreographer;
 import android.view.View;
 import android.view.animation.Interpolator;
 
@@ -42,8 +37,6 @@
 import com.android.compose.animation.scene.SceneKey;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.jank.InteractionJankMonitor;
-import com.android.internal.jank.InteractionJankMonitor.Configuration;
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
@@ -54,7 +47,6 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
 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.data.model.SceneStack;
 import com.android.systemui.scene.data.model.SceneStackKt;
 import com.android.systemui.scene.domain.interactor.SceneBackInteractor;
@@ -113,7 +105,6 @@
 
     private final ArrayList<RankedListener> mListeners = new ArrayList<>();
     private final UiEventLogger mUiEventLogger;
-    private final Lazy<InteractionJankMonitor> mInteractionJankMonitorLazy;
     private final JavaAdapter mJavaAdapter;
     private final Lazy<KeyguardInteractor> mKeyguardInteractorLazy;
     private final Lazy<KeyguardTransitionInteractor> mKeyguardTransitionInteractorLazy;
@@ -184,7 +175,6 @@
     @Inject
     public StatusBarStateControllerImpl(
             UiEventLogger uiEventLogger,
-            Lazy<InteractionJankMonitor> interactionJankMonitorLazy,
             JavaAdapter javaAdapter,
             Lazy<KeyguardInteractor> keyguardInteractor,
             Lazy<KeyguardTransitionInteractor> keyguardTransitionInteractor,
@@ -196,7 +186,6 @@
             Lazy<SceneBackInteractor> sceneBackInteractorLazy,
             Lazy<AlternateBouncerInteractor> alternateBouncerInteractorLazy) {
         mUiEventLogger = uiEventLogger;
-        mInteractionJankMonitorLazy = interactionJankMonitorLazy;
         mJavaAdapter = javaAdapter;
         mKeyguardInteractorLazy = keyguardInteractor;
         mKeyguardTransitionInteractorLazy = keyguardTransitionInteractor;
@@ -470,22 +459,6 @@
                 this, SET_DARK_AMOUNT_PROPERTY, mDozeAmountTarget);
         darkAnimator.setInterpolator(Interpolators.LINEAR);
         darkAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP);
-        darkAnimator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                cancelInteractionJankMonitor();
-            }
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                endInteractionJankMonitor();
-            }
-
-            @Override
-            public void onAnimationStart(Animator animation) {
-                beginInteractionJankMonitor();
-            }
-        });
         darkAnimator.start();
         return darkAnimator;
     }
@@ -511,42 +484,6 @@
         return mKeyguardClockInteractorLazy.get().getRenderedClockId();
     }
 
-    private void beginInteractionJankMonitor() {
-        final boolean shouldPost =
-                (mIsDozing && mDozeAmount == 0) || (!mIsDozing && mDozeAmount == 1);
-        InteractionJankMonitor monitor = mInteractionJankMonitorLazy.get();
-        if (monitor != null && mView != null && mView.isAttachedToWindow()) {
-            if (shouldPost) {
-                Choreographer.getInstance().postCallback(
-                        Choreographer.CALLBACK_ANIMATION, this::beginInteractionJankMonitor, null);
-            } else {
-                Configuration.Builder builder = Configuration.Builder.withView(getCujType(), mView)
-                        .setTag(getClockId())
-                        .setDeferMonitorForAnimationStart(false);
-                monitor.begin(builder);
-            }
-        }
-    }
-
-    private void endInteractionJankMonitor() {
-        InteractionJankMonitor monitor = mInteractionJankMonitorLazy.get();
-        if (monitor == null) {
-            return;
-        }
-        monitor.end(getCujType());
-    }
-
-    private void cancelInteractionJankMonitor() {
-        InteractionJankMonitor monitor = mInteractionJankMonitorLazy.get();
-        if (monitor == null) {
-            return;
-        }
-        monitor.cancel(getCujType());
-    }
-
-    private int getCujType() {
-        return mIsDozing ? CUJ_LOCKSCREEN_TRANSITION_TO_AOD : CUJ_LOCKSCREEN_TRANSITION_FROM_AOD;
-    }
 
     @Override
     public boolean goingToFullShade() {
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 541a07c..98b7521 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,6 +16,7 @@
 
 package com.android.systemui.statusbar.chips.call.ui.viewmodel
 
+import android.content.Context
 import android.view.View
 import com.android.internal.jank.Cuj
 import com.android.systemui.animation.ActivityTransitionAnimator
@@ -23,6 +24,7 @@
 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.dagger.qualifiers.Main
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.LogLevel
 import com.android.systemui.plugins.ActivityStarter
@@ -52,6 +54,7 @@
 open class CallChipViewModel
 @Inject
 constructor(
+    @Main private val context: Context,
     @Application private val scope: CoroutineScope,
     interactor: CallChipInteractor,
     systemClock: SystemClock,
@@ -65,15 +68,18 @@
                     is OngoingCallModel.NoCall,
                     is OngoingCallModel.InCallWithVisibleApp -> OngoingActivityChipModel.Hidden()
                     is OngoingCallModel.InCall -> {
+                        val contentDescription = getContentDescription(state.appName)
                         val icon =
                             if (state.notificationIconView != null) {
                                 StatusBarConnectedDisplays.assertInLegacyMode()
                                 OngoingActivityChipModel.ChipIcon.StatusBarView(
-                                    state.notificationIconView
+                                    state.notificationIconView,
+                                    contentDescription,
                                 )
                             } else if (StatusBarConnectedDisplays.isEnabled) {
                                 OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon(
-                                    state.notificationKey
+                                    state.notificationKey,
+                                    contentDescription,
                                 )
                             } else {
                                 OngoingActivityChipModel.ChipIcon.SingleColorIcon(phoneIcon)
@@ -155,6 +161,17 @@
             )
         }
 
+    private fun getContentDescription(appName: String): ContentDescription {
+        val ongoingCallDescription = context.getString(R.string.ongoing_call_content_description)
+        return ContentDescription.Loaded(
+            context.getString(
+                R.string.accessibility_desc_notification_icon,
+                appName,
+                ongoingCallDescription,
+            )
+        )
+    }
+
     companion object {
         private val phoneIcon =
             Icon.Resource(
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
index 6ea72b9..5215398 100644
--- 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
@@ -18,6 +18,7 @@
 
 import android.content.Context
 import android.os.Bundle
+import android.view.View
 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
@@ -48,6 +49,11 @@
                 R.string.cast_to_other_device_stop_dialog_button,
                 endMediaProjectionDialogHelper.wrapStopAction(stopAction),
             )
+            if (com.android.media.projection.flags.Flags.showStopDialogPostCallEnd()) {
+                window
+                    ?.decorView
+                    ?.setAccessibilityDataSensitive(View.ACCESSIBILITY_DATA_SENSITIVE_YES)
+            }
         }
     }
 
@@ -82,9 +88,7 @@
                     hostDeviceName,
                 )
             } else {
-                context.getString(
-                    R.string.cast_to_other_device_stop_dialog_message_entire_screen,
-                )
+                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/EndGenericCastToOtherDeviceDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegate.kt
index b0c8321..8644c53 100644
--- 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
@@ -18,6 +18,7 @@
 
 import android.content.Context
 import android.os.Bundle
+import android.view.View
 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
@@ -59,6 +60,11 @@
                 R.string.cast_to_other_device_stop_dialog_button,
                 endMediaProjectionDialogHelper.wrapStopAction(stopAction),
             )
+            if (com.android.media.projection.flags.Flags.showStopDialogPostCallEnd()) {
+                window
+                    ?.decorView
+                    ?.setAccessibilityDataSensitive(View.ACCESSIBILITY_DATA_SENSITIVE_YES)
+            }
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/model/MediaProjectionStopDialogModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/model/MediaProjectionStopDialogModel.kt
index b37c762..52f55fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/model/MediaProjectionStopDialogModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/model/MediaProjectionStopDialogModel.kt
@@ -34,6 +34,13 @@
          */
         fun createAndShowDialog() {
             val dialog = dialogDelegate.createDialog()
+            // Prevents the dialog from being dismissed by tapping outside its boundary.
+            // This is specifically required for the stop dialog shown at call end (i.e.,
+            // PROJECTION_STARTED_DURING_CALL_AND_ACTIVE_POST_CALL event) to disallow remote
+            // dismissal by external devices. Other media projection stop dialogs do not require
+            // this since they are triggered explicitly by tapping the status bar chip, in which
+            // case the full screen containing the dialog is not remote dismissible.
+            dialog.setCanceledOnTouchOutside(/* cancel= */ false)
             dialog.setOnCancelListener { onDismissAction.invoke() }
             dialog.setOnDismissListener { onDismissAction.invoke() }
             dialog.show()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt
index cece521..a933888 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt
@@ -138,7 +138,7 @@
             }
         }
 
-        return NotificationChipModel(key, statusBarChipIconView, promotedContent)
+        return NotificationChipModel(key, appName, statusBarChipIconView, promotedContent)
     }
 
     @AssistedFactory
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/model/NotificationChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/model/NotificationChipModel.kt
index c6759da..e7a9080 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/model/NotificationChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/model/NotificationChipModel.kt
@@ -22,6 +22,8 @@
 /** Modeling all the data needed to render a status bar notification chip. */
 data class NotificationChipModel(
     val key: String,
+    /** The user-readable name of the app that posted the call notification. */
+    val appName: String,
     val statusBarChipIconView: StatusBarIconView?,
     val promotedContent: PromotedNotificationContentModel,
 )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
index 46456b8..b0da642 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
@@ -16,10 +16,14 @@
 
 package com.android.systemui.statusbar.chips.notification.ui.viewmodel
 
+import android.content.Context
 import android.view.View
 import com.android.systemui.Flags
+import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.chips.notification.domain.interactor.StatusBarNotificationChipsInteractor
 import com.android.systemui.statusbar.chips.notification.domain.model.NotificationChipModel
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
@@ -43,6 +47,7 @@
 class NotifChipsViewModel
 @Inject
 constructor(
+    @Main private val context: Context,
     @Application private val applicationScope: CoroutineScope,
     private val notifChipsInteractor: StatusBarNotificationChipsInteractor,
     headsUpNotificationInteractor: HeadsUpNotificationInteractor,
@@ -65,13 +70,20 @@
         headsUpState: TopPinnedState
     ): OngoingActivityChipModel.Shown {
         StatusBarNotifChips.assertInNewMode()
+        val contentDescription = getContentDescription(this.appName)
         val icon =
             if (this.statusBarChipIconView != null) {
                 StatusBarConnectedDisplays.assertInLegacyMode()
-                OngoingActivityChipModel.ChipIcon.StatusBarView(this.statusBarChipIconView)
+                OngoingActivityChipModel.ChipIcon.StatusBarView(
+                    this.statusBarChipIconView,
+                    contentDescription,
+                )
             } else {
                 StatusBarConnectedDisplays.assertInNewMode()
-                OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon(this.key)
+                OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon(
+                    this.key,
+                    contentDescription,
+                )
             }
         val colors = this.promotedContent.toCustomColorsModel()
 
@@ -79,6 +91,7 @@
             // The notification pipeline needs everything to run on the main thread, so keep
             // this event on the main thread.
             applicationScope.launch {
+                // TODO(b/364653005): Move accessibility focus to the HUN when chip is tapped.
                 notifChipsInteractor.onPromotedNotificationChipTapped(this@toActivityChipModel.key)
             }
         }
@@ -173,4 +186,16 @@
             }
         }
     }
+
+    private fun getContentDescription(appName: String): ContentDescription {
+        val ongoingDescription =
+            context.getString(R.string.ongoing_notification_extra_content_description)
+        return ContentDescription.Loaded(
+            context.getString(
+                R.string.accessibility_desc_notification_icon,
+                appName,
+                ongoingDescription,
+            )
+        )
+    }
 }
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 72656ca..4e0117e 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
@@ -19,6 +19,7 @@
 import android.app.ActivityManager
 import android.content.Context
 import android.os.Bundle
+import android.view.View
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
 import com.android.systemui.statusbar.chips.screenrecord.ui.viewmodel.ScreenRecordChipViewModel
@@ -56,6 +57,11 @@
                 R.string.screenrecord_stop_dialog_button,
                 endMediaProjectionDialogHelper.wrapStopAction(stopAction),
             )
+            if (com.android.media.projection.flags.Flags.showStopDialogPostCallEnd()) {
+                window
+                    ?.decorView
+                    ?.setAccessibilityDataSensitive(View.ACCESSIBILITY_DATA_SENSITIVE_YES)
+            }
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndGenericShareToAppDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndGenericShareToAppDialogDelegate.kt
index 8ec0567..b8db613 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndGenericShareToAppDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndGenericShareToAppDialogDelegate.kt
@@ -18,6 +18,7 @@
 
 import android.content.Context
 import android.os.Bundle
+import android.view.View
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
 import com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel.ShareToAppChipViewModel.Companion.SHARE_TO_APP_ICON
@@ -49,6 +50,11 @@
                 R.string.share_to_app_stop_dialog_button,
                 endMediaProjectionDialogHelper.wrapStopAction(stopAction),
             )
+            if (com.android.media.projection.flags.Flags.showStopDialogPostCallEnd()) {
+                window
+                    ?.decorView
+                    ?.setAccessibilityDataSensitive(View.ACCESSIBILITY_DATA_SENSITIVE_YES)
+            }
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegate.kt
index 053016e3..11a1555 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegate.kt
@@ -18,6 +18,7 @@
 
 import android.content.Context
 import android.os.Bundle
+import android.view.View
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
@@ -48,6 +49,11 @@
                 R.string.share_to_app_stop_dialog_button,
                 endMediaProjectionDialogHelper.wrapStopAction(stopAction),
             )
+            if (com.android.media.projection.flags.Flags.showStopDialogPostCallEnd()) {
+                window
+                    ?.decorView
+                    ?.setAccessibilityDataSensitive(View.ACCESSIBILITY_DATA_SENSITIVE_YES)
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt
index f5764d5..de9d497 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt
@@ -26,6 +26,8 @@
 import android.widget.ImageView
 import android.widget.TextView
 import androidx.annotation.UiThread
+import com.android.systemui.common.shared.model.ContentDescription
+import com.android.systemui.common.ui.binder.ContentDescriptionViewBinder
 import com.android.systemui.common.ui.binder.IconViewBinder
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.StatusBarIconView
@@ -187,7 +189,13 @@
             }
             is OngoingActivityChipModel.ChipIcon.StatusBarView -> {
                 StatusBarConnectedDisplays.assertInLegacyMode()
-                setStatusBarIconView(defaultIconView, icon.impl, iconTint, backgroundView)
+                setStatusBarIconView(
+                    defaultIconView,
+                    icon.impl,
+                    icon.contentDescription,
+                    iconTint,
+                    backgroundView,
+                )
             }
             is OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon -> {
                 StatusBarConnectedDisplays.assertInNewMode()
@@ -196,7 +204,13 @@
                     // This means that the notification key doesn't exist anymore.
                     return
                 }
-                setStatusBarIconView(defaultIconView, iconView, iconTint, backgroundView)
+                setStatusBarIconView(
+                    defaultIconView,
+                    iconView,
+                    icon.contentDescription,
+                    iconTint,
+                    backgroundView,
+                )
             }
         }
     }
@@ -215,6 +229,7 @@
     private fun setStatusBarIconView(
         defaultIconView: ImageView,
         iconView: StatusBarIconView,
+        iconContentDescription: ContentDescription,
         iconTint: Int,
         backgroundView: ChipBackgroundContainer,
     ) {
@@ -224,9 +239,12 @@
         // 1. Set up the right visual params.
         with(iconView) {
             id = CUSTOM_ICON_VIEW_ID
-            // TODO(b/354930838): For RON chips, use the app name for the content description.
-            contentDescription =
-                context.resources.getString(R.string.ongoing_call_content_description)
+            if (StatusBarNotifChips.isEnabled) {
+                ContentDescriptionViewBinder.bind(iconContentDescription, this)
+            } else {
+                contentDescription =
+                    context.resources.getString(R.string.ongoing_call_content_description)
+            }
             tintView(iconTint)
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/ChipContent.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/ChipContent.kt
index 375e029..cf2ec47 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/ChipContent.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/ChipContent.kt
@@ -16,12 +16,20 @@
 
 package com.android.systemui.statusbar.chips.ui.compose
 
-import androidx.compose.foundation.layout.padding
 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.Modifier
+import androidx.compose.ui.draw.drawWithCache
+import androidx.compose.ui.graphics.BlendMode
+import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.CompositingStrategy
+import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.layout.Measurable
 import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.layout.MeasureScope
@@ -29,12 +37,15 @@
 import androidx.compose.ui.node.ModifierNodeElement
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.text.rememberTextMeasurer
 import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.constrain
 import androidx.compose.ui.unit.dp
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.android.systemui.statusbar.chips.ui.viewmodel.rememberChronometerState
+import kotlin.math.min
 
 @Composable
 fun ChipContent(viewModel: OngoingActivityChipModel.Shown, modifier: Modifier = Modifier) {
@@ -43,6 +54,9 @@
     val hasEmbeddedIcon =
         viewModel.icon is OngoingActivityChipModel.ChipIcon.StatusBarView ||
             viewModel.icon is OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon
+    val textStyle = MaterialTheme.typography.labelLarge
+    val textColor = Color(viewModel.colors.text(context))
+    val maxTextWidth = dimensionResource(id = R.dimen.ongoing_activity_chip_max_text_width)
     val startPadding =
         if (isTextOnly || hasEmbeddedIcon) {
             0.dp
@@ -57,38 +71,69 @@
         } else {
             0.dp
         }
-    val textStyle = MaterialTheme.typography.labelLarge
-    val textColor = Color(viewModel.colors.text(context))
+    val textMeasurer = rememberTextMeasurer()
     when (viewModel) {
         is OngoingActivityChipModel.Shown.Timer -> {
             val timerState = rememberChronometerState(startTimeMillis = viewModel.startTimeMs)
+            val text = timerState.currentTimeText
             Text(
-                text = timerState.currentTimeText,
+                text = text,
                 style = textStyle,
                 color = textColor,
+                softWrap = false,
                 modifier =
-                    modifier.padding(start = startPadding, end = endPadding).neverDecreaseWidth(),
+                    modifier
+                        .customTextContentLayout(
+                            maxTextWidth = maxTextWidth,
+                            startPadding = startPadding,
+                            endPadding = endPadding,
+                        ) { constraintWidth ->
+                            val intrinsicWidth =
+                                textMeasurer.measure(text, textStyle, softWrap = false).size.width
+                            intrinsicWidth <= constraintWidth
+                        }
+                        .neverDecreaseWidth(),
             )
         }
 
         is OngoingActivityChipModel.Shown.Countdown -> {
-            ChipText(
-                text = viewModel.secondsUntilStarted.toString(),
+            val text = viewModel.secondsUntilStarted.toString()
+            Text(
+                text = text,
                 style = textStyle,
                 color = textColor,
-                modifier =
-                    modifier.padding(start = startPadding, end = endPadding).neverDecreaseWidth(),
-                backgroundColor = Color(viewModel.colors.background(context).defaultColor),
+                softWrap = false,
+                modifier = modifier.neverDecreaseWidth(),
             )
         }
 
         is OngoingActivityChipModel.Shown.Text -> {
-            ChipText(
-                text = viewModel.text,
-                style = textStyle,
+            var hasOverflow by remember { mutableStateOf(false) }
+            val text = viewModel.text
+            Text(
+                text = text,
                 color = textColor,
-                modifier = modifier.padding(start = startPadding, end = endPadding),
-                backgroundColor = Color(viewModel.colors.background(context).defaultColor),
+                style = textStyle,
+                softWrap = false,
+                modifier =
+                    modifier
+                        .customTextContentLayout(
+                            maxTextWidth = maxTextWidth,
+                            startPadding = startPadding,
+                            endPadding = endPadding,
+                        ) { constraintWidth ->
+                            val intrinsicWidth =
+                                textMeasurer.measure(text, textStyle, softWrap = false).size.width
+                            hasOverflow = intrinsicWidth > constraintWidth
+                            constraintWidth.toFloat() / intrinsicWidth.toFloat() > 0.5f
+                        }
+                        .overflowFadeOut(
+                            hasOverflow = { hasOverflow },
+                            fadeLength =
+                                dimensionResource(
+                                    id = R.dimen.ongoing_activity_chip_text_fading_edge_length
+                                ),
+                        ),
             )
         }
 
@@ -133,3 +178,83 @@
         return layout(width, height) { placeable.place(0, 0) }
     }
 }
+
+/**
+ * A custom layout modifier for text that ensures its text is only visible if a provided
+ * [shouldShow] callback returns true. Imposes a provided [maxTextWidthPx]. Also, accounts for
+ * provided padding values if provided and ensures its text is placed with the provided padding
+ * included around it.
+ */
+private fun Modifier.customTextContentLayout(
+    maxTextWidth: Dp,
+    startPadding: Dp = 0.dp,
+    endPadding: Dp = 0.dp,
+    shouldShow: (constraintWidth: Int) -> Boolean,
+): Modifier {
+    return this.then(
+        CustomTextContentLayoutElement(maxTextWidth, startPadding, endPadding, shouldShow)
+    )
+}
+
+private data class CustomTextContentLayoutElement(
+    val maxTextWidth: Dp,
+    val startPadding: Dp,
+    val endPadding: Dp,
+    val shouldShow: (constrainedWidth: Int) -> Boolean,
+) : ModifierNodeElement<CustomTextContentLayoutNode>() {
+    override fun create(): CustomTextContentLayoutNode {
+        return CustomTextContentLayoutNode(maxTextWidth, startPadding, endPadding, shouldShow)
+    }
+
+    override fun update(node: CustomTextContentLayoutNode) {
+        node.shouldShow = shouldShow
+        node.maxTextWidth = maxTextWidth
+        node.startPadding = startPadding
+        node.endPadding = endPadding
+    }
+}
+
+private class CustomTextContentLayoutNode(
+    var maxTextWidth: Dp,
+    var startPadding: Dp,
+    var endPadding: Dp,
+    var shouldShow: (constrainedWidth: Int) -> Boolean,
+) : Modifier.Node(), LayoutModifierNode {
+    override fun MeasureScope.measure(
+        measurable: Measurable,
+        constraints: Constraints,
+    ): MeasureResult {
+        val horizontalPadding = startPadding + endPadding
+        val maxWidth =
+            min(maxTextWidth.roundToPx(), (constraints.maxWidth - horizontalPadding.roundToPx()))
+                .coerceAtLeast(constraints.minWidth)
+        val placeable = measurable.measure(constraints.copy(maxWidth = maxWidth))
+
+        val height = placeable.height
+        val width = placeable.width
+        return if (shouldShow(maxWidth)) {
+            layout(width + horizontalPadding.roundToPx(), height) {
+                placeable.place(startPadding.roundToPx(), 0)
+            }
+        } else {
+            layout(0, 0) {}
+        }
+    }
+}
+
+private fun Modifier.overflowFadeOut(hasOverflow: () -> Boolean, fadeLength: Dp): Modifier {
+    return graphicsLayer(compositingStrategy = CompositingStrategy.Offscreen).drawWithCache {
+        val width = size.width
+        val start = (width - fadeLength.toPx()).coerceAtLeast(0f)
+        val gradient =
+            Brush.horizontalGradient(
+                colors = listOf(Color.Black, Color.Transparent),
+                startX = start,
+                endX = width,
+            )
+        onDrawWithContent {
+            drawContent()
+            if (hasOverflow()) drawRect(brush = gradient, blendMode = BlendMode.DstIn)
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/ChipText.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/ChipText.kt
deleted file mode 100644
index 3d768d2..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/ChipText.kt
+++ /dev/null
@@ -1,114 +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.ui.compose
-
-import androidx.compose.foundation.layout.sizeIn
-import androidx.compose.material3.LocalTextStyle
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.drawWithContent
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.geometry.Size
-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.text.TextLayoutResult
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.rememberTextMeasurer
-import com.android.systemui.res.R
-
-/**
- * Renders text within a status bar chip. The text is only displayed if more than 50% of its width
- * can fit inside the bounds of the chip. If there is any overflow,
- * [R.dimen.ongoing_activity_chip_text_fading_edge_length] is used to fade out the edge of the text.
- */
-@Composable
-fun ChipText(
-    text: String,
-    backgroundColor: Color,
-    modifier: Modifier = Modifier,
-    color: Color = Color.Unspecified,
-    style: TextStyle = LocalTextStyle.current,
-    minimumVisibleRatio: Float = 0.5f,
-) {
-    val density = LocalDensity.current
-    val textMeasurer = rememberTextMeasurer()
-
-    val textFadeLength =
-        dimensionResource(id = R.dimen.ongoing_activity_chip_text_fading_edge_length)
-    val maxTextWidthDp = dimensionResource(id = R.dimen.ongoing_activity_chip_max_text_width)
-    val maxTextWidthPx = with(density) { maxTextWidthDp.toPx() }
-
-    val textLayoutResult = remember(text, style) { textMeasurer.measure(text, style) }
-    val willOverflowWidth = textLayoutResult.size.width > maxTextWidthPx
-
-    if (isSufficientlyVisible(maxTextWidthPx, minimumVisibleRatio, textLayoutResult)) {
-        Text(
-            text = text,
-            style = style,
-            softWrap = false,
-            color = color,
-            modifier =
-                modifier
-                    .sizeIn(maxWidth = maxTextWidthDp)
-                    .then(
-                        if (willOverflowWidth) {
-                            Modifier.overflowFadeOut(
-                                with(density) { textFadeLength.roundToPx() },
-                                backgroundColor,
-                            )
-                        } else {
-                            Modifier
-                        }
-                    ),
-        )
-    }
-}
-
-private fun Modifier.overflowFadeOut(fadeLength: Int, color: Color): Modifier = drawWithContent {
-    drawContent()
-
-    val brush =
-        Brush.horizontalGradient(
-            colors = listOf(Color.Transparent, color),
-            startX = size.width - fadeLength,
-            endX = size.width,
-        )
-    drawRect(
-        brush = brush,
-        topLeft = Offset(size.width - fadeLength, 0f),
-        size = Size(fadeLength.toFloat(), size.height),
-    )
-}
-
-/**
- * Returns `true` if at least [minimumVisibleRatio] of the text width fits within the given
- * [maxAvailableWidthPx].
- */
-@Composable
-private fun isSufficientlyVisible(
-    maxAvailableWidthPx: Float,
-    minimumVisibleRatio: Float,
-    textLayoutResult: TextLayoutResult,
-): Boolean {
-    val widthPx = textLayoutResult.size.width
-
-    return (maxAvailableWidthPx / widthPx) > minimumVisibleRatio
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
index 647f3bd..b49d46c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
@@ -35,13 +35,18 @@
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.layout.layout
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.viewinterop.AndroidView
 import com.android.compose.animation.Expandable
+import com.android.compose.modifiers.thenIf
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.ui.compose.Icon
+import com.android.systemui.common.ui.compose.load
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.chips.ui.model.ColorsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
@@ -76,17 +81,41 @@
 private fun ChipBody(
     model: OngoingActivityChipModel.Shown,
     modifier: Modifier = Modifier,
-    onClick: () -> Unit = {},
+    onClick: (() -> Unit)? = null,
 ) {
     val context = LocalContext.current
-    val isClickable = onClick != {}
+    val isClickable = onClick != null
     val hasEmbeddedIcon = model.icon is OngoingActivityChipModel.ChipIcon.StatusBarView
-
+    val contentDescription =
+        when (val icon = model.icon) {
+            is OngoingActivityChipModel.ChipIcon.StatusBarView -> icon.contentDescription.load()
+            is OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon ->
+                icon.contentDescription.load()
+            is OngoingActivityChipModel.ChipIcon.SingleColorIcon -> null
+            null -> null
+        }
+    val chipSidePadding = dimensionResource(id = R.dimen.ongoing_activity_chip_side_padding)
+    val minWidth =
+        if (isClickable) {
+            dimensionResource(id = R.dimen.min_clickable_item_size)
+        } else if (model.icon != null) {
+            dimensionResource(id = R.dimen.ongoing_activity_chip_icon_size) + chipSidePadding
+        } else {
+            dimensionResource(id = R.dimen.ongoing_activity_chip_min_text_width) + chipSidePadding
+        }
     // Use a Box with `fillMaxHeight` to create a larger click surface for the chip. The visible
     // height of the chip is determined by the height of the background of the Row below.
     Box(
         contentAlignment = Alignment.Center,
-        modifier = modifier.fillMaxHeight().clickable(enabled = isClickable, onClick = onClick),
+        modifier =
+            modifier
+                .fillMaxHeight()
+                .clickable(enabled = isClickable, onClick = onClick ?: {})
+                .semantics {
+                    if (contentDescription != null) {
+                        this.contentDescription = contentDescription
+                    }
+                },
     ) {
         Row(
             horizontalArrangement = Arrangement.Center,
@@ -98,14 +127,15 @@
                         )
                     )
                     .height(dimensionResource(R.dimen.ongoing_appops_chip_height))
-                    .widthIn(
-                        min =
-                            if (isClickable) {
-                                dimensionResource(id = R.dimen.min_clickable_item_size)
-                            } else {
-                                0.dp
+                    .thenIf(isClickable) { Modifier.widthIn(min = minWidth) }
+                    .layout { measurable, constraints ->
+                        val placeable = measurable.measure(constraints)
+                        layout(placeable.width, placeable.height) {
+                            if (constraints.maxWidth >= minWidth.roundToPx()) {
+                                placeable.place(0, 0)
                             }
-                    )
+                        }
+                    }
                     .background(Color(model.colors.background(context).defaultColor))
                     .padding(
                         horizontal =
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 e0c7645..d44646c 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
@@ -18,6 +18,7 @@
 
 import android.view.View
 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.statusbar.StatusBarIconView
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
@@ -140,7 +141,10 @@
          * The icon is a custom icon, which is set on [impl]. The icon was likely created by an
          * external app.
          */
-        data class StatusBarView(val impl: StatusBarIconView) : ChipIcon {
+        data class StatusBarView(
+            val impl: StatusBarIconView,
+            val contentDescription: ContentDescription,
+        ) : ChipIcon {
             init {
                 StatusBarConnectedDisplays.assertInLegacyMode()
             }
@@ -150,7 +154,10 @@
          * The icon is a custom icon, which is set on a notification, and can be looked up using the
          * provided [notificationKey]. The icon was likely created by an external app.
          */
-        data class StatusBarNotificationIcon(val notificationKey: String) : ChipIcon {
+        data class StatusBarNotificationIcon(
+            val notificationKey: String,
+            val contentDescription: ContentDescription,
+        ) : ChipIcon {
             init {
                 StatusBarConnectedDisplays.assertInNewMode()
             }
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 baa9d8b..4becc8c 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
@@ -16,8 +16,11 @@
 
 package com.android.systemui.statusbar.chips.ui.viewmodel
 
+import android.content.res.Configuration
+import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
+import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.LogLevel
 import com.android.systemui.statusbar.chips.StatusBarChipLogTags.pad
@@ -30,6 +33,7 @@
 import com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel.ShareToAppChipViewModel
 import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChipsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
 import com.android.systemui.util.kotlin.pairwise
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
@@ -37,7 +41,9 @@
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.stateIn
 
 /**
@@ -50,14 +56,36 @@
 class OngoingActivityChipsViewModel
 @Inject
 constructor(
-    @Application scope: CoroutineScope,
+    @Background scope: CoroutineScope,
     screenRecordChipViewModel: ScreenRecordChipViewModel,
     shareToAppChipViewModel: ShareToAppChipViewModel,
     castToOtherDeviceChipViewModel: CastToOtherDeviceChipViewModel,
     callChipViewModel: CallChipViewModel,
     notifChipsViewModel: NotifChipsViewModel,
+    displayStateInteractor: DisplayStateInteractor,
+    configurationInteractor: ConfigurationInteractor,
     @StatusBarChipsLog private val logger: LogBuffer,
 ) {
+    private val isLandscape: Flow<Boolean> =
+        configurationInteractor.configurationValues
+            .map { it.isLandscape }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+
+    private val isScreenReasonablyLarge: Flow<Boolean> =
+        combine(isLandscape, displayStateInteractor.isLargeScreen) { isLandscape, isLargeScreen ->
+                isLandscape || isLargeScreen
+            }
+            .distinctUntilChanged()
+            .onEach {
+                logger.log(
+                    TAG,
+                    LogLevel.DEBUG,
+                    { bool1 = it },
+                    { "isScreenReasonablyLarge: $bool1" },
+                )
+            }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+
     private enum class ChipType {
         ScreenRecord,
         ShareToApp,
@@ -165,22 +193,72 @@
     )
 
     private val internalChips: Flow<InternalMultipleOngoingActivityChipsModel> =
-        incomingChipBundle.map { bundle ->
+        combine(incomingChipBundle, isScreenReasonablyLarge) { bundle, isScreenReasonablyLarge ->
             // First: Find the most important chip.
             val primaryChipResult = pickMostImportantChip(bundle)
-            val primaryChip = primaryChipResult.mostImportantChip
-            if (primaryChip is InternalChipModel.Hidden) {
-                // If the primary chip is hidden, the secondary chip will also be hidden, so just
-                // pass the same Hidden model for both.
-                InternalMultipleOngoingActivityChipsModel(primaryChip, primaryChip)
-            } else {
-                // Then: Find the next most important chip.
-                val secondaryChip =
-                    pickMostImportantChip(primaryChipResult.remainingChips).mostImportantChip
-                InternalMultipleOngoingActivityChipsModel(primaryChip, secondaryChip)
+            when (val primaryChip = primaryChipResult.mostImportantChip) {
+                is InternalChipModel.Hidden -> {
+                    // If the primary chip is hidden, the secondary chip will also be hidden, so
+                    // just pass the same Hidden model for both.
+                    InternalMultipleOngoingActivityChipsModel(primaryChip, primaryChip)
+                }
+                is InternalChipModel.Shown -> {
+                    // Otherwise: Find the next most important chip.
+                    val secondaryChip =
+                        pickMostImportantChip(primaryChipResult.remainingChips).mostImportantChip
+                    if (
+                        secondaryChip is InternalChipModel.Shown &&
+                            StatusBarNotifChips.isEnabled &&
+                            !StatusBarChipsModernization.isEnabled &&
+                            !isScreenReasonablyLarge
+                    ) {
+                        // If we have two showing chips and we don't have a ton of room
+                        // (!isScreenReasonablyLarge), then we want to make both of them as small as
+                        // possible so that we have the highest chance of showing both chips (as
+                        // opposed to showing the primary chip with a lot of text and completely
+                        // hiding the secondary chip).
+                        // Also: If StatusBarChipsModernization is enabled, then we'll do the
+                        // squishing in Compose instead.
+                        InternalMultipleOngoingActivityChipsModel(
+                            primaryChip.squish(),
+                            secondaryChip.squish(),
+                        )
+                    } else {
+                        InternalMultipleOngoingActivityChipsModel(primaryChip, secondaryChip)
+                    }
+                }
             }
         }
 
+    /** Squishes the chip down to the smallest content possible. */
+    private fun InternalChipModel.Shown.squish(): InternalChipModel.Shown {
+        return when (model) {
+            // Icon-only is already maximum squished
+            is OngoingActivityChipModel.Shown.IconOnly -> this
+            // Countdown shows just a single digit, so already maximum squished
+            is OngoingActivityChipModel.Shown.Countdown -> this
+            // The other chips have icon+text, so we should hide the text
+            is OngoingActivityChipModel.Shown.Timer,
+            is OngoingActivityChipModel.Shown.ShortTimeDelta,
+            is OngoingActivityChipModel.Shown.Text ->
+                InternalChipModel.Shown(this.type, this.model.toIconOnly())
+        }
+    }
+
+    private fun OngoingActivityChipModel.Shown.toIconOnly(): OngoingActivityChipModel.Shown {
+        // If this chip doesn't have an icon, then it only has text and we should continue showing
+        // its text. (This is theoretically impossible because
+        // [OngoingActivityChipModel.Shown.Countdown] is the only chip without an icon, but protect
+        // against it just in case.)
+        val currentIcon = icon ?: return this
+        return OngoingActivityChipModel.Shown.IconOnly(
+            currentIcon,
+            colors,
+            onClickListenerLegacy,
+            clickBehavior,
+        )
+    }
+
     /**
      * A flow modeling the primary chip that should be shown in the status bar after accounting for
      * possibly multiple ongoing activities and animation requirements.
@@ -327,6 +405,9 @@
         }
     }
 
+    private val Configuration.isLandscape: Boolean
+        get() = orientation == Configuration.ORIENTATION_LANDSCAPE
+
     companion object {
         private val TAG = "ChipsViewModel".pad()
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
index b057fb0..eeb7a40 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.core
 
 import android.view.Display
+import android.view.IWindowManager
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
@@ -54,6 +55,7 @@
     private val autoHideControllerStore: AutoHideControllerStore,
     private val privacyDotWindowControllerStore: PrivacyDotWindowControllerStore,
     private val lightBarControllerStore: LightBarControllerStore,
+    private val windowManager: IWindowManager,
 ) : CoreStartable {
 
     init {
@@ -68,7 +70,13 @@
                 }
                 .onStart { emit(displayRepository.displays.value) }
                 .collect { newDisplays ->
-                    newDisplays.forEach { createAndStartComponentsForDisplay(it) }
+                    newDisplays.forEach {
+                        // TODO(b/393191204): Split navbar, status bar, etc. functionality
+                        // from WindowManager#shouldShowSystemDecors.
+                        if (windowManager.shouldShowSystemDecors(it.displayId)) {
+                            createAndStartComponentsForDisplay(it)
+                        }
+                    }
                 }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/layout/StatusBarContentInsetsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/layout/StatusBarContentInsetsProvider.kt
index 7358c51..9d5d87f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/layout/StatusBarContentInsetsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/layout/StatusBarContentInsetsProvider.kt
@@ -185,7 +185,7 @@
 
     override fun start() {
         configurationController.addCallback(this)
-        dumpManager.registerDumpable(dumpableName, this)
+        dumpManager.registerNormalDumpable(dumpableName, this)
         commandRegistry.registerCommand(commandName) {
             StatusBarInsetsCommand(
                 object : StatusBarInsetsCommand.Callback {
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 5cc79df..09cc3f2 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
@@ -812,11 +812,6 @@
         return !mSbn.isOngoing() || !isLocked;
     }
 
-    public boolean canViewBeDismissed() {
-        if (row == null) return true;
-        return row.canViewBeDismissed();
-    }
-
     @VisibleForTesting
     boolean isExemptFromDndVisualSuppression() {
         if (isNotificationBlockedByPolicy(mSbn.getNotification())) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
index fd5973e..bde3c4d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt
@@ -21,10 +21,12 @@
 import android.app.Notification.CallStyle.CALL_TYPE_UNKNOWN
 import android.app.Notification.EXTRA_CALL_TYPE
 import android.app.PendingIntent
+import android.content.Context
 import android.graphics.drawable.Icon
 import android.service.notification.StatusBarNotification
 import android.util.ArrayMap
 import com.android.app.tracing.traceSection
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.statusbar.StatusBarIconView
 import com.android.systemui.statusbar.notification.collection.GroupEntry
 import com.android.systemui.statusbar.notification.collection.ListEntry
@@ -50,6 +52,7 @@
 constructor(
     private val repository: ActiveNotificationListRepository,
     private val sectionStyleProvider: SectionStyleProvider,
+    @Main private val context: Context,
 ) {
     /**
      * Sets the current list of rendered notification entries as displayed in the notification list.
@@ -57,7 +60,7 @@
     fun setRenderedList(entries: List<ListEntry>) {
         traceSection("RenderNotificationListInteractor.setRenderedList") {
             repository.activeNotifications.update { existingModels ->
-                buildActiveNotificationsStore(existingModels, sectionStyleProvider) {
+                buildActiveNotificationsStore(existingModels, sectionStyleProvider, context) {
                     entries.forEach(::addListEntry)
                     setRankingsMap(entries)
                 }
@@ -69,13 +72,17 @@
 private fun buildActiveNotificationsStore(
     existingModels: ActiveNotificationsStore,
     sectionStyleProvider: SectionStyleProvider,
+    context: Context,
     block: ActiveNotificationsStoreBuilder.() -> Unit,
 ): ActiveNotificationsStore =
-    ActiveNotificationsStoreBuilder(existingModels, sectionStyleProvider).apply(block).build()
+    ActiveNotificationsStoreBuilder(existingModels, sectionStyleProvider, context)
+        .apply(block)
+        .build()
 
 private class ActiveNotificationsStoreBuilder(
     private val existingModels: ActiveNotificationsStore,
     private val sectionStyleProvider: SectionStyleProvider,
+    private val context: Context,
 ) {
     private val builder = ActiveNotificationsStore.Builder()
 
@@ -154,6 +161,7 @@
             statusBarChipIconView = icons.statusBarChipIcon,
             uid = sbn.uid,
             packageName = sbn.packageName,
+            appName = sbn.notification.loadHeaderAppName(context),
             contentIntent = sbn.notification.contentIntent,
             instanceId = sbn.instanceId?.id,
             isGroupSummary = sbn.notification.isGroupSummary,
@@ -180,6 +188,7 @@
     statusBarChipIconView: StatusBarIconView?,
     uid: Int,
     packageName: String,
+    appName: String,
     contentIntent: PendingIntent?,
     instanceId: Int?,
     isGroupSummary: Boolean,
@@ -206,6 +215,7 @@
             instanceId = instanceId,
             isGroupSummary = isGroupSummary,
             packageName = packageName,
+            appName = appName,
             contentIntent = contentIntent,
             bucket = bucket,
             callType = callType,
@@ -230,6 +240,7 @@
             instanceId = instanceId,
             isGroupSummary = isGroupSummary,
             packageName = packageName,
+            appName = appName,
             contentIntent = contentIntent,
             bucket = bucket,
             callType = callType,
@@ -253,6 +264,7 @@
     statusBarChipIconView: StatusBarIconView?,
     uid: Int,
     packageName: String,
+    appName: String,
     contentIntent: PendingIntent?,
     instanceId: Int?,
     isGroupSummary: Boolean,
@@ -278,6 +290,7 @@
         instanceId != this.instanceId -> false
         isGroupSummary != this.isGroupSummary -> false
         packageName != this.packageName -> false
+        appName != this.appName -> false
         contentIntent != this.contentIntent -> false
         bucket != this.bucket -> false
         callType != this.callType -> false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt
index 33c71d4..91bd72c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt
@@ -17,6 +17,8 @@
 package com.android.systemui.statusbar.notification.promoted
 
 import android.app.Flags
+import android.app.Notification
+import android.graphics.PorterDuff
 import android.view.LayoutInflater
 import android.view.View
 import android.view.View.GONE
@@ -49,6 +51,7 @@
 import com.android.internal.widget.ImageFloatingTextView
 import com.android.internal.widget.NotificationExpandButton
 import com.android.internal.widget.NotificationProgressBar
+import com.android.internal.widget.NotificationProgressModel
 import com.android.internal.widget.NotificationRowIconView
 import com.android.systemui.lifecycle.rememberViewModel
 import com.android.systemui.res.R as systemuiR
@@ -68,6 +71,7 @@
     val viewModel = rememberViewModel(traceName = "$TAG.viewModel") { viewModelFactory.create() }
 
     val content = viewModel.content ?: return
+    val audiblyAlertedIconVisible = viewModel.audiblyAlertedIconVisible
 
     key(content.identity) {
         val layoutResource = content.layoutResource ?: return
@@ -86,6 +90,7 @@
             AODPromotedNotificationView(
                 layoutResource = layoutResource,
                 content = content,
+                audiblyAlertedIconVisible = audiblyAlertedIconVisible,
                 modifier = Modifier.border(borderStroke, borderShape),
             )
         }
@@ -96,6 +101,7 @@
 fun AODPromotedNotificationView(
     layoutResource: Int,
     content: PromotedNotificationContentModel,
+    audiblyAlertedIconVisible: Boolean,
     modifier: Modifier = Modifier,
 ) {
     AndroidView(
@@ -115,7 +121,7 @@
         update = { view ->
             val updater = view.getTag(viewUpdaterTagId) as AODPromotedNotificationViewUpdater
 
-            traceSection("$TAG.update") { updater.update(content) }
+            traceSection("$TAG.update") { updater.update(content, audiblyAlertedIconVisible) }
         },
         modifier = modifier,
     )
@@ -145,7 +151,7 @@
     }
 
 private class AODPromotedNotificationViewUpdater(root: View) {
-    private val alertedIcon: View? = root.findViewById(R.id.alerted_icon)
+    private val alertedIcon: ImageView? = root.findViewById(R.id.alerted_icon)
     private val alternateExpandTarget: View? = root.findViewById(R.id.alternate_expand_target)
     private val appNameDivider: View? = root.findViewById(R.id.app_name_divider)
     private val appNameText: TextView? = root.findViewById(R.id.app_name_text)
@@ -176,60 +182,104 @@
     private val verificationIcon: ImageView? = root.findViewById(R.id.verification_icon)
     private val verificationText: TextView? = root.findViewById(R.id.verification_text)
 
-    private var oldProgressStub = root.findViewById<View>(R.id.progress) as? ViewStub
-    private var oldProgress: ProgressBar? = null
-    private val newProgress = root.findViewById<View>(R.id.progress) as? NotificationProgressBar
+    private var oldProgressBarStub = root.findViewById<View>(R.id.progress) as? ViewStub
+    private var oldProgressBar: ProgressBar? = null
+    private val newProgressBar = root.findViewById<View>(R.id.progress) as? NotificationProgressBar
 
-    fun update(content: PromotedNotificationContentModel) {
+    init {
+        // Hide views that are never visible in the skeleton promoted notification.
+        alternateExpandTarget?.visibility = GONE
+        bigPicture?.visibility = GONE
+        closeButton?.visibility = GONE
+        expandButton?.visibility = GONE
+        leftIcon?.visibility = GONE
+        notificationProgressEndIcon?.visibility = GONE
+        notificationProgressStartIcon?.visibility = GONE
+
+        // Make one-time changes needed for the skeleton promoted notification.
+        alertedIcon
+            ?.drawable
+            ?.mutate()
+            ?.setColorFilter(SecondaryText.colorInt, PorterDuff.Mode.SRC_IN)
+    }
+
+    fun update(content: PromotedNotificationContentModel, audiblyAlertedIconVisible: Boolean) {
         when (content.style) {
             Style.Base -> updateBase(content)
-            Style.BigPicture -> updateBigPicture(content)
-            Style.BigText -> updateBigText(content)
-            Style.Call -> updateCall(content)
-            Style.Progress -> updateProgress(content)
+            Style.BigPicture -> updateBigPictureStyle(content)
+            Style.BigText -> updateBigTextStyle(content)
+            Style.Call -> updateCallStyle(content)
+            Style.Progress -> updateProgressStyle(content)
             Style.Ineligible -> {}
         }
+
+        alertedIcon?.isVisible = audiblyAlertedIconVisible
     }
 
     private fun updateBase(
         content: PromotedNotificationContentModel,
         textView: ImageFloatingTextView? = null,
+        showOldProgress: Boolean = true,
     ) {
         updateHeader(content)
 
         updateTitle(title, content)
         updateText(textView ?: text, content)
+
+        if (showOldProgress) {
+            updateOldProgressBar(content)
+        }
     }
 
-    private fun updateBigPicture(content: PromotedNotificationContentModel) {
+    private fun updateBigPictureStyle(content: PromotedNotificationContentModel) {
         updateBase(content)
-
-        bigPicture?.visibility = GONE
     }
 
-    private fun updateBigText(content: PromotedNotificationContentModel) {
+    private fun updateBigTextStyle(content: PromotedNotificationContentModel) {
         updateBase(content, textView = bigText)
     }
 
-    private fun updateCall(content: PromotedNotificationContentModel) {
+    private fun updateCallStyle(content: PromotedNotificationContentModel) {
         updateConversationHeader(content)
 
         updateText(text, content)
     }
 
-    private fun updateProgress(content: PromotedNotificationContentModel) {
-        updateBase(content)
+    private fun updateProgressStyle(content: PromotedNotificationContentModel) {
+        updateBase(content, showOldProgress = false)
 
         updateNewProgressBar(content)
     }
 
+    private fun updateOldProgressBar(content: PromotedNotificationContentModel) {
+        if (
+            content.oldProgress == null ||
+                content.oldProgress.max == 0 ||
+                content.oldProgress.isIndeterminate
+        ) {
+            oldProgressBar?.visibility = GONE
+            return
+        }
+
+        inflateOldProgressBar()
+
+        val oldProgressBar = oldProgressBar ?: return
+
+        oldProgressBar.progress = content.oldProgress.progress
+        oldProgressBar.max = content.oldProgress.max
+        oldProgressBar.isIndeterminate = content.oldProgress.isIndeterminate
+        oldProgressBar.visibility = VISIBLE
+    }
+
     private fun updateNewProgressBar(content: PromotedNotificationContentModel) {
-        notificationProgressStartIcon?.visibility = GONE
-        notificationProgressEndIcon?.visibility = GONE
-        content.progress?.let {
-            newProgress?.setProgressModel(it.toBundle())
-            newProgress?.visibility = VISIBLE
-        } ?: run { newProgress?.visibility = GONE }
+        val newProgressBar = newProgressBar ?: return
+
+        if (content.newProgress != null && !content.newProgress.isIndeterminate) {
+            newProgressBar.setProgressModel(content.newProgress.toSkeleton().toBundle())
+            newProgressBar.visibility = VISIBLE
+        } else {
+            newProgressBar.visibility = GONE
+        }
     }
 
     private fun updateHeader(content: PromotedNotificationContentModel) {
@@ -239,11 +289,6 @@
         updateTimeAndChronometer(content)
 
         updateHeaderDividers(content)
-
-        leftIcon?.visibility = GONE
-        alternateExpandTarget?.visibility = GONE
-        expandButton?.visibility = GONE
-        closeButton?.visibility = GONE
     }
 
     private fun updateHeaderDividers(content: PromotedNotificationContentModel) {
@@ -335,6 +380,15 @@
         chronometerStub = null
     }
 
+    private fun inflateOldProgressBar() {
+        if (oldProgressBar != null) {
+            return
+        }
+
+        oldProgressBar = oldProgressBarStub?.inflate() as ProgressBar
+        oldProgressBarStub = null
+    }
+
     private fun updateText(
         view: ImageFloatingTextView?,
         content: PromotedNotificationContentModel,
@@ -351,7 +405,7 @@
         setTextViewColor(view, color)
 
         if (text != null && text.isNotEmpty()) {
-            view?.text = text
+            view?.text = text.toSkeleton()
             view?.visibility = VISIBLE
         } else {
             view?.text = ""
@@ -364,6 +418,38 @@
     }
 }
 
+private fun CharSequence.toSkeleton(): CharSequence {
+    return this.toString()
+}
+
+private fun NotificationProgressModel.toSkeleton(): NotificationProgressModel {
+    if (isIndeterminate) {
+        return NotificationProgressModel(/* indeterminateColor= */ SecondaryText.colorInt)
+    }
+
+    return NotificationProgressModel(
+        listOf(Notification.ProgressStyle.Segment(progressMax).toSkeleton()),
+        points.map { it.toSkeleton() }.toList(),
+        progress,
+        /* isStyledByProgress = */ true,
+        /* segmentsFallbackColor = */ SecondaryText.colorInt,
+    )
+}
+
+private fun Notification.ProgressStyle.Segment.toSkeleton(): Notification.ProgressStyle.Segment {
+    return Notification.ProgressStyle.Segment(length).also {
+        it.id = id
+        it.color = SecondaryText.colorInt
+    }
+}
+
+private fun Notification.ProgressStyle.Point.toSkeleton(): Notification.ProgressStyle.Point {
+    return Notification.ProgressStyle.Point(position).also {
+        it.id = id
+        it.color = SecondaryText.colorInt
+    }
+}
+
 private enum class AodPromotedNotificationColor(colorUInt: UInt) {
     Background(0x00000000u),
     PrimaryText(0xFFFFFFFFu),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
index 24d071c..035edd9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
@@ -21,6 +21,9 @@
 import android.app.Notification.BigTextStyle
 import android.app.Notification.CallStyle
 import android.app.Notification.EXTRA_CHRONOMETER_COUNT_DOWN
+import android.app.Notification.EXTRA_PROGRESS
+import android.app.Notification.EXTRA_PROGRESS_INDETERMINATE
+import android.app.Notification.EXTRA_PROGRESS_MAX
 import android.app.Notification.EXTRA_SUB_TEXT
 import android.app.Notification.EXTRA_TEXT
 import android.app.Notification.EXTRA_TITLE
@@ -34,6 +37,7 @@
 import com.android.systemui.statusbar.notification.promoted.AutomaticPromotionCoordinator.Companion.EXTRA_WAS_AUTOMATICALLY_PROMOTED
 import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
 import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Companion.isPromotedForStatusBarChip
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.OldProgress
 import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style
 import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.When
 import javax.inject.Inject
@@ -90,6 +94,7 @@
         contentBuilder.title = notification.title()
         contentBuilder.text = notification.text()
         contentBuilder.skeletonLargeIcon = null // TODO
+        contentBuilder.oldProgress = notification.oldProgress()
 
         val colorsFromNotif = recoveredBuilder.getColors(/* header= */ false)
         contentBuilder.colors =
@@ -126,6 +131,21 @@
 private fun Notification.chronometerCountDown(): Boolean =
     extras?.getBoolean(EXTRA_CHRONOMETER_COUNT_DOWN, /* defaultValue= */ false) ?: false
 
+private fun Notification.oldProgress(): OldProgress? {
+    val progress = progress() ?: return null
+    val max = progressMax() ?: return null
+    val isIndeterminate = progressIndeterminate() ?: return null
+
+    return OldProgress(progress = progress, max = max, isIndeterminate = isIndeterminate)
+}
+
+private fun Notification.progress(): Int? = extras?.getInt(EXTRA_PROGRESS)
+
+private fun Notification.progressMax(): Int? = extras?.getInt(EXTRA_PROGRESS_MAX)
+
+private fun Notification.progressIndeterminate(): Boolean? =
+    extras?.getBoolean(EXTRA_PROGRESS_INDETERMINATE)
+
 private fun Notification.extractWhen(): When? {
     val time = `when`
     val showsTime = showsTime()
@@ -191,5 +211,5 @@
 
 private fun ProgressStyle.extractContent(contentBuilder: PromotedNotificationContentModel.Builder) {
     // TODO: Create NotificationProgressModel.toSkeleton, or something similar.
-    contentBuilder.progress = createProgressModel(0xffffffff.toInt(), 0xff000000.toInt())
+    contentBuilder.newProgress = createProgressModel(0xffffffff.toInt(), 0xff000000.toInt())
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationLogger.kt
index 4ccdc65..4689347 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationLogger.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.notification.promoted
 
 import androidx.constraintlayout.widget.ConstraintSet
+import com.android.systemui.keyguard.ui.view.layout.sections.AodPromotedNotificationSection
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.LogLevel.ERROR
 import com.android.systemui.log.core.LogLevel.INFO
@@ -25,6 +26,7 @@
 import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
 import javax.inject.Inject
 
+@OptIn(ExperimentalStdlibApi::class)
 class PromotedNotificationLogger
 @Inject
 constructor(@PromotedNotificationLog private val buffer: LogBuffer) {
@@ -92,20 +94,44 @@
         buffer.log(AOD_VIEW_BINDER_TAG, INFO, "binder unbound notification")
     }
 
-    fun logSectionAddedViews() {
-        buffer.log(AOD_SECTION_TAG, INFO, "section added views")
+    fun logSectionCreated(section: AodPromotedNotificationSection) {
+        buffer.log(
+            AOD_SECTION_TAG,
+            INFO,
+            "section ${System.identityHashCode(section).toHexString()} created",
+        )
     }
 
-    fun logSectionBoundData() {
-        buffer.log(AOD_SECTION_TAG, INFO, "section bound data")
+    fun logSectionAddedViews(section: AodPromotedNotificationSection) {
+        buffer.log(
+            AOD_SECTION_TAG,
+            INFO,
+            "section ${System.identityHashCode(section).toHexString()} added views",
+        )
     }
 
-    fun logSectionAppliedConstraints() {
-        buffer.log(AOD_SECTION_TAG, INFO, "section applied constraints")
+    fun logSectionBoundData(section: AodPromotedNotificationSection) {
+        buffer.log(
+            AOD_SECTION_TAG,
+            INFO,
+            "section ${System.identityHashCode(section).toHexString()} bound data",
+        )
     }
 
-    fun logSectionRemovedViews() {
-        buffer.log(AOD_SECTION_TAG, INFO, "section removed views")
+    fun logSectionAppliedConstraints(section: AodPromotedNotificationSection) {
+        buffer.log(
+            AOD_SECTION_TAG,
+            INFO,
+            "section ${System.identityHashCode(section).toHexString()} applied constraints",
+        )
+    }
+
+    fun logSectionRemovedViews(section: AodPromotedNotificationSection) {
+        buffer.log(
+            AOD_SECTION_TAG,
+            INFO,
+            "section ${System.identityHashCode(section).toHexString()} removed views",
+        )
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
index 3dacae2..58da528 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
@@ -51,6 +51,7 @@
     val title: CharSequence?,
     val text: CharSequence?,
     val skeletonLargeIcon: Icon?, // TODO(b/377568176): Make into an IconModel.
+    val oldProgress: OldProgress?,
     val colors: Colors,
     val style: Style,
 
@@ -61,7 +62,7 @@
     val verificationText: CharSequence?,
 
     // for ProgressStyle:
-    val progress: NotificationProgressModel?,
+    val newProgress: NotificationProgressModel?,
 ) {
     class Builder(val key: String) {
         var wasPromotedAutomatically: Boolean = false
@@ -75,6 +76,7 @@
         var title: CharSequence? = null
         var text: CharSequence? = null
         var skeletonLargeIcon: Icon? = null
+        var oldProgress: OldProgress? = null
         var style: Style = Style.Ineligible
         var colors: Colors = Colors(backgroundColor = 0, primaryTextColor = 0)
 
@@ -85,7 +87,7 @@
         var verificationText: CharSequence? = null
 
         // for ProgressStyle:
-        var progress: NotificationProgressModel? = null
+        var newProgress: NotificationProgressModel? = null
 
         fun build() =
             PromotedNotificationContentModel(
@@ -101,13 +103,14 @@
                 title = title,
                 text = text,
                 skeletonLargeIcon = skeletonLargeIcon,
+                oldProgress = oldProgress,
                 colors = colors,
                 style = style,
                 personIcon = personIcon,
                 personName = personName,
                 verificationIcon = verificationIcon,
                 verificationText = verificationText,
-                progress = progress,
+                newProgress = newProgress,
             )
     }
 
@@ -129,6 +132,9 @@
     /** The colors used to display the notification. */
     data class Colors(@ColorInt val backgroundColor: Int, @ColorInt val primaryTextColor: Int)
 
+    /** The fields needed to render the old-style progress bar. */
+    data class OldProgress(val progress: Int, val max: Int, val isIndeterminate: Boolean)
+
     /** The promotion-eligible style of a notification, or [Style.Ineligible] if not. */
     enum class Style {
         Base, // style == null
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/ui/viewmodel/AODPromotedNotificationViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/ui/viewmodel/AODPromotedNotificationViewModel.kt
index 3bbd217..0ac280f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/ui/viewmodel/AODPromotedNotificationViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/ui/viewmodel/AODPromotedNotificationViewModel.kt
@@ -17,16 +17,40 @@
 package com.android.systemui.statusbar.notification.promoted.ui.viewmodel
 
 import androidx.compose.runtime.getValue
+import com.android.systemui.dump.DumpManager
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.lifecycle.Hydrator
 import com.android.systemui.statusbar.notification.promoted.domain.interactor.AODPromotedNotificationInteractor
 import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
+import com.android.systemui.util.kotlin.ActivatableFlowDumper
+import com.android.systemui.util.kotlin.ActivatableFlowDumperImpl
+import com.android.systemui.util.time.SystemClock
+import com.android.systemui.utils.coroutines.flow.transformLatestConflated
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
 
 class AODPromotedNotificationViewModel
 @AssistedInject
-constructor(interactor: AODPromotedNotificationInteractor) : ExclusiveActivatable() {
+constructor(
+    interactor: AODPromotedNotificationInteractor,
+    systemClock: SystemClock,
+    dumpManager: DumpManager,
+) :
+    ExclusiveActivatable(),
+    ActivatableFlowDumper by ActivatableFlowDumperImpl(
+        dumpManager,
+        "AODPromotedNotificationViewModel",
+    ) {
     private val hydrator = Hydrator("AODPromotedNotificationViewModel.hydrator")
 
     val content: PromotedNotificationContentModel? by
@@ -36,12 +60,52 @@
             source = interactor.content,
         )
 
+    private val audiblyAlertedIconVisibleUntil: Flow<Duration?> =
+        interactor.content
+            .map {
+                when (it) {
+                    null -> null
+                    else -> it.lastAudiblyAlertedMs.milliseconds + RECENTLY_ALERTED_THRESHOLD
+                }
+            }
+            .distinctUntilChanged()
+            .dumpWhileCollecting("audiblyAlertedIconVisibleUntil")
+
+    private val audiblyAlertedIconVisibleFlow: Flow<Boolean> =
+        audiblyAlertedIconVisibleUntil
+            .transformLatestConflated { until ->
+                val now = systemClock.currentTimeMillis().milliseconds
+
+                if (until != null && until > now) {
+                    emit(true)
+                    delay(until - now)
+                }
+                emit(false)
+            }
+            .distinctUntilChanged()
+            .dumpWhileCollecting("audiblyAlertedIconVisible")
+
+    val audiblyAlertedIconVisible: Boolean by
+        hydrator.hydratedStateOf(
+            traceName = "audiblyAlertedIconVisible",
+            initialValue = false,
+            source = audiblyAlertedIconVisibleFlow,
+        )
+
     override suspend fun onActivated(): Nothing {
-        hydrator.activate()
+        coroutineScope {
+            launch { activateFlowDumper() }
+            launch { hydrator.activate() }
+            awaitCancellation()
+        }
     }
 
     @AssistedFactory
     interface Factory {
         fun create(): AODPromotedNotificationViewModel
     }
+
+    companion object {
+        private val RECENTLY_ALERTED_THRESHOLD = 30.seconds
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/ui/viewmodel/PromotedNotificationViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/ui/viewmodel/PromotedNotificationViewModel.kt
deleted file mode 100644
index f265e0f..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/ui/viewmodel/PromotedNotificationViewModel.kt
+++ /dev/null
@@ -1,58 +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.promoted.ui.viewmodel
-
-import android.graphics.drawable.Icon
-import com.android.internal.widget.NotificationProgressModel
-import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
-import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style
-import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.When
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.map
-
-class PromotedNotificationViewModel(
-    identity: PromotedNotificationContentModel.Identity,
-    content: Flow<PromotedNotificationContentModel>,
-) {
-    // for all styles:
-
-    val key: String = identity.key
-    val style: Style = identity.style
-
-    val skeletonSmallIcon: Flow<Icon?> = content.map { it.skeletonSmallIcon }
-    val appName: Flow<CharSequence?> = content.map { it.appName }
-    val subText: Flow<CharSequence?> = content.map { it.subText }
-
-    private val time: Flow<When?> = content.map { it.time }
-    val whenTime: Flow<Long?> = time.map { it?.time }
-    val whenMode: Flow<When.Mode?> = time.map { it?.mode }
-
-    val lastAudiblyAlertedMs: Flow<Long> = content.map { it.lastAudiblyAlertedMs }
-    val profileBadgeResId: Flow<Int?> = content.map { it.profileBadgeResId }
-    val title: Flow<CharSequence?> = content.map { it.title }
-    val text: Flow<CharSequence?> = content.map { it.text }
-    val skeletonLargeIcon: Flow<Icon?> = content.map { it.skeletonLargeIcon }
-
-    // for CallStyle:
-    val personIcon: Flow<Icon?> = content.map { it.personIcon }
-    val personName: Flow<CharSequence?> = content.map { it.personName }
-    val verificationIcon: Flow<Icon?> = content.map { it.verificationIcon }
-    val verificationText: Flow<CharSequence?> = content.map { it.verificationText }
-
-    // for ProgressStyle:
-    val progress: Flow<NotificationProgressModel?> = content.map { it.progress }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfo.java
deleted file mode 100644
index 9c6e41c..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/BundleNotificationInfo.java
+++ /dev/null
@@ -1,124 +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.row;
-
-import android.app.INotificationManager;
-import android.app.NotificationChannel;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.RemoteException;
-import android.service.notification.NotificationAssistantService;
-import android.service.notification.StatusBarNotification;
-import android.util.AttributeSet;
-import android.view.View;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.res.R;
-import com.android.systemui.statusbar.notification.AssistantFeedbackController;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-
-import java.util.List;
-
-/**
- * The guts of a notification revealed when performing a long press.
- */
-public class BundleNotificationInfo extends NotificationInfo {
-    private static final String TAG = "BundleNotifInfoGuts";
-
-    public BundleNotificationInfo(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    public void bindNotification(
-            PackageManager pm,
-            INotificationManager iNotificationManager,
-            OnUserInteractionCallback onUserInteractionCallback,
-            ChannelEditorDialogController channelEditorDialogController,
-            String pkg,
-            NotificationChannel notificationChannel,
-            NotificationEntry entry,
-            OnSettingsClickListener onSettingsClick,
-            OnAppSettingsClickListener onAppSettingsClick,
-            UiEventLogger uiEventLogger,
-            boolean isDeviceProvisioned,
-            boolean isNonblockable,
-            boolean wasShownHighPriority,
-            AssistantFeedbackController assistantFeedbackController,
-            MetricsLogger metricsLogger, OnClickListener onCloseClick) throws RemoteException {
-        super.bindNotification(pm, iNotificationManager, onUserInteractionCallback,
-                channelEditorDialogController, pkg, notificationChannel, entry, onSettingsClick,
-                onAppSettingsClick, uiEventLogger, isDeviceProvisioned, isNonblockable,
-                wasShownHighPriority, assistantFeedbackController, metricsLogger, onCloseClick);
-
-        // Additionally, bind the feedback button.
-        ComponentName assistant = iNotificationManager.getAllowedNotificationAssistant();
-        bindFeedback(entry.getSbn(), pm, assistant, onAppSettingsClick);
-    }
-
-    protected void bindFeedback(StatusBarNotification sbn, PackageManager pm,
-            ComponentName assistant,
-            NotificationInfo.OnAppSettingsClickListener appSettingsClickListener) {
-        View feedbackButton = findViewById(R.id.notification_guts_bundle_feedback);
-        // If the assistant component is null, don't show the feedback button and finish.
-        if (assistant == null) {
-            feedbackButton.setVisibility(GONE);
-            return;
-        }
-        // Otherwise we extract the assistant package name.
-        String assistantPkg = assistant.getPackageName();
-
-        feedbackButton.setOnClickListener(getBundleFeedbackClickListener(sbn, pm, assistantPkg,
-                appSettingsClickListener));
-        feedbackButton.setVisibility(feedbackButton.hasOnClickListeners() ? VISIBLE : GONE);
-    }
-
-    private OnClickListener getBundleFeedbackClickListener(StatusBarNotification sbn,
-            PackageManager pm, String assistantPkg,
-            NotificationInfo.OnAppSettingsClickListener appSettingsClickListener) {
-        Intent feedbackIntent = getBundleFeedbackIntent(pm, assistantPkg, sbn.getKey());
-        if (feedbackIntent != null) {
-            return ((View view) -> {
-                appSettingsClickListener.onClick(view, feedbackIntent);
-            });
-        }
-        return null;
-    }
-
-    private Intent getBundleFeedbackIntent(PackageManager pm, String packageName, String key) {
-        Intent intent = new Intent(
-                NotificationAssistantService.ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS)
-                .setPackage(packageName);
-        final List<ResolveInfo> resolveInfos = pm.queryIntentActivities(
-                intent,
-                PackageManager.MATCH_DEFAULT_ONLY
-        );
-        if (resolveInfos == null || resolveInfos.size() == 0 || resolveInfos.get(0) == null) {
-            return null;
-        }
-        final ActivityInfo activityInfo = resolveInfos.get(0).activityInfo;
-        intent.setClassName(activityInfo.packageName, activityInfo.name);
-        intent.putExtra(NotificationAssistantService.EXTRA_NOTIFICATION_KEY, key);
-        return intent;
-    }
-}
-
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 a6dde10..15f3168 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
@@ -71,7 +71,6 @@
 import androidx.annotation.Nullable;
 import androidx.dynamicanimation.animation.FloatPropertyCompat;
 import androidx.dynamicanimation.animation.SpringAnimation;
-import androidx.dynamicanimation.animation.SpringForce;
 
 import com.android.app.animation.Interpolators;
 import com.android.internal.annotations.VisibleForTesting;
@@ -361,39 +360,14 @@
         }
     };
 
-    private final SpringAnimation mMagneticAnimator = new SpringAnimation(
-            this, FloatPropertyCompat.createFloatPropertyCompat(TRANSLATE_CONTENT));
-
-    private final MagneticRowListener mMagneticRowListener = new MagneticRowListener() {
-
-        @Override
-        public void setMagneticTranslation(float translation) {
-            if (mMagneticAnimator.isRunning()) {
-                mMagneticAnimator.animateToFinalPosition(translation);
-            } else {
-                setTranslation(translation);
-            }
-        }
-
-        @Override
-        public void triggerMagneticForce(float endTranslation, @NonNull SpringForce springForce,
-                float startVelocity) {
-            cancelMagneticAnimations();
-            mMagneticAnimator.setSpring(springForce);
-            mMagneticAnimator.setStartVelocity(startVelocity);
-            mMagneticAnimator.animateToFinalPosition(endTranslation);
-        }
-
-        @Override
-        public void cancelMagneticAnimations() {
-            cancelSnapBackAnimation();
-            cancelTranslateAnimation();
-            mMagneticAnimator.cancel();
-        }
-    };
+    @Override
+    protected void cancelTranslationAnimations() {
+        cancelSnapBackAnimation();
+        cancelTranslateAnimation();
+    }
 
     private void cancelSnapBackAnimation() {
-        PhysicsAnimator<ExpandableNotificationRow> animator =
+        PhysicsAnimator<ExpandableView> animator =
                 PhysicsAnimator.getInstanceIfExists(this /* target */);
         if (animator != null) {
             animator.cancel();
@@ -1497,9 +1471,6 @@
             items.add(NotificationMenuRow.createPartialConversationItem(mContext));
             items.add(NotificationMenuRow.createInfoItem(mContext));
             items.add(NotificationMenuRow.createSnoozeItem(mContext));
-            if (android.app.Flags.notificationClassificationUi()) {
-                items.add(NotificationMenuRow.createBundleItem(mContext));
-            }
             mMenuRow.setMenuItems(items);
         }
         if (existed) {
@@ -2047,6 +2018,8 @@
                 new NotificationInlineImageCache());
         float radius = getResources().getDimension(R.dimen.notification_corner_radius_small);
         mSmallRoundness = radius / getMaxRadius();
+        mMagneticAnimator = new SpringAnimation(
+                this, FloatPropertyCompat.createFloatPropertyCompat(TRANSLATE_CONTENT));
         initDimens();
     }
 
@@ -3303,6 +3276,19 @@
     }
 
     /**
+     * For the case of an {@link ExpandableNotificationRow}, the dismissibility of the row considers
+     * the exposure of guts, the state of the  notification entry, and if the view itself is allowed
+     * to be dismissed.
+     */
+    @Override
+    public boolean canExpandableViewBeDismissed() {
+        if (areGutsExposed() || !mEntry.hasFinishedInitialization()) {
+            return false;
+        }
+        return canViewBeDismissed();
+    }
+
+    /**
      * @return Whether this view is allowed to be dismissed. Only valid for visible notifications as
      * otherwise some state might not be updated.
      */
@@ -4070,6 +4056,11 @@
         mLayouts = new NotificationContentView[]{mPrivateLayout, mPublicLayout};
     }
 
+    @VisibleForTesting
+    public void setMagneticRowListener(MagneticRowListener listener) {
+        mMagneticRowListener = listener;
+    }
+
     /**
      * Equivalent to View.OnLongClickListener with coordinates
      */
@@ -4320,8 +4311,4 @@
         }
         mLogger.logRemoveTransientRow(row.getEntry(), getEntry());
     }
-
-    public MagneticRowListener getMagneticRowListener() {
-        return mMagneticRowListener;
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index f83a1d9..76ba7f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -33,6 +33,9 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.dynamicanimation.animation.DynamicAnimation;
+import androidx.dynamicanimation.animation.SpringAnimation;
+import androidx.dynamicanimation.animation.SpringForce;
 
 import com.android.app.animation.Interpolators;
 import com.android.systemui.Dumpable;
@@ -42,6 +45,7 @@
 import com.android.systemui.statusbar.notification.RoundableState;
 import com.android.systemui.statusbar.notification.headsup.PinnedStatus;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
+import com.android.systemui.statusbar.notification.stack.MagneticRowListener;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.util.Compile;
 import com.android.systemui.util.DumpUtilsKt;
@@ -85,6 +89,55 @@
     protected boolean mLastInSection;
     protected boolean mFirstInSection;
 
+    protected SpringAnimation mMagneticAnimator = new SpringAnimation(
+            this /* object */, DynamicAnimation.TRANSLATION_X);
+
+    protected MagneticRowListener mMagneticRowListener = new MagneticRowListener() {
+
+        @Override
+        public void setMagneticTranslation(float translation) {
+            if (mMagneticAnimator.isRunning()) {
+                mMagneticAnimator.animateToFinalPosition(translation);
+            } else {
+                setTranslation(translation);
+            }
+        }
+
+        @Override
+        public void triggerMagneticForce(float endTranslation, @NonNull SpringForce springForce,
+                float startVelocity) {
+            cancelMagneticAnimations();
+            mMagneticAnimator.setSpring(springForce);
+            mMagneticAnimator.setStartVelocity(startVelocity);
+            mMagneticAnimator.animateToFinalPosition(endTranslation);
+        }
+
+        @Override
+        public void cancelMagneticAnimations() {
+            cancelTranslationAnimations();
+            mMagneticAnimator.cancel();
+        }
+
+        @Override
+        public boolean canRowBeDismissed() {
+            return canExpandableViewBeDismissed();
+        }
+    };
+
+    /**
+     * @return true if the ExpandableView can be dismissed. False otherwise.
+     */
+    public boolean canExpandableViewBeDismissed() {
+        return false;
+    }
+
+    /** Cancel any trailing animations on the translation of the view */
+    protected void cancelTranslationAnimations(){}
+
+    public MagneticRowListener getMagneticRowListener() {
+        return mMagneticRowListener;
+    }
+
     public ExpandableView(Context context, AttributeSet attrs) {
         super(context, attrs);
         mViewState = createExpandableViewState();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index be9f60d..3c7d9ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -70,6 +70,7 @@
 import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
 import com.android.systemui.res.R;
 import com.android.systemui.shade.ShadeController;
+import com.android.systemui.statusbar.notification.NmSummarizationUiFlag;
 import com.android.systemui.statusbar.notification.NotificationChannelHelper;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
@@ -118,6 +119,7 @@
     private OnSettingsClickListener mOnSettingsClickListener;
     private NotificationGuts mGutsContainer;
     private OnConversationSettingsClickListener mOnConversationSettingsClickListener;
+    private NotificationInfo.OnFeedbackClickListener mFeedbackClickListener;
 
     private UserManager mUm;
 
@@ -202,6 +204,7 @@
             NotificationEntry entry,
             Notification.BubbleMetadata bubbleMetadata,
             OnSettingsClickListener onSettingsClick,
+            NotificationInfo.OnFeedbackClickListener onFeedbackClickListener,
             ConversationIconFactory conversationIconFactory,
             Context userContext,
             boolean isDeviceProvisioned,
@@ -234,6 +237,7 @@
         mBgHandler = bgHandler;
         mShortcutManager = shortcutManager;
         mShortcutInfo = entry.getRanking().getConversationShortcutInfo();
+        mFeedbackClickListener = onFeedbackClickListener;
         if (mShortcutInfo == null) {
             throw new IllegalArgumentException("Does not have required information");
         }
@@ -288,6 +292,8 @@
         settingsButton.setOnClickListener(getSettingsOnClickListener());
         settingsButton.setVisibility(settingsButton.hasOnClickListeners() ? VISIBLE : GONE);
 
+        bindFeedback();
+
         updateToggleActions(mSelectedAction == -1 ? getPriority() : mSelectedAction,
                 false);
     }
@@ -299,6 +305,25 @@
         bindDelegate();
     }
 
+    private void bindFeedback() {
+        View feedbackButton = findViewById(R.id.feedback);
+        if (!NmSummarizationUiFlag.isEnabled()
+                || TextUtils.isEmpty(mEntry.getRanking().getSummarization())) {
+            feedbackButton.setVisibility(GONE);
+        } else {
+            Intent intent = NotificationInfo.getAssistantFeedbackIntent(
+                    mINotificationManager, mPm, mEntry);
+            if (intent == null) {
+                feedbackButton.setVisibility(GONE);
+            } else {
+                feedbackButton.setVisibility(VISIBLE);
+                feedbackButton.setOnClickListener((View v) -> {
+                    mFeedbackClickListener.onClick(v, intent);
+                });
+            }
+        }
+    }
+
     private OnClickListener getSettingsOnClickListener() {
         if (mAppUid >= 0 && mOnSettingsClickListener != null && mIsDeviceProvisioned) {
             final int appUidF = mAppUid;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 445cd01..430e5e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -18,14 +18,22 @@
 import static android.app.AppOpsManager.OP_CAMERA;
 import static android.app.AppOpsManager.OP_RECORD_AUDIO;
 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
+import static android.service.notification.Adjustment.KEY_SUMMARIZATION;
+import static android.service.notification.Adjustment.KEY_TYPE;
+import static android.service.notification.NotificationAssistantService.ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS;
+import static android.service.notification.NotificationAssistantService.EXTRA_NOTIFICATION_ADJUSTMENT;
+import static android.service.notification.NotificationAssistantService.EXTRA_NOTIFICATION_KEY;
 
 import android.annotation.FlaggedApi;
 import android.app.INotificationManager;
 import android.app.NotificationChannel;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.pm.ShortcutManager;
 import android.net.Uri;
 import android.os.Bundle;
@@ -33,6 +41,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.service.notification.NotificationAssistantService;
 import android.service.notification.StatusBarNotification;
 import android.util.ArraySet;
 import android.util.IconDrawableFactory;
@@ -78,6 +87,7 @@
 import com.android.systemui.util.kotlin.JavaAdapter;
 import com.android.systemui.wmshell.BubblesManager;
 
+import java.util.List;
 import java.util.Optional;
 
 import javax.inject.Inject;
@@ -325,9 +335,6 @@
                         (PartialConversationInfo) gutsView);
             } else if (gutsView instanceof FeedbackInfo) {
                 initializeFeedbackInfo(row, (FeedbackInfo) gutsView);
-            } else if (android.app.Flags.notificationClassificationUi()
-                    && gutsView instanceof BundleNotificationInfo) {
-                initializeBundleNotificationInfo(row, (BundleNotificationInfo) gutsView);
             }
             return true;
         } catch (Exception e) {
@@ -412,60 +419,10 @@
             };
         }
 
-        notificationInfoView.bindNotification(
-                pmUser,
-                mNotificationManager,
-                mOnUserInteractionCallback,
-                mChannelEditorDialogController,
-                packageName,
-                row.getEntry().getChannel(),
-                row.getEntry(),
-                onSettingsClick,
-                onAppSettingsClick,
-                mUiEventLogger,
-                mDeviceProvisionedController.isDeviceProvisioned(),
-                row.getIsNonblockable(),
-                mHighPriorityProvider.isHighPriority(row.getEntry()),
-                mAssistantFeedbackController,
-                mMetricsLogger,
-                row.getCloseButtonOnClickListener(row));
-    }
-
-    /**
-     * Sets up the {@link BundleNotificationInfo} inside the notification row's guts.
-     * @param row view to set up the guts for
-     * @param notificationInfoView view to set up/bind within {@code row}
-     */
-    @VisibleForTesting
-    @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
-    void initializeBundleNotificationInfo(
-            final ExpandableNotificationRow row,
-            BundleNotificationInfo notificationInfoView) throws Exception {
-        NotificationGuts guts = row.getGuts();
-        StatusBarNotification sbn = row.getEntry().getSbn();
-        String packageName = sbn.getPackageName();
-        // Settings link is only valid for notifications that specify a non-system user
-        NotificationInfo.OnSettingsClickListener onSettingsClick = null;
-        UserHandle userHandle = sbn.getUser();
-        PackageManager pmUser = CentralSurfaces.getPackageManagerForUser(
-                mContext, userHandle.getIdentifier());
-        final NotificationInfo.OnAppSettingsClickListener onAppSettingsClick =
-                (View v, Intent intent) -> {
-                    mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_APP_NOTE_SETTINGS);
-                    guts.resetFalsingCheck();
-                    mNotificationActivityStarter.startNotificationGutsIntent(intent, sbn.getUid(),
-                            row);
-                };
-
-        if (!userHandle.equals(UserHandle.ALL)
-                || mLockscreenUserManager.getCurrentUserId() == UserHandle.USER_SYSTEM) {
-            onSettingsClick = (View v, NotificationChannel channel, int appUid) -> {
-                mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_NOTE_INFO);
-                guts.resetFalsingCheck();
-                mOnSettingsClickListener.onSettingsClick(sbn.getKey());
-                startAppNotificationSettingsActivity(packageName, appUid, channel, row);
-            };
-        }
+        NotificationInfo.OnFeedbackClickListener onNasFeedbackClick = (View v, Intent intent) -> {
+            guts.resetFalsingCheck();
+            mNotificationActivityStarter.startNotificationGutsIntent(intent, sbn.getUid(), row);
+        };
 
         notificationInfoView.bindNotification(
                 pmUser,
@@ -477,6 +434,7 @@
                 row.getEntry(),
                 onSettingsClick,
                 onAppSettingsClick,
+                onNasFeedbackClick,
                 mUiEventLogger,
                 mDeviceProvisionedController.isDeviceProvisioned(),
                 row.getIsNonblockable(),
@@ -572,6 +530,11 @@
                 mContext.getResources().getDimensionPixelSize(
                         R.dimen.notification_guts_conversation_icon_size));
 
+        NotificationInfo.OnFeedbackClickListener onNasFeedbackClick = (View v, Intent intent) -> {
+            guts.resetFalsingCheck();
+            mNotificationActivityStarter.startNotificationGutsIntent(intent, sbn.getUid(), row);
+        };
+
         notificationInfoView.bindNotification(
                 mShortcutManager,
                 pmUser,
@@ -584,6 +547,7 @@
                 entry,
                 entry.getBubbleMetadata(),
                 onSettingsClick,
+                onNasFeedbackClick,
                 iconFactoryLoader,
                 mContextTracker.getUserContext(),
                 mDeviceProvisionedController.isDeviceProvisioned(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index 8d26f94..bea14b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -17,9 +17,12 @@
 package com.android.systemui.statusbar.notification.row;
 
 import static android.app.Notification.EXTRA_BUILDER_APPLICATION_INFO;
+import static android.app.NotificationChannel.SYSTEM_RESERVED_IDS;
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+import static android.service.notification.Adjustment.KEY_SUMMARIZATION;
+import static android.service.notification.Adjustment.KEY_TYPE;
 
 import static com.android.app.animation.Interpolators.FAST_OUT_SLOW_IN;
 
@@ -27,10 +30,12 @@
 
 import android.annotation.IntDef;
 import android.annotation.Nullable;
+import android.app.Flags;
 import android.app.INotificationManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -41,6 +46,7 @@
 import android.metrics.LogMaker;
 import android.os.Handler;
 import android.os.RemoteException;
+import android.service.notification.NotificationAssistantService;
 import android.service.notification.StatusBarNotification;
 import android.text.Html;
 import android.text.TextUtils;
@@ -50,6 +56,7 @@
 import android.transition.TransitionSet;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.Slog;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.ImageView;
@@ -63,6 +70,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.AssistantFeedbackController;
+import com.android.systemui.statusbar.notification.NmSummarizationUiFlag;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 
 import java.lang.annotation.Retention;
@@ -126,6 +134,7 @@
 
     private OnSettingsClickListener mOnSettingsClickListener;
     private OnAppSettingsClickListener mAppSettingsClickListener;
+    private OnFeedbackClickListener mFeedbackClickListener;
     private NotificationGuts mGutsContainer;
     private Drawable mPkgIcon;
     private UiEventLogger mUiEventLogger;
@@ -187,6 +196,10 @@
         void onClick(View v, Intent intent);
     }
 
+    public interface OnFeedbackClickListener {
+        void onClick(View v, Intent intent);
+    }
+
     public void bindNotification(
             PackageManager pm,
             INotificationManager iNotificationManager,
@@ -197,6 +210,7 @@
             NotificationEntry entry,
             OnSettingsClickListener onSettingsClick,
             OnAppSettingsClickListener onAppSettingsClick,
+            OnFeedbackClickListener onFeedbackClickListener,
             UiEventLogger uiEventLogger,
             boolean isDeviceProvisioned,
             boolean isNonblockable,
@@ -214,6 +228,7 @@
         mSbn = entry.getSbn();
         mPm = pm;
         mAppSettingsClickListener = onAppSettingsClick;
+        mFeedbackClickListener = onFeedbackClickListener;
         mAppName = mPackageName;
         mOnSettingsClickListener = onSettingsClick;
         mSingleNotificationChannel = notificationChannel;
@@ -318,19 +333,25 @@
         // Delegate
         bindDelegate();
 
-        // Set up app settings link (i.e. Customize)
-        View settingsLinkView = findViewById(R.id.app_settings);
-        Intent settingsIntent = getAppSettingsIntent(mPm, mPackageName,
-                mSingleNotificationChannel,
-                mSbn.getId(), mSbn.getTag());
-        if (settingsIntent != null
-                && !TextUtils.isEmpty(mSbn.getNotification().getSettingsText())) {
-            settingsLinkView.setVisibility(VISIBLE);
-            settingsLinkView.setOnClickListener((View view) -> {
-                mAppSettingsClickListener.onClick(view, settingsIntent);
-            });
+
+        if (Flags.notificationClassificationUi() &&
+                SYSTEM_RESERVED_IDS.contains(mSingleNotificationChannel.getId())) {
+            bindFeedback();
         } else {
-            settingsLinkView.setVisibility(View.GONE);
+            // Set up app settings link (i.e. Customize)
+            View settingsLinkView = findViewById(R.id.app_settings);
+            Intent settingsIntent = getAppSettingsIntent(mPm, mPackageName,
+                    mSingleNotificationChannel,
+                    mSbn.getId(), mSbn.getTag());
+            if (settingsIntent != null
+                    && !TextUtils.isEmpty(mSbn.getNotification().getSettingsText())) {
+                settingsLinkView.setVisibility(VISIBLE);
+                settingsLinkView.setOnClickListener((View view) -> {
+                    mAppSettingsClickListener.onClick(view, settingsIntent);
+                });
+            } else {
+                settingsLinkView.setVisibility(View.GONE);
+            }
         }
 
         // System Settings button.
@@ -339,6 +360,51 @@
         settingsButton.setVisibility(settingsButton.hasOnClickListeners() ? VISIBLE : GONE);
     }
 
+    private void bindFeedback() {
+        View feedbackButton = findViewById(R.id.feedback);
+        Intent intent = getAssistantFeedbackIntent(mINotificationManager, mPm, mEntry);
+        if (!android.app.Flags.notificationClassificationUi() || intent == null) {
+            feedbackButton.setVisibility(GONE);
+        } else {
+            feedbackButton.setVisibility(VISIBLE);
+            feedbackButton.setOnClickListener((View v) -> {
+                if (mFeedbackClickListener != null) {
+                    mFeedbackClickListener.onClick(v, intent);
+                }
+            });
+        }
+    }
+
+    public static Intent getAssistantFeedbackIntent(INotificationManager inm, PackageManager pm,
+            NotificationEntry entry) {
+        try {
+            ComponentName assistant = inm.getAllowedNotificationAssistant();
+            if (assistant == null) {
+                return null;
+            }
+            Intent intent = new Intent(
+                    NotificationAssistantService.ACTION_NOTIFICATION_ASSISTANT_FEEDBACK_SETTINGS)
+                    .setPackage(assistant.getPackageName());
+            final List<ResolveInfo> resolveInfos = pm.queryIntentActivities(
+                    intent,
+                    PackageManager.MATCH_DEFAULT_ONLY
+            );
+            if (resolveInfos == null || resolveInfos.size() == 0 || resolveInfos.get(0) == null) {
+                return null;
+            }
+            final ActivityInfo activityInfo = resolveInfos.get(0).activityInfo;
+            intent.setClassName(activityInfo.packageName, activityInfo.name);
+
+            intent.putExtra(NotificationAssistantService.EXTRA_NOTIFICATION_KEY, entry.getKey());
+            intent.putExtra(NotificationAssistantService.EXTRA_NOTIFICATION_ADJUSTMENT,
+                    entry.getRanking().getSummarization() != null ? KEY_SUMMARIZATION : KEY_TYPE);
+            return intent;
+        } catch (Exception e) {
+            Slog.d(TAG, "no assistant?", e);
+            return null;
+        }
+    }
+
     private OnClickListener getSettingsOnClickListener() {
         if (mAppUid >= 0 && mOnSettingsClickListener != null && mIsDeviceProvisioned) {
             final int appUidF = mAppUid;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index d213c78..b96b224a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -263,12 +263,7 @@
         mFeedbackItem = createFeedbackItem(mContext);
         NotificationEntry entry = mParent.getEntry();
         int personNotifType = mPeopleNotificationIdentifier.getPeopleNotificationType(entry);
-        if (android.app.Flags.notificationClassificationUi()
-                && entry.getChannel() != null
-                && SYSTEM_RESERVED_IDS.contains(entry.getChannel().getId())) {
-            // Bundled notification; create bundle-specific guts.
-            mInfoItem = createBundleItem(mContext);
-        } else if (personNotifType == PeopleNotificationIdentifier.TYPE_PERSON) {
+        if (personNotifType == PeopleNotificationIdentifier.TYPE_PERSON) {
             mInfoItem = createPartialConversationItem(mContext);
         } else if (personNotifType >= PeopleNotificationIdentifier.TYPE_FULL_PERSON) {
             mInfoItem = createConversationItem(mContext);
@@ -698,16 +693,6 @@
                 R.drawable.ic_settings);
     }
 
-    static NotificationMenuItem createBundleItem(Context context) {
-        Resources res = context.getResources();
-        String infoDescription = res.getString(R.string.notification_menu_gear_description);
-        BundleNotificationInfo infoContent =
-                (BundleNotificationInfo) LayoutInflater.from(context).inflate(
-                        R.layout.bundle_notification_info, null, false);
-        return new NotificationMenuItem(context, infoDescription, infoContent,
-                R.drawable.ic_settings);
-    }
-
     static NotificationMenuItem createPartialConversationItem(Context context) {
         Resources res = context.getResources();
         String infoDescription = res.getString(R.string.notification_menu_gear_description);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt
index a0b0415..9e1c974 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt
@@ -219,6 +219,21 @@
             { "Failed to set magnetic and roundable targets for $str1 on state $str2." },
         )
     }
+
+    fun logMagneticRowTranslationNotSet(
+        state: MagneticNotificationRowManagerImpl.State,
+        entry: NotificationEntry,
+    ) {
+        buffer.log(
+            TAG,
+            LogLevel.ERROR,
+            {
+                str1 = entry.logKey
+                str2 = state.name
+            },
+            { "Failed to set magnetic row translation for $str1 on state $str2." },
+        )
+    }
 }
 
 private const val TAG = "NotifRow"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfo.java
index e4a0fa5..93b2a2d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfo.java
@@ -56,6 +56,7 @@
             NotificationEntry entry,
             OnSettingsClickListener onSettingsClick,
             OnAppSettingsClickListener onAppSettingsClick,
+            OnFeedbackClickListener feedbackClickListener,
             UiEventLogger uiEventLogger,
             boolean isDeviceProvisioned,
             boolean isNonblockable,
@@ -64,8 +65,9 @@
             MetricsLogger metricsLogger, OnClickListener onCloseClick) throws RemoteException {
         super.bindNotification(pm, iNotificationManager, onUserInteractionCallback,
                 channelEditorDialogController, pkg, notificationChannel, entry, onSettingsClick,
-                onAppSettingsClick, uiEventLogger, isDeviceProvisioned, isNonblockable,
-                wasShownHighPriority, assistantFeedbackController, metricsLogger, onCloseClick);
+                onAppSettingsClick, feedbackClickListener, uiEventLogger, isDeviceProvisioned,
+                isNonblockable, wasShownHighPriority, assistantFeedbackController, metricsLogger,
+                onCloseClick);
 
         mNotificationManager = iNotificationManager;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
index ab8be30..f00c3ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt
@@ -68,6 +68,8 @@
     val uid: Int,
     /** The notifying app's packageName. */
     val packageName: String,
+    /** The notifying app's display name. */
+    val appName: String,
     /** The intent to execute if UI related to this notification is clicked. */
     val contentIntent: PendingIntent?,
     /** A small per-notification ID, used for statsd logging. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt
index bddff12..3941700 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt
@@ -57,7 +57,7 @@
         SpringForce().setStiffness(SNAP_BACK_STIFFNESS).setDampingRatio(SNAP_BACK_DAMPING_RATIO)
 
     // Multiplier applied to the translation of a row while swiped
-    private val swipedRowMultiplier =
+    val swipedRowMultiplier =
         MAGNETIC_TRANSLATION_MULTIPLIERS[MAGNETIC_TRANSLATION_MULTIPLIERS.size / 2]
 
     override fun setSwipeThresholdPx(thresholdPx: Float) {
@@ -111,48 +111,75 @@
     ): Boolean {
         if (!row.isSwipedTarget()) return false
 
+        val canTargetBeDismissed =
+            currentMagneticListeners.swipedListener()?.canRowBeDismissed() ?: false
         when (currentState) {
+            State.IDLE -> {
+                logger.logMagneticRowTranslationNotSet(currentState, row.entry)
+                return false
+            }
             State.TARGETS_SET -> {
-                pullTargets(translation)
+                pullTargets(translation, canTargetBeDismissed)
                 currentState = State.PULLING
             }
             State.PULLING -> {
-                val targetTranslation = swipedRowMultiplier * translation
-                val crossedThreshold = abs(targetTranslation) >= magneticDetachThreshold
-                if (crossedThreshold) {
-                    snapNeighborsBack()
-                    currentMagneticListeners.swipedListener()?.let { detach(it, translation) }
-                    currentState = State.DETACHED
+                if (canTargetBeDismissed) {
+                    pullDismissibleRow(translation)
                 } else {
-                    pullTargets(translation)
+                    pullTargets(translation, canSwipedBeDismissed = false)
                 }
             }
             State.DETACHED -> {
                 val swiped = currentMagneticListeners.swipedListener()
                 swiped?.setMagneticTranslation(translation)
             }
-            else -> {}
         }
         return true
     }
 
-    private fun pullTargets(translation: Float) {
-        var targetTranslation: Float
-        currentMagneticListeners.forEachIndexed { i, listener ->
-            targetTranslation = MAGNETIC_TRANSLATION_MULTIPLIERS[i] * translation
-            listener?.setMagneticTranslation(targetTranslation)
+    private fun pullDismissibleRow(translation: Float) {
+        val targetTranslation = swipedRowMultiplier * translation
+        val crossedThreshold = abs(targetTranslation) >= magneticDetachThreshold
+        if (crossedThreshold) {
+            snapNeighborsBack()
+            currentMagneticListeners.swipedListener()?.let { detach(it, translation) }
+            currentState = State.DETACHED
+        } else {
+            pullTargets(translation, canSwipedBeDismissed = true)
         }
-        playPullHaptics(mappedTranslation = swipedRowMultiplier * translation)
     }
 
-    private fun playPullHaptics(mappedTranslation: Float) {
+    private fun pullTargets(translation: Float, canSwipedBeDismissed: Boolean) {
+        var targetTranslation: Float
+        currentMagneticListeners.forEachIndexed { i, listener ->
+            listener?.let {
+                if (!canSwipedBeDismissed || !it.canRowBeDismissed()) {
+                    // Use a reduced translation if the target swiped can't be dismissed or if the
+                    // target itself can't be dismissed
+                    targetTranslation =
+                        MAGNETIC_TRANSLATION_MULTIPLIERS[i] * translation * MAGNETIC_REDUCTION
+                } else {
+                    targetTranslation = MAGNETIC_TRANSLATION_MULTIPLIERS[i] * translation
+                }
+                it.setMagneticTranslation(targetTranslation)
+            }
+        }
+        playPullHaptics(mappedTranslation = swipedRowMultiplier * translation, canSwipedBeDismissed)
+    }
+
+    private fun playPullHaptics(mappedTranslation: Float, canSwipedBeDismissed: Boolean) {
         val normalizedTranslation = abs(mappedTranslation) / magneticDetachThreshold
-        val vibrationScale =
-            (normalizedTranslation * MAX_VIBRATION_SCALE).pow(VIBRATION_PERCEPTION_EXPONENT)
+        val scaleFactor =
+            if (canSwipedBeDismissed) {
+                WEAK_VIBRATION_SCALE
+            } else {
+                STRONG_VIBRATION_SCALE
+            }
+        val vibrationScale = scaleFactor * normalizedTranslation
         msdlPlayer.playToken(
             MSDLToken.DRAG_INDICATOR_CONTINUOUS,
             InteractionProperties.DynamicVibrationScale(
-                scale = vibrationScale,
+                scale = vibrationScale.pow(VIBRATION_PERCEPTION_EXPONENT),
                 vibrationAttributes = VIBRATION_ATTRIBUTES_PIPELINING,
             ),
         )
@@ -230,6 +257,8 @@
          */
         private val MAGNETIC_TRANSLATION_MULTIPLIERS = listOf(0.18f, 0.28f, 0.5f, 0.28f, 0.18f)
 
+        const val MAGNETIC_REDUCTION = 0.65f
+
         /** Spring parameters for physics animators */
         private const val DETACH_STIFFNESS = 800f
         private const val DETACH_DAMPING_RATIO = 0.95f
@@ -241,7 +270,8 @@
                 .setUsage(VibrationAttributes.USAGE_TOUCH)
                 .setFlags(VibrationAttributes.FLAG_PIPELINED_EFFECT)
                 .build()
-        private const val MAX_VIBRATION_SCALE = 0.2f
         private const val VIBRATION_PERCEPTION_EXPONENT = 1 / 0.89f
+        private const val WEAK_VIBRATION_SCALE = 0.2f
+        private const val STRONG_VIBRATION_SCALE = 0.45f
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticRowListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticRowListener.kt
index 8a1adfe..46036d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticRowListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticRowListener.kt
@@ -41,4 +41,7 @@
 
     /** Cancel any animations related to the magnetic interactions of the row */
     fun cancelMagneticAnimations()
+
+    /** Can the row be dismissed. */
+    fun canRowBeDismissed(): Boolean
 }
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 8760901..d6b34b0 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
@@ -26,6 +26,7 @@
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_SHADE_CLEAR_ALL;
 import static com.android.systemui.Flags.magneticNotificationSwipes;
 import static com.android.systemui.Flags.notificationOverExpansionClippingFix;
+import static com.android.systemui.Flags.notificationsRedesignFooterView;
 import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SILENT;
 import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE;
 import static com.android.systemui.statusbar.notification.stack.shared.model.AccessibilityScrollEvent.SCROLL_DOWN;
@@ -694,11 +695,28 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
 
+        if (notificationsRedesignFooterView()) {
+            int bottomMargin = getBottomMargin(getContext());
+            MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
+            lp.setMargins(lp.leftMargin, lp.topMargin, lp.rightMargin, bottomMargin);
+            setLayoutParams(lp);
+        }
+
         if (!ModesEmptyShadeFix.isEnabled()) {
             inflateEmptyShadeView();
         }
     }
 
+    /** Get the pixel value of the bottom margin, taking flags into account. */
+    public static int getBottomMargin(Context context) {
+        Resources res = context.getResources();
+        if (notificationsRedesignFooterView()) {
+            return res.getDimensionPixelSize(R.dimen.notification_2025_panel_margin_bottom);
+        } else {
+            return res.getDimensionPixelSize(R.dimen.notification_panel_margin_bottom);
+        }
+    }
+
     /**
      * Sets whether keyguard bypass is enabled. If true, this layout will be rendered in bypass
      * mode when it is on the keyguard.
@@ -6591,10 +6609,7 @@
 
     static boolean canChildBeDismissed(View v) {
         if (v instanceof ExpandableNotificationRow row) {
-            if (row.areGutsExposed() || !row.getEntry().hasFinishedInitialization()) {
-                return false;
-            }
-            return row.canViewBeDismissed();
+            return row.canExpandableViewBeDismissed();
         }
         return false;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt
index 74e8b8e..b69b936 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationTargetsHelper.kt
@@ -3,7 +3,9 @@
 import androidx.core.view.children
 import androidx.core.view.isVisible
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.NotificationShelf
 import com.android.systemui.statusbar.notification.Roundable
+import com.android.systemui.statusbar.notification.footer.ui.view.FooterView
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.ExpandableView
 import javax.inject.Inject
@@ -129,6 +131,10 @@
                     magneticTargets[leftIndex] = leftElement.magneticRowListener
                     leftIndex--
                 } else {
+                    if (leftElement.isValidMagneticBoundary()) {
+                        // Add the boundary and then stop the iterating
+                        magneticTargets[leftIndex] = leftElement?.magneticRowListener
+                    }
                     canMoveLeft = false
                 }
             }
@@ -138,12 +144,24 @@
                     magneticTargets[rightIndex] = rightElement.magneticRowListener
                     rightIndex++
                 } else {
+                    if (rightElement.isValidMagneticBoundary()) {
+                        // Add the boundary and then stop the iterating
+                        magneticTargets[rightIndex] = rightElement?.magneticRowListener
+                    }
                     canMoveRight = false
                 }
             }
         }
         return magneticTargets
     }
+
+    private fun ExpandableView?.isValidMagneticBoundary(): Boolean =
+        when (this) {
+            is FooterView,
+            is NotificationShelf,
+            is SectionHeaderView -> true
+            else -> false
+        }
 }
 
 /**
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 06b989a..673eb9f 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
@@ -107,7 +107,7 @@
         mGapHeightOnLockscreen = res.getDimensionPixelSize(
                 R.dimen.notification_section_divider_height_lockscreen);
         mNotificationScrimPadding = res.getDimensionPixelSize(R.dimen.notification_side_paddings);
-        mMarginBottom = res.getDimensionPixelSize(R.dimen.notification_panel_margin_bottom);
+        mMarginBottom = NotificationStackScrollLayout.getBottomMargin(context);
         mQuickQsOffsetHeight = SystemBarUtils.getQuickQsOffsetHeight(context);
         mSmallCornerRadius = res.getDimension(R.dimen.notification_corner_radius_small);
         mLargeCornerRadius = res.getDimension(R.dimen.notification_corner_radius);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt
index 1bd4440..96af833 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt
@@ -19,7 +19,7 @@
 
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.statusbar.notification.stack.data.repository.NotificationPlaceholderRepository
 import com.android.systemui.statusbar.notification.stack.data.repository.NotificationViewHeightRepository
@@ -45,7 +45,7 @@
     private val viewHeightRepository: NotificationViewHeightRepository,
     private val placeholderRepository: NotificationPlaceholderRepository,
     sceneInteractor: SceneInteractor,
-    shadeInteractor: ShadeInteractor,
+    shadeModeInteractor: ShadeModeInteractor,
 ) {
     /** The bounds of the notification stack in the current scene. */
     val notificationShadeScrimBounds: StateFlow<ShadeScrimBounds?> =
@@ -60,7 +60,7 @@
 
     /** The rounding of the notification stack. */
     val shadeScrimRounding: Flow<ShadeScrimRounding> =
-        combine(shadeInteractor.shadeMode, isExpandingFromHeadsUp) {
+        combine(shadeModeInteractor.shadeMode, isExpandingFromHeadsUp) {
                 shadeMode,
                 isExpandingFromHeadsUp ->
                 ShadeScrimRounding(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt
index 107875d..c8b3341 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/SharedNotificationContainerInteractor.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.LargeScreenHeaderHelper
 import com.android.systemui.shade.ShadeDisplayAware
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
 import com.android.systemui.statusbar.policy.SplitShadeStateController
 import dagger.Lazy
 import javax.inject.Inject
@@ -79,8 +80,7 @@
                             getBoolean(R.bool.config_use_large_screen_shade_header),
                         marginHorizontal =
                             getDimensionPixelSize(R.dimen.notification_panel_margin_horizontal),
-                        marginBottom =
-                            getDimensionPixelSize(R.dimen.notification_panel_margin_bottom),
+                        marginBottom = NotificationStackScrollLayout.getBottomMargin(context),
                         marginTop = getDimensionPixelSize(R.dimen.notification_panel_margin_top),
                         marginTopLargeScreen =
                             largeScreenHeaderHelperLazy.get().getLargeScreenHeaderHeight(),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationStatsLoggerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationStatsLoggerImpl.kt
index c8c798d..5689230 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationStatsLoggerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationStatsLoggerImpl.kt
@@ -19,6 +19,7 @@
 import android.service.notification.NotificationListenerService
 import androidx.annotation.VisibleForTesting
 import com.android.app.tracing.coroutines.TrackTracer
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.internal.statusbar.IStatusBarService
 import com.android.internal.statusbar.NotificationVisibility
 import com.android.systemui.dagger.SysUISingleton
@@ -33,8 +34,9 @@
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Job
-import com.android.app.tracing.coroutines.launchTraced as launch
+import kotlinx.coroutines.channels.BufferOverflow
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.channels.consumeEach
 import kotlinx.coroutines.withContext
 
 @VisibleForTesting const val UNKNOWN_RANK = -1
@@ -49,32 +51,56 @@
     private val notificationPanelLogger: NotificationPanelLogger,
     private val statusBarService: IStatusBarService,
 ) : NotificationStatsLogger {
-    private val lastLoggedVisibilities = mutableMapOf<String, VisibilityState>()
-    private var logVisibilitiesJob: Job? = null
-
     private val expansionStates: MutableMap<String, ExpansionState> =
         ConcurrentHashMap<String, ExpansionState>()
     @VisibleForTesting
     val lastReportedExpansionValues: MutableMap<String, Boolean> =
         ConcurrentHashMap<String, Boolean>()
 
+    private val visibilityLogger =
+        Channel<VisibilityAction>(capacity = 2, onBufferOverflow = BufferOverflow.DROP_OLDEST)
+
+    init {
+        applicationScope.launch { consumeVisibilityActions() }
+    }
+
+    private suspend fun consumeVisibilityActions() {
+        val lastLoggedVisibilities = mutableMapOf<String, VisibilityState>()
+
+        visibilityLogger.consumeEach { action ->
+            val newVisibilities =
+                when (action) {
+                    is VisibilityAction.Change -> action.visibilities
+                    is VisibilityAction.Clear -> emptyMap()
+                }
+
+            val newlyVisible = newVisibilities - lastLoggedVisibilities.keys
+            val noLongerVisible = lastLoggedVisibilities - newVisibilities.keys
+
+            maybeLogVisibilityChanges(newlyVisible, noLongerVisible, action.activeCount)
+            updateExpansionStates(newlyVisible, noLongerVisible)
+            TrackTracer.instantForGroup("Notifications", "Active", action.activeCount)
+            TrackTracer.instantForGroup("Notifications", "Visible", newVisibilities.size)
+
+            lastLoggedVisibilities.clear()
+            lastLoggedVisibilities.putAll(newVisibilities)
+        }
+    }
+
     override fun onNotificationLocationsChanged(
         locationsProvider: Callable<Map<String, Int>>,
         notificationRanks: Map<String, Int>,
     ) {
-        if (logVisibilitiesJob?.isActive == true) {
-            return
-        }
-
-        logVisibilitiesJob =
-            startLogVisibilitiesJob(
-                newVisibilities =
+        visibilityLogger.trySend(
+            VisibilityAction.Change(
+                visibilities =
                     combine(
                         visibilities = locationsProvider.call(),
-                        rankingsMap = notificationRanks
+                        rankingsMap = notificationRanks,
                     ),
-                activeNotifCount = notificationRanks.size,
+                activeCount = notificationRanks.size,
             )
+        )
     }
 
     override fun onNotificationExpansionChanged(
@@ -125,7 +151,7 @@
                     /* expanded = */ expansionState.isExpanded,
                     /* notificationLocation = */ expansionState.location
                         .toNotificationLocation()
-                        .ordinal
+                        .ordinal,
                 )
             }
         }
@@ -138,7 +164,7 @@
             withContext(bgDispatcher) {
                 notificationPanelLogger.logPanelShown(
                     isOnLockScreen,
-                    activeNotifications.toNotificationProto()
+                    activeNotifications.toNotificationProto(),
                 )
             }
         }
@@ -147,11 +173,7 @@
     override fun onLockscreenOrShadeNotInteractive(
         activeNotifications: List<ActiveNotificationModel>
     ) {
-        logVisibilitiesJob =
-            startLogVisibilitiesJob(
-                newVisibilities = emptyMap(),
-                activeNotifCount = activeNotifications.size
-            )
+        visibilityLogger.trySend(VisibilityAction.Clear(activeCount = activeNotifications.size))
     }
 
     override fun onNotificationRemoved(key: String) {
@@ -167,29 +189,12 @@
 
     private fun combine(
         visibilities: Map<String, Int>,
-        rankingsMap: Map<String, Int>
+        rankingsMap: Map<String, Int>,
     ): Map<String, VisibilityState> =
         visibilities.mapValues { entry ->
             VisibilityState(entry.key, entry.value, rankingsMap[entry.key] ?: UNKNOWN_RANK)
         }
 
-    private fun startLogVisibilitiesJob(
-        newVisibilities: Map<String, VisibilityState>,
-        activeNotifCount: Int,
-    ) =
-        applicationScope.launch {
-            val newlyVisible = newVisibilities - lastLoggedVisibilities.keys
-            val noLongerVisible = lastLoggedVisibilities - newVisibilities.keys
-
-            maybeLogVisibilityChanges(newlyVisible, noLongerVisible, activeNotifCount)
-            updateExpansionStates(newlyVisible, noLongerVisible)
-            TrackTracer.instantForGroup("Notifications", "Active", activeNotifCount)
-            TrackTracer.instantForGroup("Notifications", "Visible", newVisibilities.size)
-
-            lastLoggedVisibilities.clear()
-            lastLoggedVisibilities.putAll(newVisibilities)
-        }
-
     private suspend fun maybeLogVisibilityChanges(
         newlyVisible: Map<String, VisibilityState>,
         noLongerVisible: Map<String, VisibilityState>,
@@ -205,7 +210,7 @@
         val noLongerVisibleAr =
             noLongerVisible.mapToNotificationVisibilitiesAr(
                 visible = false,
-                count = activeNotifCount
+                count = activeNotifCount,
             )
 
         withContext(bgDispatcher) {
@@ -218,7 +223,7 @@
 
     private fun updateExpansionStates(
         newlyVisible: Map<String, VisibilityState>,
-        noLongerVisible: Map<String, VisibilityState>
+        noLongerVisible: Map<String, VisibilityState>,
     ) {
         expansionStates.forEach { (key, expansionState) ->
             if (newlyVisible.contains(key)) {
@@ -241,11 +246,16 @@
         }
     }
 
-    private data class VisibilityState(
-        val key: String,
-        val location: Int,
-        val rank: Int,
-    )
+    private sealed class VisibilityAction(open val activeCount: Int) {
+        data class Change(
+            val visibilities: Map<String, VisibilityState>,
+            override val activeCount: Int,
+        ) : VisibilityAction(activeCount)
+
+        data class Clear(override val activeCount: Int) : VisibilityAction(activeCount)
+    }
+
+    private data class VisibilityState(val key: String, val location: Int, val rank: Int)
 
     private data class ExpansionState(
         val key: String,
@@ -278,7 +288,7 @@
                     /* rank = */ state.rank,
                     /* count = */ count,
                     /* visible = */ visible,
-                    /* location = */ state.location.toNotificationLocation()
+                    /* location = */ state.location.toNotificationLocation(),
                 )
             }
             .toTypedArray()
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 f740144..ece1803 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
@@ -28,6 +28,7 @@
 import com.android.systemui.keyguard.ui.viewmodel.ViewStateAccessor
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.shared.Flags.extendedWallpaperEffects
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator
 import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
@@ -143,7 +144,7 @@
                     }
 
                     if (!SceneContainerFlag.isEnabled) {
-                        if (Flags.magicPortraitWallpapers()) {
+                        if (extendedWallpaperEffects()) {
                             launch {
                                 combine(
                                         viewModel.getNotificationStackAbsoluteBottom(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationLockscreenScrimViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationLockscreenScrimViewModel.kt
index d68f769..4a28b54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationLockscreenScrimViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationLockscreenScrimViewModel.kt
@@ -29,7 +29,7 @@
 import com.android.systemui.lifecycle.Hydrator
 import com.android.systemui.notifications.ui.composable.Notifications
 import com.android.systemui.res.R
-import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.shade.ui.composable.Shade
 import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
@@ -46,7 +46,7 @@
 @AssistedInject
 constructor(
     dumpManager: DumpManager,
-    shadeInteractor: ShadeInteractor,
+    shadeModeInteractor: ShadeModeInteractor,
     private val stackAppearanceInteractor: NotificationStackAppearanceInteractor,
 ) :
     ActivatableFlowDumper by ActivatableFlowDumperImpl(dumpManager, "NotificationScrollViewModel"),
@@ -54,7 +54,7 @@
 
     private val hydrator = Hydrator("NotificationLockscreenScrimViewModel.hydrator")
 
-    val shadeMode: StateFlow<ShadeMode> = shadeInteractor.shadeMode
+    val shadeMode: StateFlow<ShadeMode> = shadeModeInteractor.shadeMode
 
     /** The [ElementKey] to use for the scrim. */
     val element: ElementViewModel by
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 2014982..7f016a1 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
@@ -31,6 +31,7 @@
 import com.android.systemui.scene.shared.model.Overlays
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.statusbar.domain.interactor.RemoteInputInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
@@ -63,6 +64,7 @@
     dumpManager: DumpManager,
     private val stackAppearanceInteractor: NotificationStackAppearanceInteractor,
     shadeInteractor: ShadeInteractor,
+    shadeModeInteractor: ShadeModeInteractor,
     private val remoteInputInteractor: RemoteInputInteractor,
     private val sceneInteractor: SceneInteractor,
     // TODO(b/336364825) Remove Lazy when SceneContainerFlag is released -
@@ -151,10 +153,10 @@
     val expandFraction: Flow<Float> =
         combine(
                 shadeInteractor.shadeExpansion,
-                shadeInteractor.shadeMode,
                 shadeInteractor.qsExpansion,
+                shadeModeInteractor.shadeMode,
                 sceneInteractor.transitionState,
-            ) { shadeExpansion, _, qsExpansion, transitionState ->
+            ) { shadeExpansion, qsExpansion, _, transitionState ->
                 when (transitionState) {
                     is Idle ->
                         if (
@@ -210,7 +212,8 @@
         sceneInteractor.isSceneInFamily(scene, this)
 
     private val qsAllowsClipping: Flow<Boolean> =
-        combine(shadeInteractor.shadeMode, shadeInteractor.qsExpansion) { shadeMode, qsExpansion ->
+        combine(shadeModeInteractor.shadeMode, shadeInteractor.qsExpansion) { shadeMode, qsExpansion
+                ->
                 when (shadeMode) {
                     is ShadeMode.Dual -> false
                     is ShadeMode.Split -> true
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 8e12e08..000b3f6 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
@@ -30,6 +30,7 @@
 import com.android.systemui.scene.shared.model.Overlays
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.statusbar.domain.interactor.RemoteInputInteractor
 import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
@@ -58,6 +59,7 @@
     private val interactor: NotificationStackAppearanceInteractor,
     private val sceneInteractor: SceneInteractor,
     private val shadeInteractor: ShadeInteractor,
+    shadeModeInteractor: ShadeModeInteractor,
     private val headsUpNotificationInteractor: HeadsUpNotificationInteractor,
     remoteInputInteractor: RemoteInputInteractor,
     featureFlags: FeatureFlagsClassic,
@@ -75,16 +77,16 @@
     val notificationsShadeContentKey: ContentKey by
         hydrator.hydratedStateOf(
             traceName = "notificationsShadeContentKey",
-            initialValue = getNotificationsShadeContentKey(shadeInteractor.shadeMode.value),
-            source = shadeInteractor.shadeMode.map { getNotificationsShadeContentKey(it) },
+            initialValue = getNotificationsShadeContentKey(shadeModeInteractor.shadeMode.value),
+            source = shadeModeInteractor.shadeMode.map { getNotificationsShadeContentKey(it) },
         )
 
     /** The content key to use for the quick settings shade. */
     val quickSettingsShadeContentKey: ContentKey by
         hydrator.hydratedStateOf(
             traceName = "quickSettingsShadeContentKey",
-            initialValue = getQuickSettingsShadeContentKey(shadeInteractor.shadeMode.value),
-            source = shadeInteractor.shadeMode.map { getQuickSettingsShadeContentKey(it) },
+            initialValue = getQuickSettingsShadeContentKey(shadeModeInteractor.shadeMode.value),
+            source = shadeModeInteractor.shadeMode.map { getQuickSettingsShadeContentKey(it) },
         )
 
     /** DEBUG: whether the placeholder should be made slightly visible for positional debugging. */
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 b6d89ec..1abf8ab 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
@@ -76,10 +76,12 @@
 import com.android.systemui.shade.LargeScreenHeaderHelper
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode.Dual
 import com.android.systemui.shade.shared.model.ShadeMode.Single
 import com.android.systemui.shade.shared.model.ShadeMode.Split
 import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
 import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
 import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
@@ -90,6 +92,7 @@
 import dagger.Lazy
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.currentCoroutineContext
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
@@ -110,6 +113,7 @@
 import kotlinx.coroutines.isActive
 
 /** View-model for the shared notification container, used by both the shade and keyguard spaces */
+@OptIn(ExperimentalCoroutinesApi::class)
 @SysUISingleton
 class SharedNotificationContainerViewModel
 @Inject
@@ -122,7 +126,8 @@
     private val keyguardInteractor: KeyguardInteractor,
     private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
     private val shadeInteractor: ShadeInteractor,
-    private val notificationStackAppearanceInteractor: NotificationStackAppearanceInteractor,
+    shadeModeInteractor: ShadeModeInteractor,
+    notificationStackAppearanceInteractor: NotificationStackAppearanceInteractor,
     private val alternateBouncerToGoneTransitionViewModel:
         AlternateBouncerToGoneTransitionViewModel,
     private val alternateBouncerToPrimaryBouncerTransitionViewModel:
@@ -232,7 +237,7 @@
         if (SceneContainerFlag.isEnabled) {
                 combine(
                     shadeInteractor.isShadeLayoutWide,
-                    shadeInteractor.shadeMode,
+                    shadeModeInteractor.shadeMode,
                     configurationInteractor.onAnyConfigurationChange,
                 ) { isShadeLayoutWide, shadeMode, _ ->
                     with(context.resources) {
@@ -263,8 +268,7 @@
                             horizontalPosition = horizontalPosition,
                             marginStart = if (shadeMode is Split) 0 else marginHorizontal,
                             marginEnd = marginHorizontal,
-                            marginBottom =
-                                getDimensionPixelSize(R.dimen.notification_panel_margin_bottom),
+                            marginBottom = NotificationStackScrollLayout.getBottomMargin(context),
                             // y position of the NSSL in the window needs to be 0 under scene
                             // container
                             marginTop = 0,
@@ -477,7 +481,7 @@
      */
     private val alphaForShadeAndQsExpansion: Flow<Float> =
         if (SceneContainerFlag.isEnabled) {
-                shadeInteractor.shadeMode.flatMapLatest { shadeMode ->
+                shadeModeInteractor.shadeMode.flatMapLatest { shadeMode ->
                     when (shadeMode) {
                         Single ->
                             combineTransform(
@@ -539,7 +543,7 @@
 
     private fun bouncerToGoneNotificationAlpha(viewState: ViewStateAccessor): Flow<Float> =
         merge(
-                primaryBouncerToGoneTransitionViewModel.notificationAlpha,
+                primaryBouncerToGoneTransitionViewModel.notificationAlpha(viewState),
                 alternateBouncerToGoneTransitionViewModel.notificationAlpha(viewState),
             )
             .sample(communalSceneInteractor.isCommunalVisible) { alpha, isCommunalVisible ->
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 5a63c0c..bd1d7f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
@@ -30,6 +30,7 @@
 import com.android.systemui.util.concurrency.DelayableExecutor
 import dagger.Lazy
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
 
 /** Handles start activity logic in SystemUI. */
 @SysUISingleton
@@ -52,9 +53,10 @@
     override fun registerTransition(
         cookie: ActivityTransitionAnimator.TransitionCookie,
         controllerFactory: ActivityTransitionAnimator.ControllerFactory,
+        scope: CoroutineScope,
     ) {
         if (!TransitionAnimator.longLivedReturnAnimationsEnabled()) return
-        activityStarterInternal.registerTransition(cookie, controllerFactory)
+        activityStarterInternal.registerTransition(cookie, controllerFactory, scope)
     }
 
     override fun unregisterTransition(cookie: ActivityTransitionAnimator.TransitionCookie) {
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 5e427fb..015ec30 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt
@@ -25,15 +25,17 @@
 import com.android.systemui.ActivityIntentHelper
 import com.android.systemui.animation.ActivityTransitionAnimator
 import com.android.systemui.plugins.ActivityStarter
+import kotlinx.coroutines.CoroutineScope
 
 interface ActivityStarterInternal {
     /**
      * Registers the given [controllerFactory] for launching and closing transitions matching the
-     * [cookie] and the [ComponentName] that it contains.
+     * [cookie] and the [ComponentName] that it contains, within the given [scope].
      */
     fun registerTransition(
         cookie: ActivityTransitionAnimator.TransitionCookie,
         controllerFactory: ActivityTransitionAnimator.ControllerFactory,
+        scope: CoroutineScope,
     )
 
     /**
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 7289c2e..6e82d7f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
@@ -66,6 +66,7 @@
 import dagger.Lazy
 import java.util.Optional
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
 
 /**
  * Encapsulates the activity logic for activity starter when the SceneContainerFlag is enabled.
@@ -105,6 +106,7 @@
     override fun registerTransition(
         cookie: ActivityTransitionAnimator.TransitionCookie,
         controllerFactory: ActivityTransitionAnimator.ControllerFactory,
+        scope: CoroutineScope,
     ) {
         check(TransitionAnimator.longLivedReturnAnimationsEnabled())
 
@@ -116,7 +118,7 @@
                     controllerFactory.launchCujType,
                     controllerFactory.returnCujType,
                 ) {
-                override fun createController(
+                override suspend fun createController(
                     forLaunch: Boolean
                 ): ActivityTransitionAnimator.Controller {
                     val baseController = controllerFactory.createController(forLaunch)
@@ -132,7 +134,7 @@
                 }
             }
 
-        activityTransitionAnimator.register(cookie, factory)
+        activityTransitionAnimator.register(cookie, factory, scope)
     }
 
     override fun unregisterTransition(cookie: ActivityTransitionAnimator.TransitionCookie) {
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 09531c3..01f2e9b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -230,7 +230,11 @@
             mDozingRequested = true;
             updateDozing();
             mDozeLog.traceDozing(mStatusBarStateController.isDozing());
-            mCentralSurfaces.updateIsKeyguard();
+            // This is initialized in a CoreStartable, but binder calls from DreamManagerService can
+            // arrive earlier
+            if (mCentralSurfaces != null) {
+                mCentralSurfaces.updateIsKeyguard();
+            }
         }
     }
 
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 d7a29c3..76f67dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
@@ -64,6 +64,7 @@
 import dagger.Lazy
 import java.util.Optional
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
 
 /** Encapsulates the activity logic for activity starter. */
 @SysUISingleton
@@ -102,6 +103,7 @@
     override fun registerTransition(
         cookie: ActivityTransitionAnimator.TransitionCookie,
         controllerFactory: ActivityTransitionAnimator.ControllerFactory,
+        scope: CoroutineScope,
     ) {
         check(TransitionAnimator.longLivedReturnAnimationsEnabled())
 
@@ -113,7 +115,7 @@
                     controllerFactory.launchCujType,
                     controllerFactory.returnCujType,
                 ) {
-                override fun createController(
+                override suspend fun createController(
                     forLaunch: Boolean
                 ): ActivityTransitionAnimator.Controller {
                     val baseController = controllerFactory.createController(forLaunch)
@@ -129,7 +131,7 @@
                 }
             }
 
-        activityTransitionAnimator.register(cookie, factory)
+        activityTransitionAnimator.register(cookie, factory, scope)
     }
 
     override fun unregisterTransition(cookie: ActivityTransitionAnimator.TransitionCookie) {
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 d5f456f..4c35ea1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -74,7 +74,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.domain.interactor.ShadeModeInteractor;
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
 import com.android.systemui.statusbar.notification.stack.ViewState;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -218,6 +218,7 @@
     private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
     private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private final KeyguardInteractor mKeyguardInteractor;
+    private final ShadeModeInteractor mShadeModeInteractor;
 
     private GradientColors mColors;
     private boolean mNeedsDrawableColorUpdate;
@@ -338,6 +339,7 @@
             AlternateBouncerToGoneTransitionViewModel alternateBouncerToGoneTransitionViewModel,
             KeyguardTransitionInteractor keyguardTransitionInteractor,
             KeyguardInteractor keyguardInteractor,
+            ShadeModeInteractor shadeModeInteractor,
             @Main CoroutineDispatcher mainDispatcher,
             LargeScreenShadeInterpolator largeScreenShadeInterpolator,
             BlurConfig blurConfig) {
@@ -387,6 +389,7 @@
         mAlternateBouncerToGoneTransitionViewModel = alternateBouncerToGoneTransitionViewModel;
         mKeyguardTransitionInteractor = keyguardTransitionInteractor;
         mKeyguardInteractor = keyguardInteractor;
+        mShadeModeInteractor = shadeModeInteractor;
         mMainDispatcher = mainDispatcher;
     }
 
@@ -428,6 +431,10 @@
         mViewsAttached = true;
     }
 
+    private boolean isDualShade() {
+        return SceneContainerFlag.isEnabled() && mShadeModeInteractor.isDualShade();
+    }
+
     private void hydrateStateInternally(ScrimView behindScrim) {
         if (SceneContainerFlag.isEnabled()) {
             return;
@@ -956,7 +963,7 @@
             if (!mScreenOffAnimationController.shouldExpandNotifications()
                     && !mAnimatingPanelExpansionOnUnlock
                     && !occluding) {
-                if (mTransparentScrimBackground || DualShade.isEnabled()) {
+                if (mTransparentScrimBackground || isDualShade()) {
                     mBehindAlpha = 0;
                     mNotificationsAlpha = 0;
                 } else if (mClipsQsScrim) {
@@ -1015,7 +1022,7 @@
                 behindAlpha = 0f;
             }
             mInFrontAlpha = mState.getFrontAlpha();
-            if (DualShade.isEnabled() && mState == ScrimState.SHADE_LOCKED) {
+            if (isDualShade() && mState == ScrimState.SHADE_LOCKED) {
                 mBehindAlpha = 0;
                 mNotificationsTint = Color.TRANSPARENT;
                 mNotificationsAlpha = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index a29934fa..949cb0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -160,6 +160,7 @@
                 notificationIconView = currentInfo.notificationIconView,
                 intent = currentInfo.intent,
                 notificationKey = currentInfo.key,
+                appName = currentInfo.appName,
                 promotedContent = currentInfo.promotedContent,
             )
         } else {
@@ -217,6 +218,7 @@
                     notifModel.statusBarChipIconView,
                     notifModel.contentIntent,
                     notifModel.uid,
+                    notifModel.appName,
                     notifModel.promotedContent,
                     isOngoing = true,
                     statusBarSwipedAway = callNotificationInfo?.statusBarSwipedAway ?: false,
@@ -337,6 +339,7 @@
         val notificationIconView: StatusBarIconView?,
         val intent: PendingIntent?,
         val uid: Int,
+        val appName: String,
         /**
          * If the call notification also meets promoted notification criteria, this field is filled
          * in with the content related to promotion. Otherwise null.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt
index ba7628f..2fd7d82 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt
@@ -163,6 +163,7 @@
                     notificationIconView = model.statusBarChipIconView,
                     intent = model.contentIntent,
                     notificationKey = model.key,
+                    appName = model.appName,
                     promotedContent = model.promotedContent,
                 )
             }
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 7d00e9d..6507b72 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
@@ -42,6 +42,7 @@
      * @property notificationIconView the [android.app.Notification.getSmallIcon] that's set on the
      *   call notification. We may use this icon in the chip instead of the default phone icon.
      * @property intent the intent associated with the call notification.
+     * @property appName the user-readable name of the app that posted the call notification.
      * @property promotedContent if the call notification also meets promoted notification criteria,
      *   this field is filled in with the content related to promotion. Otherwise null.
      */
@@ -50,6 +51,7 @@
         val notificationIconView: StatusBarIconView?,
         val intent: PendingIntent?,
         val notificationKey: String,
+        val appName: String,
         val promotedContent: PromotedNotificationContentModel?,
     ) : OngoingCallModel
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt
index bd69060..acce642 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt
@@ -67,7 +67,7 @@
         viewModel: HomeStatusBarViewModel,
         systemEventChipAnimateIn: ((View) -> Unit)?,
         systemEventChipAnimateOut: ((View) -> Unit)?,
-        listener: StatusBarVisibilityChangeListener,
+        listener: StatusBarVisibilityChangeListener?,
     )
 }
 
@@ -83,8 +83,22 @@
         viewModel: HomeStatusBarViewModel,
         systemEventChipAnimateIn: ((View) -> Unit)?,
         systemEventChipAnimateOut: ((View) -> Unit)?,
-        listener: StatusBarVisibilityChangeListener,
+        listener: StatusBarVisibilityChangeListener?,
     ) {
+        // Set some top-level views to gone before we get started
+        val primaryChipView: View = view.requireViewById(R.id.ongoing_activity_chip_primary)
+        val systemInfoView = view.requireViewById<View>(R.id.status_bar_end_side_content)
+        val clockView = view.requireViewById<View>(R.id.clock)
+        val notificationIconsArea = view.requireViewById<View>(R.id.notificationIcons)
+
+        // CollapsedStatusBarFragment doesn't need this
+        if (StatusBarRootModernization.isEnabled) {
+            primaryChipView.isVisible = false
+            systemInfoView.isVisible = false
+            clockView.isVisible = false
+            notificationIconsArea.isVisible = false
+        }
+
         view.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.CREATED) {
                 val iconViewStore =
@@ -95,15 +109,19 @@
                     } else {
                         null
                     }
-                launch {
-                    viewModel.isTransitioningFromLockscreenToOccluded.collect {
-                        listener.onStatusBarVisibilityMaybeChanged()
+                listener?.let { listener ->
+                    launch {
+                        viewModel.isTransitioningFromLockscreenToOccluded.collect {
+                            listener.onStatusBarVisibilityMaybeChanged()
+                        }
                     }
                 }
 
-                launch {
-                    viewModel.transitionFromLockscreenToDreamStartedEvent.collect {
-                        listener.onTransitionFromLockscreenToDreamStarted()
+                listener?.let { listener ->
+                    launch {
+                        viewModel.transitionFromLockscreenToDreamStartedEvent.collect {
+                            listener.onTransitionFromLockscreenToDreamStarted()
+                        }
                     }
                 }
 
@@ -129,9 +147,7 @@
 
                 if (!StatusBarNotifChips.isEnabled && !StatusBarChipsModernization.isEnabled) {
                     val primaryChipViewBinding =
-                        OngoingActivityChipBinder.createBinding(
-                            view.requireViewById(R.id.ongoing_activity_chip_primary)
-                        )
+                        OngoingActivityChipBinder.createBinding(primaryChipView)
                     launch {
                         viewModel.primaryOngoingActivityChip.collect { primaryChipModel ->
                             OngoingActivityChipBinder.bind(
@@ -155,14 +171,14 @@
                             } else {
                                 when (primaryChipModel) {
                                     is OngoingActivityChipModel.Shown ->
-                                        listener.onOngoingActivityStatusChanged(
+                                        listener?.onOngoingActivityStatusChanged(
                                             hasPrimaryOngoingActivity = true,
                                             hasSecondaryOngoingActivity = false,
                                             shouldAnimate = true,
                                         )
 
                                     is OngoingActivityChipModel.Hidden ->
-                                        listener.onOngoingActivityStatusChanged(
+                                        listener?.onOngoingActivityStatusChanged(
                                             hasPrimaryOngoingActivity = false,
                                             hasSecondaryOngoingActivity = false,
                                             shouldAnimate = primaryChipModel.shouldAnimate,
@@ -177,9 +193,7 @@
                     // Create view bindings here so we don't keep re-fetching child views each time
                     // the chip model changes.
                     val primaryChipViewBinding =
-                        OngoingActivityChipBinder.createBinding(
-                            view.requireViewById(R.id.ongoing_activity_chip_primary)
-                        )
+                        OngoingActivityChipBinder.createBinding(primaryChipView)
                     val secondaryChipViewBinding =
                         OngoingActivityChipBinder.createBinding(
                             view.requireViewById(R.id.ongoing_activity_chip_secondary)
@@ -205,7 +219,7 @@
                                     chips.secondary.toVisibilityModel()
                                 )
                             } else {
-                                listener.onOngoingActivityStatusChanged(
+                                listener?.onOngoingActivityStatusChanged(
                                     hasPrimaryOngoingActivity =
                                         chips.primary is OngoingActivityChipModel.Shown,
                                     hasSecondaryOngoingActivity =
@@ -231,15 +245,21 @@
                 }
 
                 if (SceneContainerFlag.isEnabled) {
-                    launch {
-                        viewModel.isHomeStatusBarAllowedByScene.collect {
-                            listener.onIsHomeStatusBarAllowedBySceneChanged(it)
+                    listener?.let { listener ->
+                        launch {
+                            viewModel.isHomeStatusBarAllowedByScene.collect {
+                                listener.onIsHomeStatusBarAllowedBySceneChanged(it)
+                            }
                         }
                     }
                 }
 
                 if (StatusBarRootModernization.isEnabled) {
+                    // TODO(b/393445203): figure out the best story for this stub view. This crashes
+                    // if we move it up to the top of [bind]
                     val operatorNameView = view.requireViewById<View>(R.id.operator_name_frame)
+                    operatorNameView.isVisible = false
+
                     StatusBarOperatorNameViewBinder.bind(
                         operatorNameView,
                         viewModel.operatorNameViewModel,
@@ -251,19 +271,14 @@
                         }
                     }
 
-                    val clockView = view.requireViewById<View>(R.id.clock)
                     launch { viewModel.isClockVisible.collect { clockView.adjustVisibility(it) } }
 
-                    val notificationIconsArea = view.requireViewById<View>(R.id.notificationIcons)
                     launch {
                         viewModel.isNotificationIconContainerVisible.collect {
                             notificationIconsArea.adjustVisibility(it)
                         }
                     }
 
-                    val systemInfoView =
-                        view.requireViewById<View>(R.id.status_bar_end_side_content)
-                    // TODO(b/364360986): Also handle operator name view.
                     launch {
                         viewModel.systemInfoCombinedVis.collect { (baseVis, animState) ->
                             // Broadly speaking, the baseVis controls the view.visibility, and
@@ -352,6 +367,9 @@
 
     // See CollapsedStatusBarFragment#hide.
     private fun View.hide(state: Int = View.INVISIBLE, shouldAnimateChange: Boolean) {
+        if (visibility == View.INVISIBLE || visibility == View.GONE) {
+            return
+        }
         val v = this
         v.animate().cancel()
         if (!shouldAnimateChange) {
@@ -370,6 +388,9 @@
 
     // See CollapsedStatusBarFragment#show.
     private fun View.show(shouldAnimateChange: Boolean) {
+        if (visibility == View.VISIBLE) {
+            return
+        }
         val v = this
         v.animate().cancel()
         v.visibility = View.VISIBLE
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
index 9c1171f..9d72daf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
@@ -25,16 +25,13 @@
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
-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.platform.ComposeView
 import androidx.compose.ui.platform.ViewCompositionStrategy
 import androidx.compose.ui.viewinterop.AndroidView
-import androidx.core.view.isVisible
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.compose.theme.PlatformTheme
 import com.android.keyguard.AlphaOptimizedLinearLayout
 import com.android.systemui.plugins.DarkIconDispatcher
@@ -56,7 +53,6 @@
 import com.android.systemui.statusbar.phone.ui.StatusBarIconController
 import com.android.systemui.statusbar.pipeline.shared.ui.binder.HomeStatusBarIconBlockListBinder
 import com.android.systemui.statusbar.pipeline.shared.ui.binder.HomeStatusBarViewBinder
-import com.android.systemui.statusbar.pipeline.shared.ui.binder.StatusBarVisibilityChangeListener
 import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel
 import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel
 import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel.HomeStatusBarViewModelFactory
@@ -124,25 +120,6 @@
     eventAnimationInteractor: SystemStatusEventAnimationInteractor,
     onViewCreated: (ViewGroup) -> Unit,
 ) {
-    // None of these methods are used when [StatusBarRootModernization] is on.
-    // This can be deleted once the fragment is gone
-    val nopVisibilityChangeListener =
-        object : StatusBarVisibilityChangeListener {
-            override fun onStatusBarVisibilityMaybeChanged() {}
-
-            override fun onTransitionFromLockscreenToDreamStarted() {}
-
-            override fun onOngoingActivityStatusChanged(
-                hasPrimaryOngoingActivity: Boolean,
-                hasSecondaryOngoingActivity: Boolean,
-                shouldAnimate: Boolean,
-            ) {}
-
-            override fun onIsHomeStatusBarAllowedBySceneChanged(
-                isHomeStatusBarAllowedByScene: Boolean
-            ) {}
-        }
-
     Box(Modifier.fillMaxSize()) {
         // TODO(b/364360986): remove this before rolling the flag forward
         if (StatusBarRootModernization.SHOW_DISAMBIGUATION) {
@@ -150,9 +127,6 @@
         }
 
         Row(Modifier.fillMaxSize()) {
-            val scope = rememberCoroutineScope()
-            val visible =
-                statusBarViewModel.shouldHomeStatusBarBeVisible.collectAsStateWithLifecycle(false)
             AndroidView(
                 factory = { context ->
                     val inflater = LayoutInflater.from(context)
@@ -267,32 +241,23 @@
                         endSideContent.addView(composeView, 0)
                     }
 
-                    scope.launch {
-                        notificationIconsBinder.bindWhileAttached(
-                            notificationIconContainer,
-                            context.displayId,
-                        )
-                    }
+                    notificationIconsBinder.bindWhileAttached(
+                        notificationIconContainer,
+                        context.displayId,
+                    )
 
                     // This binder handles everything else
-                    scope.launch {
-                        statusBarViewBinder.bind(
-                            context.displayId,
-                            phoneStatusBarView,
-                            statusBarViewModel,
-                            eventAnimationInteractor::animateStatusBarContentForChipEnter,
-                            eventAnimationInteractor::animateStatusBarContentForChipExit,
-                            nopVisibilityChangeListener,
-                        )
-                    }
+                    statusBarViewBinder.bind(
+                        context.displayId,
+                        phoneStatusBarView,
+                        statusBarViewModel,
+                        eventAnimationInteractor::animateStatusBarContentForChipEnter,
+                        eventAnimationInteractor::animateStatusBarContentForChipExit,
+                        listener = null,
+                    )
                     onViewCreated(phoneStatusBarView)
                     phoneStatusBarView
-                },
-                update = { view ->
-                    // Show or hide the entire status bar. This is important so that we aren't
-                    // visible when first inflated
-                    view.isVisible = visible.value
-                },
+                }
             )
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
index b116b47..67366bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
@@ -19,7 +19,7 @@
 import android.annotation.ColorInt
 import android.graphics.Rect
 import android.view.View
-import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.Edge
@@ -61,6 +61,7 @@
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
@@ -71,6 +72,7 @@
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 
@@ -85,9 +87,6 @@
  * so that it's all in one place and easily testable outside of the fragment.
  */
 interface HomeStatusBarViewModel {
-    /** Should the entire status bar be hidden? */
-    val shouldHomeStatusBarBeVisible: Flow<Boolean>
-
     /**
      * True if the device is currently transitioning from lockscreen to occluded and false
      * otherwise.
@@ -193,7 +192,8 @@
     statusBarPopupChipsViewModel: StatusBarPopupChipsViewModel,
     animations: SystemStatusEventAnimationInteractor,
     statusBarContentInsetsViewModelStore: StatusBarContentInsetsViewModelStore,
-    @Application coroutineScope: CoroutineScope,
+    @Background bgScope: CoroutineScope,
+    @Background bgDispatcher: CoroutineDispatcher,
 ) : HomeStatusBarViewModel {
 
     val tableLogger = tableLoggerFactory.getOrCreate(tableLogBufferName(thisDisplayId), 200)
@@ -207,13 +207,14 @@
                 columnName = COL_LOCK_TO_OCCLUDED,
                 initialValue = false,
             )
-            .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), initialValue = false)
+            .stateIn(bgScope, SharingStarted.WhileSubscribed(), initialValue = false)
 
     override val transitionFromLockscreenToDreamStartedEvent: Flow<Unit> =
         keyguardTransitionInteractor
             .transition(Edge.create(from = LOCKSCREEN, to = DREAMING))
             .filter { it.transitionState == TransitionState.STARTED }
             .map {}
+            .flowOn(bgDispatcher)
 
     override val mediaProjectionStopDialogDueToCallEndedState =
         shareToAppChipViewModel.stopDialogToShow
@@ -242,7 +243,7 @@
                 columnName = COL_ALLOWED_BY_SCENE,
                 initialValue = false,
             )
-            .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), initialValue = false)
+            .stateIn(bgScope, SharingStarted.WhileSubscribed(), initialValue = false)
 
     override val areNotificationsLightsOut: Flow<Boolean> =
         if (NotificationsLiveDataStoreRefactor.isUnexpectedlyInLegacyMode()) {
@@ -261,6 +262,7 @@
                 columnName = COL_NOTIF_LIGHTS_OUT,
                 initialValue = false,
             )
+            .flowOn(bgDispatcher)
 
     override val areaTint: Flow<StatusBarTintColor> =
         darkIconInteractor
@@ -276,6 +278,7 @@
             }
             .conflate()
             .distinctUntilChanged()
+            .flowOn(bgDispatcher)
 
     /**
      * True if the current SysUI state can show the home status bar (aka this status bar), and false
@@ -297,7 +300,7 @@
             isHomeScreenStatusBarAllowedLegacy
         }
 
-    override val shouldHomeStatusBarBeVisible =
+    private val shouldHomeStatusBarBeVisible =
         combine(
                 isHomeStatusBarAllowed,
                 keyguardInteractor.isSecureCameraActive,
@@ -318,6 +321,7 @@
                 columnName = COL_VISIBLE,
                 initialValue = false,
             )
+            .flowOn(bgDispatcher)
 
     private val isAnyChipVisible =
         if (StatusBarNotifChips.isEnabled) {
@@ -361,6 +365,7 @@
                 columnName = COL_SHOW_OPERATOR_NAME,
                 initialValue = false,
             )
+            .flowOn(bgDispatcher)
 
     override val isClockVisible: Flow<VisibilityModel> =
         combine(
@@ -382,6 +387,7 @@
                 columnPrefix = COL_PREFIX_CLOCK,
                 initialValue = VisibilityModel(false.toVisibleOrInvisible(), false),
             )
+            .flowOn(bgDispatcher)
 
     override val isNotificationIconContainerVisible: Flow<VisibilityModel> =
         combine(
@@ -407,6 +413,7 @@
                 columnPrefix = COL_PREFIX_NOTIF_CONTAINER,
                 initialValue = VisibilityModel(false.toVisibleOrInvisible(), false),
             )
+            .flowOn(bgDispatcher)
 
     private val isSystemInfoVisible =
         combine(shouldHomeStatusBarBeVisible, homeStatusBarInteractor.visibilityViaDisableFlags) {
@@ -429,17 +436,17 @@
                     SystemInfoCombinedVisibilityModel(VisibilityModel(View.VISIBLE, false), Idle),
             )
             .stateIn(
-                coroutineScope,
+                bgScope,
                 SharingStarted.WhileSubscribed(),
                 SystemInfoCombinedVisibilityModel(VisibilityModel(View.VISIBLE, false), Idle),
             )
 
     override val iconBlockList: Flow<List<String>> =
-        homeStatusBarIconBlockListInteractor.iconBlockList
+        homeStatusBarIconBlockListInteractor.iconBlockList.flowOn(bgDispatcher)
 
     override val contentArea: Flow<Rect> =
         statusBarContentInsetsViewModelStore.forDisplay(thisDisplayId)?.contentArea
-            ?: flowOf(Rect(0, 0, 0, 0))
+            ?: flowOf(Rect(0, 0, 0, 0)).flowOn(bgDispatcher)
 
     @View.Visibility
     private fun Boolean.toVisibleOrGone(): Int {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt
index 6258a55..34ba767 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt
@@ -22,7 +22,7 @@
 import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
 import com.android.systemui.common.shared.model.Text
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.qs.tileimpl.QSTileImpl.ResourceIcon
 import com.android.systemui.res.R
@@ -61,7 +61,7 @@
     mobileIconsInteractor: MobileIconsInteractor,
     wifiInteractor: WifiInteractor,
     private val context: Context,
-    @Application scope: CoroutineScope,
+    @Background scope: CoroutineScope,
 ) {
     private val internetLabel: String = context.getString(R.string.quick_settings_internet_label)
 
@@ -111,17 +111,16 @@
             if (it == null) {
                 notConnectedFlow
             } else {
-                combine(
-                    it.networkName,
-                    it.signalLevelIcon,
-                    mobileDataContentName,
-                ) { networkNameModel, signalIcon, dataContentDescription ->
+                combine(it.networkName, it.signalLevelIcon, mobileDataContentName) {
+                    networkNameModel,
+                    signalIcon,
+                    dataContentDescription ->
                     when (signalIcon) {
                         is SignalIconModel.Cellular -> {
                             val secondary =
                                 mobileDataContentConcat(
                                     networkNameModel.name,
-                                    dataContentDescription
+                                    dataContentDescription,
                                 )
                             InternetTileModel.Active(
                                 secondaryTitle = secondary,
@@ -147,7 +146,7 @@
 
     private fun mobileDataContentConcat(
         networkName: String?,
-        dataContentDescription: CharSequence?
+        dataContentDescription: CharSequence?,
     ): CharSequence {
         if (dataContentDescription == null) {
             return networkName ?: ""
@@ -160,9 +159,9 @@
             context.getString(
                 R.string.mobile_carrier_text_format,
                 networkName,
-                dataContentDescription
+                dataContentDescription,
             ),
-            0
+            0,
         )
     }
 
@@ -191,10 +190,9 @@
         }
 
     private val notConnectedFlow: StateFlow<InternetTileModel> =
-        combine(
-                wifiInteractor.areNetworksAvailable,
-                airplaneModeRepository.isAirplaneMode,
-            ) { networksAvailable, isAirplaneMode ->
+        combine(wifiInteractor.areNetworksAvailable, airplaneModeRepository.isAirplaneMode) {
+                networksAvailable,
+                isAirplaneMode ->
                 when {
                     isAirplaneMode -> {
                         val secondary = context.getString(R.string.status_bar_airplane)
@@ -213,7 +211,7 @@
                             iconId = R.drawable.ic_qs_no_internet_available,
                             stateDescription = null,
                             contentDescription =
-                                ContentDescription.Loaded("$internetLabel,$secondary")
+                                ContentDescription.Loaded("$internetLabel,$secondary"),
                         )
                     }
                     else -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegate.kt
index db5f130..2fc2286 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegate.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.policy.ui.dialog
 
+import android.annotation.UiThread;
 import android.app.Dialog
 import android.content.Context
 import android.content.Intent
@@ -205,6 +206,7 @@
      * Special dialog to ask the user for the duration of DND. Not to be confused with the modes
      * dialog itself.
      */
+    @UiThread
     fun makeDndDurationDialog(): Dialog {
         val dialog =
             EnableDndDialogFactory(
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java b/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java
index a63660b..5c43926 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/CsdWarningDialog.java
@@ -46,14 +46,13 @@
 import com.android.systemui.util.NotificationChannels;
 import com.android.systemui.util.concurrency.DelayableExecutor;
 
-import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.Optional;
 
 import dagger.assisted.Assisted;
 import dagger.assisted.AssistedFactory;
 import dagger.assisted.AssistedInject;
 
-import java.util.Optional;
-
 /**
  * A class that implements the three Computed Sound Dose-related warnings defined in
  * {@link AudioManager}:
@@ -108,7 +107,7 @@
     private long mShowTime;
 
     @VisibleForTesting public int mCachedMediaStreamVolume;
-    private Optional<ImmutableList<CsdWarningAction>> mActionIntents;
+    private Optional<List<CsdWarningAction>> mActionIntents;
     private final BroadcastDispatcher mBroadcastDispatcher;
 
     /**
@@ -120,7 +119,7 @@
         CsdWarningDialog create(
                 int csdWarning,
                 Runnable onCleanup,
-                Optional<ImmutableList<CsdWarningAction>> actionIntents);
+                Optional<List<CsdWarningAction>> actionIntents);
     }
 
     @AssistedInject
@@ -131,7 +130,7 @@
             NotificationManager notificationManager,
             @Background DelayableExecutor delayableExecutor,
             @Assisted Runnable onCleanup,
-            @Assisted Optional<ImmutableList<CsdWarningAction>> actionIntents,
+            @Assisted Optional<List<CsdWarningAction>> actionIntents,
             BroadcastDispatcher broadcastDispatcher) {
         super(context);
         mCsdWarning = csdWarning;
@@ -350,7 +349,7 @@
         if (Flags.sounddoseCustomization()
                 && mActionIntents.isPresent()
                 && !mActionIntents.get().isEmpty()) {
-            ImmutableList<CsdWarningAction> actionIntentsList = mActionIntents.get();
+            List<CsdWarningAction> actionIntentsList = mActionIntents.get();
             for (CsdWarningAction action : actionIntentsList) {
                 if (action.getLabel() == null || action.getIntent() == null) {
                     Log.w(TAG, "Null action intent received. Skipping addition to notification");
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index a4e46f6..ae063b4 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -31,7 +31,6 @@
 import static android.view.View.LAYOUT_DIRECTION_RTL;
 import static android.view.View.VISIBLE;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_VOLUME_CONTROL;
 import static com.android.internal.jank.InteractionJankMonitor.Configuration.Builder;
 import static com.android.settingslib.flags.Flags.audioSharingDeveloperOption;
@@ -144,18 +143,17 @@
 import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor;
 import com.android.systemui.volume.panel.shared.flag.VolumePanelFlag;
 import com.android.systemui.volume.ui.navigation.VolumeNavigator;
-
 import com.google.android.msdl.domain.MSDLPlayer;
-import com.google.common.collect.ImmutableList;
-
-import dagger.Lazy;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 import java.util.function.Consumer;
 
+import dagger.Lazy;
+
 /**
  * Visual presentation of the volume dialog.
  *
@@ -326,8 +324,8 @@
     private final VolumePanelFlag mVolumePanelFlag;
     private final VolumeDialogInteractor mInteractor;
     // Optional actions for soundDose
-    private Optional<ImmutableList<CsdWarningAction>>
-            mCsdWarningNotificationActions = Optional.of(ImmutableList.of());
+    private Optional<List<CsdWarningAction>>
+            mCsdWarningNotificationActions = Optional.of(Collections.emptyList());
 
     public VolumeDialogImpl(
             Context context,
@@ -2237,7 +2235,7 @@
     }
 
     public void setCsdWarningNotificationActionIntents(
-            ImmutableList<CsdWarningAction> actionIntent) {
+            List<CsdWarningAction> actionIntent) {
         mCsdWarningNotificationActions = Optional.of(actionIntent);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
index 2009143..94964bb 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
@@ -43,13 +43,13 @@
 import com.android.systemui.volume.VolumeUI;
 import com.android.systemui.volume.dialog.VolumeDialogPlugin;
 import com.android.systemui.volume.dialog.dagger.VolumeDialogPluginComponent;
+import com.android.systemui.volume.dialog.dagger.factory.VolumeDialogPluginComponentFactory;
 import com.android.systemui.volume.domain.interactor.VolumeDialogInteractor;
 import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor;
 import com.android.systemui.volume.panel.dagger.VolumePanelComponent;
 import com.android.systemui.volume.panel.dagger.factory.VolumePanelComponentFactory;
 import com.android.systemui.volume.panel.shared.flag.VolumePanelFlag;
 import com.android.systemui.volume.ui.navigation.VolumeNavigator;
-
 import com.google.android.msdl.domain.MSDLPlayer;
 
 import dagger.Binds;
@@ -104,6 +104,10 @@
     @Binds
     VolumePanelComponentFactory bindVolumePanelComponentFactory(VolumePanelComponent.Factory impl);
 
+    @Binds
+    VolumeDialogPluginComponentFactory bindVolumeDialogPluginComponentFactory(
+            VolumeDialogPluginComponent.Factory impl);
+
     /**  */
     @Provides
     static VolumeDialog provideVolumeDialog(
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt
index 5a69be5..938e313 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/VolumeDialogPlugin.kt
@@ -22,9 +22,13 @@
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.plugins.VolumeDialog
+import com.android.systemui.volume.CsdWarningAction
+import com.android.systemui.volume.CsdWarningDialog
 import com.android.systemui.volume.SafetyWarningDialog
 import com.android.systemui.volume.dialog.dagger.VolumeDialogPluginComponent
+import com.android.systemui.volume.dialog.dagger.factory.VolumeDialogPluginComponentFactory
 import com.android.systemui.volume.dialog.ui.viewmodel.VolumeDialogPluginViewModel
+import java.util.Optional
 import javax.inject.Inject
 import kotlin.coroutines.resume
 import kotlinx.coroutines.CoroutineScope
@@ -39,7 +43,8 @@
     @Application private val applicationCoroutineScope: CoroutineScope,
     private val context: Context,
     private val audioManager: AudioManager,
-    private val volumeDialogPluginComponentFactory: VolumeDialogPluginComponent.Factory,
+    private val volumeDialogPluginComponentFactory: VolumeDialogPluginComponentFactory,
+    private val csdWarningDialogFactory: CsdWarningDialog.Factory,
 ) : VolumeDialog {
 
     private var job: Job? = null
@@ -67,6 +72,16 @@
                 }
             }
             .launchIn(this)
+
+        viewModel.csdWarning
+            .mapLatest { csdWarning ->
+                if (csdWarning != null) {
+                    showCsdWarningDialog(csdWarning, viewModel.csdWarningConfigModel.actions) {
+                        viewModel.onCsdWarningDismissed()
+                    }
+                }
+            }
+            .launchIn(this)
     }
 
     override fun destroy() {
@@ -86,4 +101,23 @@
             dialog.show()
             continuation.invokeOnCancellation { dialog.dismiss() }
         }
+
+    private suspend fun showCsdWarningDialog(
+        warning: Int,
+        actions: List<CsdWarningAction>,
+        onDismissed: () -> Unit,
+    ) = suspendCancellableCoroutine { continuation ->
+        val dialog =
+            csdWarningDialogFactory.create(
+                warning,
+                {
+                    onDismissed()
+                    continuation.resume(Unit)
+                },
+                Optional.of(actions),
+            )
+
+        dialog.show()
+        continuation.invokeOnCancellation { dialog.dismiss() }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogPluginComponent.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogPluginComponent.kt
index 4e0098c..f0fe4a3 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogPluginComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/VolumeDialogPluginComponent.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.volume.dialog.dagger
 
+import com.android.systemui.volume.dialog.dagger.factory.VolumeDialogPluginComponentFactory
 import com.android.systemui.volume.dialog.dagger.module.VolumeDialogPluginModule
 import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPlugin
 import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPluginScope
@@ -35,9 +36,9 @@
     fun viewModel(): VolumeDialogPluginViewModel
 
     @Subcomponent.Factory
-    interface Factory {
+    interface Factory : VolumeDialogPluginComponentFactory {
 
-        fun create(
+        override fun create(
             @BindsInstance @VolumeDialogPlugin scope: CoroutineScope
         ): VolumeDialogPluginComponent
     }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/factory/VolumeDialogPluginComponentFactory.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/factory/VolumeDialogPluginComponentFactory.kt
new file mode 100644
index 0000000..8edccd5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/factory/VolumeDialogPluginComponentFactory.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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.dialog.dagger.factory
+
+import com.android.systemui.volume.dialog.dagger.VolumeDialogPluginComponent
+import kotlinx.coroutines.CoroutineScope
+
+/** Common interface for all dagger Subcomponent.Factory providing [VolumeDialogPluginComponent]. */
+interface VolumeDialogPluginComponentFactory {
+
+    fun create(scope: CoroutineScope): VolumeDialogPluginComponent
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogPluginModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogPluginModule.kt
index cd8cdc8..547c51d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogPluginModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/dagger/module/VolumeDialogPluginModule.kt
@@ -17,13 +17,22 @@
 package com.android.systemui.volume.dialog.dagger.module
 
 import com.android.systemui.volume.dialog.dagger.VolumeDialogComponent
+import com.android.systemui.volume.dialog.shared.model.CsdWarningConfigModel
 import com.android.systemui.volume.dialog.utils.VolumeTracer
 import com.android.systemui.volume.dialog.utils.VolumeTracerImpl
 import dagger.Binds
 import dagger.Module
+import dagger.Provides
 
 @Module(subcomponents = [VolumeDialogComponent::class])
 interface VolumeDialogPluginModule {
 
     @Binds fun bindVolumeTracer(volumeTracer: VolumeTracerImpl): VolumeTracer
+
+    companion object {
+
+        @Provides
+        fun provideCsdWarningConfigModel(): CsdWarningConfigModel =
+            CsdWarningConfigModel(emptyList())
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogCsdWarningInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogCsdWarningInteractor.kt
new file mode 100644
index 0000000..ef9def3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogCsdWarningInteractor.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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.dialog.domain.interactor
+
+import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPluginScope
+import com.android.systemui.volume.dialog.shared.model.VolumeDialogCsdWarningModel
+import javax.inject.Inject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@VolumeDialogPluginScope
+class VolumeDialogCsdWarningInteractor
+@Inject
+constructor(private val stateInteractor: VolumeDialogStateInteractor) {
+
+    /** Emits warning when the warning should be visible and null when it shouldn't */
+    val csdWarning: Flow<Int?> =
+        stateInteractor.volumeDialogState
+            .map { it.isShowingCsdWarning }
+            .flatMapLatest { model ->
+                when (model) {
+                    is VolumeDialogCsdWarningModel.Visible ->
+                        flow {
+                            emit(model.warning)
+                            delay(model.duration)
+                            emit(null)
+                        }
+                    is VolumeDialogCsdWarningModel.Invisible -> flowOf(null)
+                }
+            }
+
+    fun onCsdWarningDismissed() {
+        stateInteractor.setCsdWarning(VolumeDialogCsdWarningModel.Invisible)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogStateInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogStateInteractor.kt
index 26d2414..b3c92f8 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogStateInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/domain/interactor/VolumeDialogStateInteractor.kt
@@ -23,10 +23,12 @@
 import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPluginScope
 import com.android.systemui.volume.dialog.data.repository.VolumeDialogStateRepository
 import com.android.systemui.volume.dialog.domain.model.VolumeDialogEventModel
+import com.android.systemui.volume.dialog.shared.model.VolumeDialogCsdWarningModel
 import com.android.systemui.volume.dialog.shared.model.VolumeDialogSafetyWarningModel
 import com.android.systemui.volume.dialog.shared.model.VolumeDialogStateModel
 import com.android.systemui.volume.dialog.shared.model.VolumeDialogStreamModel
 import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.launchIn
@@ -64,6 +66,14 @@
                     is VolumeDialogEventModel.ShowSafetyWarning -> {
                         setSafetyWarning(VolumeDialogSafetyWarningModel.Visible(event.flags))
                     }
+                    is VolumeDialogEventModel.ShowCsdWarning -> {
+                        setCsdWarning(
+                            VolumeDialogCsdWarningModel.Visible(
+                                warning = event.csdWarning,
+                                duration = event.durationMs.milliseconds,
+                            )
+                        )
+                    }
                     is VolumeDialogEventModel.SubscribedToEvents -> {
                         volumeDialogController.getState()
                     }
@@ -81,6 +91,10 @@
         volumeDialogStateRepository.updateState { it.copy(isShowingSafetyWarning = model) }
     }
 
+    fun setCsdWarning(model: VolumeDialogCsdWarningModel) {
+        volumeDialogStateRepository.updateState { it.copy(isShowingCsdWarning = model) }
+    }
+
     /** Returns a copy of [model] filled with the values from [VolumeDialogController.State]. */
     private fun VolumeDialogController.State.copyIntoModel(
         model: VolumeDialogStateModel
diff --git a/packages/CrashRecovery/framework/java/android/service/watchdog/PackageConfig.aidl b/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/CsdWarningConfigModel.kt
similarity index 70%
rename from packages/CrashRecovery/framework/java/android/service/watchdog/PackageConfig.aidl
rename to packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/CsdWarningConfigModel.kt
index 0131586..e6741ba 100644
--- a/packages/CrashRecovery/framework/java/android/service/watchdog/PackageConfig.aidl
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/CsdWarningConfigModel.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,9 +14,8 @@
  * limitations under the License.
  */
 
-package android.service.watchdog;
+package com.android.systemui.volume.dialog.shared.model
 
-/**
- * @hide
- */
-parcelable PackageConfig;
+import com.android.systemui.volume.CsdWarningAction
+
+data class CsdWarningConfigModel(val actions: List<CsdWarningAction>)
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogCsdWarningModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogCsdWarningModel.kt
new file mode 100644
index 0000000..219af71
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogCsdWarningModel.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.volume.dialog.shared.model
+
+import kotlin.time.Duration
+
+/** Models current CSD dialog state. */
+sealed interface VolumeDialogCsdWarningModel {
+
+    /** CSD dialog is visible and has been shown with the [warning] for the [duration]. */
+    data class Visible(val warning: Int, val duration: Duration) : VolumeDialogCsdWarningModel
+
+    /** CSD dialog is invisible. */
+    data object Invisible : VolumeDialogCsdWarningModel
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogStateModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogStateModel.kt
index 838006d..89456fe 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogStateModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/shared/model/VolumeDialogStateModel.kt
@@ -23,6 +23,7 @@
     val shouldShowA11ySlider: Boolean = false,
     val isShowingSafetyWarning: VolumeDialogSafetyWarningModel =
         VolumeDialogSafetyWarningModel.Invisible,
+    val isShowingCsdWarning: VolumeDialogCsdWarningModel = VolumeDialogCsdWarningModel.Invisible,
     val streamModels: Map<Int, VolumeDialogStreamModel> = mapOf(),
     val ringerModeInternal: Int = 0,
     val ringerModeExternal: Int = 0,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt
index e7a2cf4..1765f01 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/viewmodel/VolumeDialogPluginViewModel.kt
@@ -20,9 +20,11 @@
 import com.android.systemui.volume.dialog.VolumeDialog
 import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPlugin
 import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPluginScope
+import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogCsdWarningInteractor
 import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogSafetyWarningInteractor
 import com.android.systemui.volume.dialog.domain.interactor.VolumeDialogVisibilityInteractor
 import com.android.systemui.volume.dialog.shared.VolumeDialogLogger
+import com.android.systemui.volume.dialog.shared.model.CsdWarningConfigModel
 import com.android.systemui.volume.dialog.shared.model.VolumeDialogVisibilityModel
 import javax.inject.Inject
 import javax.inject.Provider
@@ -38,8 +40,10 @@
     @VolumeDialogPlugin private val coroutineScope: CoroutineScope,
     private val dialogVisibilityInteractor: VolumeDialogVisibilityInteractor,
     private val dialogSafetyWarningInteractor: VolumeDialogSafetyWarningInteractor,
+    private val dialogCsdWarningInteractor: VolumeDialogCsdWarningInteractor,
     private val volumeDialogProvider: Provider<VolumeDialog>,
     private val logger: VolumeDialogLogger,
+    val csdWarningConfigModel: CsdWarningConfigModel,
 ) {
 
     fun launchVolumeDialog() {
@@ -61,11 +65,16 @@
     }
 
     val isShowingSafetyWarning: Flow<Boolean> = dialogSafetyWarningInteractor.isShowingSafetyWarning
+    val csdWarning: Flow<Int?> = dialogCsdWarningInteractor.csdWarning
 
     fun onSafetyWarningDismissed() {
         dialogSafetyWarningInteractor.onSafetyWarningDismissed()
     }
 
+    fun onCsdWarningDismissed() {
+        dialogCsdWarningInteractor.onCsdWarningDismissed()
+    }
+
     private fun showDialog() {
         volumeDialogProvider
             .get()
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/MediaOutputAvailabilityCriteria.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/MediaOutputAvailabilityCriteria.kt
deleted file mode 100644
index bee4564..0000000
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/MediaOutputAvailabilityCriteria.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2025 The Android Open Source Project
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF 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.component.mediaoutput.domain
-
-import android.content.Context
-import com.android.settingslib.media.PhoneMediaDevice.isDesktop
-import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope
-import com.android.systemui.volume.panel.domain.ComponentAvailabilityCriteria
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.stateIn
-
-@VolumePanelScope
-class MediaOutputAvailabilityCriteria
-@Inject
-constructor(
-    @Application private val context: Context,
-    @VolumePanelScope private val scope: CoroutineScope,
-) : ComponentAvailabilityCriteria {
-
-    private val availability =
-        flow { emit(!isDesktop(context)) }.stateIn(scope, SharingStarted.WhileSubscribed(), false)
-
-    override fun isAvailable(): Flow<Boolean> = availability
-}
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperRepository.kt b/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperRepository.kt
index 9794c61..79a9630 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/data/repository/WallpaperRepository.kt
@@ -27,12 +27,13 @@
 import androidx.annotation.VisibleForTesting
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.internal.R
-import com.android.systemui.Flags
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.keyguard.data.repository.KeyguardRepository
+import com.android.systemui.res.R as SysUIR
 import com.android.systemui.shared.Flags.ambientAod
+import com.android.systemui.shared.Flags.extendedWallpaperEffects
 import com.android.systemui.user.data.model.SelectedUserModel
 import com.android.systemui.user.data.model.SelectionStatus
 import com.android.systemui.user.data.repository.UserRepository
@@ -66,7 +67,7 @@
     /** Set rootView to get its windowToken afterwards */
     var rootView: View?
 
-    /** when we use magic portrait wallpapers, we should always get its bounds from keyguard */
+    /** some wallpapers require bounds to be sent from keyguard */
     val shouldSendFocalArea: StateFlow<Boolean>
 }
 
@@ -80,7 +81,7 @@
     userRepository: UserRepository,
     keyguardRepository: KeyguardRepository,
     private val wallpaperManager: WallpaperManager,
-    context: Context,
+    private val context: Context,
 ) : WallpaperRepository {
     private val wallpaperChanged: Flow<Unit> =
         broadcastDispatcher
@@ -125,8 +126,8 @@
     override val shouldSendFocalArea =
         wallpaperInfo
             .map {
-                val shouldSendNotificationLayout =
-                    it?.component?.className == MAGIC_PORTRAIT_CLASSNAME
+                val focalAreaTarget = context.resources.getString(SysUIR.string.focal_area_target)
+                val shouldSendNotificationLayout = it?.component?.className == focalAreaTarget
                 if (shouldSendNotificationLayout) {
                     sendLockscreenLayoutJob =
                         scope.launch {
@@ -167,9 +168,8 @@
             }
             .stateIn(
                 scope,
-                // Always be listening for wallpaper changes when magic portrait flag is on
-                if (Flags.magicPortraitWallpapers()) SharingStarted.Eagerly else WhileSubscribed(),
-                initialValue = Flags.magicPortraitWallpapers(),
+                if (extendedWallpaperEffects()) SharingStarted.Eagerly else WhileSubscribed(),
+                initialValue = extendedWallpaperEffects(),
             )
 
     private suspend fun getWallpaper(selectedUser: SelectedUserModel): WallpaperInfo? {
@@ -177,9 +177,4 @@
             wallpaperManager.getWallpaperInfoForUser(selectedUser.userInfo.id)
         }
     }
-
-    companion object {
-        const val MAGIC_PORTRAIT_CLASSNAME =
-            "com.google.android.apps.magicportrait.service.MagicPortraitWallpaperService"
-    }
 }
diff --git a/packages/SystemUI/tests/goldens/brightnessSlider_iconAlphaChanges.json b/packages/SystemUI/tests/goldens/brightnessSlider_iconAlphaChanges.json
new file mode 100644
index 0000000..cefada7
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/brightnessSlider_iconAlphaChanges.json
@@ -0,0 +1,168 @@
+{
+  "frame_ids": [
+    "before",
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352,
+    368,
+    384,
+    400,
+    416,
+    432,
+    448,
+    464,
+    480,
+    496,
+    512,
+    528,
+    544,
+    560,
+    576,
+    592,
+    608,
+    624,
+    640,
+    656,
+    672,
+    688,
+    704,
+    720,
+    736,
+    752,
+    "after"
+  ],
+  "features": [
+    {
+      "name": "activeIconAlpha_activeIconAlpha",
+      "type": "float",
+      "data_points": [
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        0.5782508,
+        0.09543866,
+        8.595586E-4,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0
+      ]
+    },
+    {
+      "name": "inactiveIconAlpha_inactiveIconAlpha",
+      "type": "float",
+      "data_points": [
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0.065971695,
+        0.3946195,
+        0.7348632,
+        0.8979182,
+        0.97246534,
+        0.9986459,
+        1
+      ]
+    }
+  ]
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
index bac2c47..f822ee9 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
@@ -95,7 +95,6 @@
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
-@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
 class ClockEventControllerTest : SysuiTestCase() {
 
     private val kosmos = testKosmos()
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 312d2ff..4110a05 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -18,7 +18,6 @@
 
 import static android.app.StatusBarManager.SESSION_KEYGUARD;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_ANY_BIOMETRIC;
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
@@ -2717,7 +2716,7 @@
                     () -> mAlternateBouncerInteractor,
                     () -> mJavaAdapter,
                     () -> mSceneInteractor,
-                    mCommunalSceneInteractor);
+                    () -> mCommunalSceneInteractor);
             setAlternateBouncerVisibility(false);
             setPrimaryBouncerVisibility(false);
             setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
index ad5f960..a0f5b22 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
@@ -242,8 +242,8 @@
             mWindowMagnificationAnimationController.enableWindowMagnification(targetScale,
                     targetCenterX, targetCenterY, mAnimationCallback2);
             mCurrentScale.set(mController.getScale());
-            mCurrentCenterX.set(mController.getCenterX());
-            mCurrentCenterY.set(mController.getCenterY());
+            mCurrentCenterX.set(mController.getMagnificationFrameCenterX());
+            mCurrentCenterY.set(mController.getMagnificationFrameCenterY());
             advanceTimeBy(mWaitAnimationDuration);
         });
 
@@ -297,8 +297,8 @@
             mWindowMagnificationAnimationController.enableWindowMagnification(targetScale,
                     targetCenterX, targetCenterY, mAnimationCallback);
             mCurrentScale.set(mController.getScale());
-            mCurrentCenterX.set(mController.getCenterX());
-            mCurrentCenterY.set(mController.getCenterY());
+            mCurrentCenterX.set(mController.getMagnificationFrameCenterX());
+            mCurrentCenterY.set(mController.getMagnificationFrameCenterY());
             advanceTimeBy(mWaitAnimationDuration);
         });
 
@@ -339,8 +339,8 @@
             mWindowMagnificationAnimationController.enableWindowMagnification(targetScale,
                     targetCenterX, targetCenterY, mAnimationCallback);
             mCurrentScale.set(mController.getScale());
-            mCurrentCenterX.set(mController.getCenterX());
-            mCurrentCenterY.set(mController.getCenterY());
+            mCurrentCenterX.set(mController.getMagnificationFrameCenterX());
+            mCurrentCenterY.set(mController.getMagnificationFrameCenterY());
             advanceTimeBy(mWaitAnimationDuration);
         });
 
@@ -375,8 +375,8 @@
             mWindowMagnificationAnimationController.enableWindowMagnification(targetScale,
                     targetCenterX, targetCenterY, mAnimationCallback);
             mCurrentScale.set(mController.getScale());
-            mCurrentCenterX.set(mController.getCenterX());
-            mCurrentCenterY.set(mController.getCenterY());
+            mCurrentCenterX.set(mController.getMagnificationFrameCenterX());
+            mCurrentCenterY.set(mController.getMagnificationFrameCenterY());
             advanceTimeBy(mWaitAnimationDuration);
         });
 
@@ -463,8 +463,8 @@
             mWindowMagnificationAnimationController.enableWindowMagnification(targetScale,
                     targetCenterX, targetCenterY, mAnimationCallback2);
             mCurrentScale.set(mController.getScale());
-            mCurrentCenterX.set(mController.getCenterX());
-            mCurrentCenterY.set(mController.getCenterY());
+            mCurrentCenterX.set(mController.getMagnificationFrameCenterX());
+            mCurrentCenterY.set(mController.getMagnificationFrameCenterY());
         });
 
         // Current spec shouldn't match given spec.
@@ -548,8 +548,8 @@
             mWindowMagnificationAnimationController.enableWindowMagnification(targetScale,
                     targetCenterX, targetCenterY, mAnimationCallback2);
             mCurrentScale.set(mController.getScale());
-            mCurrentCenterX.set(mController.getCenterX());
-            mCurrentCenterY.set(mController.getCenterY());
+            mCurrentCenterX.set(mController.getMagnificationFrameCenterX());
+            mCurrentCenterY.set(mController.getMagnificationFrameCenterY());
             advanceTimeBy(mWaitAnimationDuration);
         });
 
@@ -777,8 +777,8 @@
             mWindowMagnificationAnimationController.deleteWindowMagnification(
                     mAnimationCallback2);
             mCurrentScale.set(mController.getScale());
-            mCurrentCenterX.set(mController.getCenterX());
-            mCurrentCenterY.set(mController.getCenterY());
+            mCurrentCenterX.set(mController.getMagnificationFrameCenterX());
+            mCurrentCenterY.set(mController.getMagnificationFrameCenterY());
             // ValueAnimator.reverse() could not work correctly with the AnimatorTestRule since it
             // is using SystemClock in reverse() (b/305731398). Therefore, we call end() on the
             // animator directly to verify the result of animation is correct instead of querying
@@ -940,8 +940,8 @@
     private void verifyFinalSpec(float expectedScale, float expectedCenterX,
             float expectedCenterY) {
         assertEquals(expectedScale, mController.getScale(), 0f);
-        assertEquals(expectedCenterX, mController.getCenterX(), 0f);
-        assertEquals(expectedCenterY, mController.getCenterY(), 0f);
+        assertEquals(expectedCenterX, mController.getMagnificationFrameCenterX(), 0f);
+        assertEquals(expectedCenterY, mController.getMagnificationFrameCenterY(), 0f);
     }
 
     private void enableWindowMagnificationWithoutAnimation() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index 8552e48..7cf9327 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -63,6 +63,8 @@
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.provider.Settings;
 import android.testing.TestableLooper;
 import android.testing.TestableResources;
@@ -88,6 +90,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
 
+import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.AnimatorTestRule;
 import com.android.systemui.kosmos.KosmosJavaAdapter;
@@ -128,6 +131,7 @@
     public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule(/* test= */ null);
 
     private static final int LAYOUT_CHANGE_TIMEOUT_MS = 5000;
+    private static final int INSET_BOTTOM = 10;
     @Mock
     private MirrorWindowControl mMirrorWindowControl;
     @Mock
@@ -329,9 +333,9 @@
         final ArgumentCaptor<Rect> sourceBoundsCaptor = ArgumentCaptor.forClass(Rect.class);
         verify(mWindowMagnifierCallback, atLeast(2)).onSourceBoundsChanged(
                 (eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
-        assertThat(mWindowMagnificationController.getCenterX())
+        assertThat(mWindowMagnificationController.getMagnificationFrameCenterX())
                 .isEqualTo(sourceBoundsCaptor.getValue().exactCenterX());
-        assertThat(mWindowMagnificationController.getCenterY())
+        assertThat(mWindowMagnificationController.getMagnificationFrameCenterY())
                 .isEqualTo(sourceBoundsCaptor.getValue().exactCenterY());
     }
 
@@ -382,6 +386,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_UPDATE_WINDOW_MAGNIFIER_BOTTOM_BOUNDARY)
     public void deleteWindowMagnification_enableAtTheBottom_overlapFlagIsFalse() {
         final WindowManager wm = mContext.getSystemService(WindowManager.class);
         final Rect bounds = wm.getCurrentWindowMetrics().getBounds();
@@ -457,12 +462,14 @@
         verify(mAnimationCallback, never()).onResult(eq(false));
         verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
                 .onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
-        assertThat(mWindowMagnificationController.getCenterX())
+        assertThat(mWindowMagnificationController.getMagnificationFrameCenterX())
                 .isEqualTo(sourceBoundsCaptor.getValue().exactCenterX());
-        assertThat(mWindowMagnificationController.getCenterY())
+        assertThat(mWindowMagnificationController.getMagnificationFrameCenterY())
                 .isEqualTo(sourceBoundsCaptor.getValue().exactCenterY());
-        assertThat(mWindowMagnificationController.getCenterX()).isEqualTo(targetCenterX);
-        assertThat(mWindowMagnificationController.getCenterY()).isEqualTo(targetCenterY);
+        assertThat(mWindowMagnificationController.getMagnificationFrameCenterX())
+                .isEqualTo(targetCenterX);
+        assertThat(mWindowMagnificationController.getMagnificationFrameCenterY())
+                .isEqualTo(targetCenterY);
     }
 
     @Test
@@ -498,12 +505,14 @@
         verify(mAnimationCallback, times(3)).onResult(eq(false));
         verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
                 .onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
-        assertThat(mWindowMagnificationController.getCenterX())
+        assertThat(mWindowMagnificationController.getMagnificationFrameCenterX())
                 .isEqualTo(sourceBoundsCaptor.getValue().exactCenterX());
-        assertThat(mWindowMagnificationController.getCenterY())
+        assertThat(mWindowMagnificationController.getMagnificationFrameCenterY())
                 .isEqualTo(sourceBoundsCaptor.getValue().exactCenterY());
-        assertThat(mWindowMagnificationController.getCenterX()).isEqualTo(centerX + 40);
-        assertThat(mWindowMagnificationController.getCenterY()).isEqualTo(centerY + 40);
+        assertThat(mWindowMagnificationController.getMagnificationFrameCenterX())
+                .isEqualTo(centerX + 40);
+        assertThat(mWindowMagnificationController.getMagnificationFrameCenterY())
+                .isEqualTo(centerY + 40);
     }
 
     @Test
@@ -545,8 +554,8 @@
             mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
                     magnifiedCenter.x, magnifiedCenter.y);
             // Get the center again in case the center we set is out of screen.
-            magnifiedCenter.set(mWindowMagnificationController.getCenterX(),
-                    mWindowMagnificationController.getCenterY());
+            magnifiedCenter.set(mWindowMagnificationController.getMagnificationFrameCenterX(),
+                    mWindowMagnificationController.getMagnificationFrameCenterY());
         });
         // Rotate the window clockwise 90 degree.
         windowBounds.set(windowBounds.top, windowBounds.left, windowBounds.bottom,
@@ -559,8 +568,9 @@
         assertThat(mWindowMagnificationController.mRotation).isEqualTo(newRotation);
         final PointF expectedCenter = new PointF(magnifiedCenter.y,
                 displayWidth - magnifiedCenter.x);
-        final PointF actualCenter = new PointF(mWindowMagnificationController.getCenterX(),
-                mWindowMagnificationController.getCenterY());
+        final PointF actualCenter =
+                new PointF(mWindowMagnificationController.getMagnificationFrameCenterX(),
+                        mWindowMagnificationController.getMagnificationFrameCenterY());
         assertThat(actualCenter).isEqualTo(expectedCenter);
     }
 
@@ -603,10 +613,10 @@
         });
 
         // The ratio of center to window size should be the same.
-        assertThat(mWindowMagnificationController.getCenterX() / testWindowBounds.width())
-                .isEqualTo(expectedRatio);
-        assertThat(mWindowMagnificationController.getCenterY() / testWindowBounds.height())
-                .isEqualTo(expectedRatio);
+        assertThat(mWindowMagnificationController.getMagnificationFrameCenterX()
+                / testWindowBounds.width()).isEqualTo(expectedRatio);
+        assertThat(mWindowMagnificationController.getMagnificationFrameCenterY()
+                / testWindowBounds.height()).isEqualTo(expectedRatio);
     }
 
     @Test
@@ -1175,6 +1185,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_UPDATE_WINDOW_MAGNIFIER_BOTTOM_BOUNDARY)
     public void moveWindowMagnificationToTheBottom_enabledWithGestureInset_overlapFlagIsTrue() {
         final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
         setSystemGestureInsets();
@@ -1191,6 +1202,30 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_UPDATE_WINDOW_MAGNIFIER_BOTTOM_BOUNDARY)
+    public void moveWindowMagnificationToTheBottom_stopsAtSystemGestureTop() {
+        final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
+        setSystemGestureInsets();
+        mInstrumentation.runOnMainSync(() -> {
+            mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
+                    Float.NaN);
+        });
+
+        ViewGroup.LayoutParams params = mSurfaceControlViewHost.getView().getLayoutParams();
+        final int mOuterBorderSize = mResources.getDimensionPixelSize(
+                R.dimen.magnification_outer_border_margin);
+
+        final float expectedY =
+                (float) (bounds.bottom - INSET_BOTTOM - params.height + mOuterBorderSize);
+
+        mInstrumentation.runOnMainSync(() -> {
+            mWindowMagnificationController.moveWindowMagnifier(0, bounds.height());
+        });
+
+        assertThat(mWindowMagnificationController.getMagnifierWindowY()).isEqualTo(expectedY);
+    }
+
+    @Test
     public void moveWindowMagnificationToRightEdge_dragHandleMovesToLeftAndUpdatesTapExcludeRegion()
             throws RemoteException {
         final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
@@ -1445,8 +1480,10 @@
         mInstrumentation.runOnMainSync(() -> {
             mWindowMagnificationController.setWindowSizeAndCenter(minimumWindowSize,
                     minimumWindowSize, bounds.right, bounds.bottom);
-            magnificationCenterX.set((int) mWindowMagnificationController.getCenterX());
-            magnificationCenterY.set((int) mWindowMagnificationController.getCenterY());
+            magnificationCenterX.set(
+                    (int) mWindowMagnificationController.getMagnificationFrameCenterX());
+            magnificationCenterY.set(
+                    (int) mWindowMagnificationController.getMagnificationFrameCenterY());
         });
 
         assertThat(magnificationCenterX.get()).isLessThan(bounds.right);
@@ -1501,7 +1538,7 @@
 
     private void setSystemGestureInsets() {
         final WindowInsets testInsets = new WindowInsets.Builder()
-                .setInsets(systemGestures(), Insets.of(0, 0, 0, 10))
+                .setInsets(systemGestures(), Insets.of(0, 0, 0, INSET_BOTTOM))
                 .build();
         mWindowManager.setWindowInsets(testInsets);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/data/repository/AccessibilityQsShortcutsRepositoryImplForDeviceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/accessibility/data/repository/AccessibilityQsShortcutsRepositoryImplForDeviceTest.kt
index 4e0ebae..c6ede0c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/data/repository/AccessibilityQsShortcutsRepositoryImplForDeviceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/data/repository/AccessibilityQsShortcutsRepositoryImplForDeviceTest.kt
@@ -36,7 +36,6 @@
 import com.android.systemui.util.settings.FakeSettings
 import com.android.systemui.utils.FieldSetter
 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
@@ -55,7 +54,6 @@
  * can't mock the AccessibilityShortcutInfo for test. MultiValentTest doesn't compile when using
  * newly introduced methods and constants.
  */
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AccessibilityQsShortcutsRepositoryImplForDeviceTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt
index fd751d9..845be02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt
@@ -27,7 +27,10 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.shared.Flags
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
 import com.android.wm.shell.shared.ShellTransitions
 import com.google.common.truth.Truth.assertThat
@@ -38,6 +41,9 @@
 import junit.framework.AssertionFailedError
 import kotlin.concurrent.thread
 import kotlin.test.assertEquals
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.advanceUntilIdle
+import kotlinx.coroutines.test.runTest
 import org.junit.After
 import org.junit.Assert.assertThrows
 import org.junit.Before
@@ -54,10 +60,12 @@
 import org.mockito.Spy
 import org.mockito.junit.MockitoJUnit
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper
 class ActivityTransitionAnimatorTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
     private val transitionContainer = LinearLayout(mContext)
     private val mainExecutor = context.mainExecutor
     private val testTransitionAnimator = fakeTransitionAnimator(mainExecutor)
@@ -67,12 +75,12 @@
     @Spy private val controller = TestTransitionAnimatorController(transitionContainer)
     @Mock lateinit var iCallback: IRemoteAnimationFinishedCallback
 
-    private lateinit var activityTransitionAnimator: ActivityTransitionAnimator
+    private lateinit var underTest: ActivityTransitionAnimator
     @get:Rule val rule = MockitoJUnit.rule()
 
     @Before
     fun setup() {
-        activityTransitionAnimator =
+        underTest =
             ActivityTransitionAnimator(
                 mainExecutor,
                 ActivityTransitionAnimator.TransitionRegister.fromShellTransitions(
@@ -82,17 +90,17 @@
                 testTransitionAnimator,
                 disableWmTimeout = true,
             )
-        activityTransitionAnimator.callback = callback
-        activityTransitionAnimator.addListener(listener)
+        underTest.callback = callback
+        underTest.addListener(listener)
     }
 
     @After
     fun tearDown() {
-        activityTransitionAnimator.removeListener(listener)
+        underTest.removeListener(listener)
     }
 
     private fun startIntentWithAnimation(
-        animator: ActivityTransitionAnimator = this.activityTransitionAnimator,
+        animator: ActivityTransitionAnimator = underTest,
         controller: ActivityTransitionAnimator.Controller? = this.controller,
         animate: Boolean = true,
         intentStarter: (RemoteAnimationAdapter?) -> Int,
@@ -157,7 +165,7 @@
         val willAnimateCaptor = ArgumentCaptor.forClass(Boolean::class.java)
         var animationAdapter: RemoteAnimationAdapter? = null
 
-        startIntentWithAnimation(activityTransitionAnimator) { adapter ->
+        startIntentWithAnimation(underTest) { adapter ->
             animationAdapter = adapter
             ActivityManager.START_DELIVERED_TO_TOP
         }
@@ -185,9 +193,7 @@
     fun registersReturnIffCookieIsPresent() {
         `when`(callback.isOnKeyguard()).thenReturn(false)
 
-        startIntentWithAnimation(activityTransitionAnimator, controller) { _ ->
-            ActivityManager.START_DELIVERED_TO_TOP
-        }
+        startIntentWithAnimation(underTest, controller) { ActivityManager.START_DELIVERED_TO_TOP }
 
         waitForIdleSync()
         assertTrue(testShellTransitions.remotes.isEmpty())
@@ -199,9 +205,7 @@
                     get() = ActivityTransitionAnimator.TransitionCookie("testCookie")
             }
 
-        startIntentWithAnimation(activityTransitionAnimator, controller) { _ ->
-            ActivityManager.START_DELIVERED_TO_TOP
-        }
+        startIntentWithAnimation(underTest, controller) { ActivityManager.START_DELIVERED_TO_TOP }
 
         waitForIdleSync()
         assertEquals(1, testShellTransitions.remotes.size)
@@ -214,13 +218,15 @@
     )
     @Test
     fun registersLongLivedTransition() {
-        var factory = controllerFactory()
-        activityTransitionAnimator.register(factory.cookie, factory)
-        assertEquals(2, testShellTransitions.remotes.size)
+        kosmos.runTest {
+            var factory = controllerFactory()
+            underTest.register(factory.cookie, factory, testScope)
+            assertEquals(2, testShellTransitions.remotes.size)
 
-        factory = controllerFactory()
-        activityTransitionAnimator.register(factory.cookie, factory)
-        assertEquals(4, testShellTransitions.remotes.size)
+            factory = controllerFactory()
+            underTest.register(factory.cookie, factory, testScope)
+            assertEquals(4, testShellTransitions.remotes.size)
+        }
     }
 
     @EnableFlags(
@@ -229,49 +235,55 @@
     )
     @Test
     fun registersLongLivedTransitionOverridingPreviousRegistration() {
-        val cookie = ActivityTransitionAnimator.TransitionCookie("test_cookie")
-        var factory = controllerFactory(cookie)
-        activityTransitionAnimator.register(cookie, factory)
-        val transitions = testShellTransitions.remotes.values.toList()
+        kosmos.runTest {
+            val cookie = ActivityTransitionAnimator.TransitionCookie("test_cookie")
+            var factory = controllerFactory(cookie)
+            underTest.register(cookie, factory, testScope)
+            val transitions = testShellTransitions.remotes.values.toList()
 
-        factory = controllerFactory(cookie)
-        activityTransitionAnimator.register(cookie, factory)
-        assertEquals(2, testShellTransitions.remotes.size)
-        for (transition in transitions) {
-            assertThat(testShellTransitions.remotes.values).doesNotContain(transition)
+            factory = controllerFactory(cookie)
+            underTest.register(cookie, factory, testScope)
+            assertEquals(2, testShellTransitions.remotes.size)
+            for (transition in transitions) {
+                assertThat(testShellTransitions.remotes.values).doesNotContain(transition)
+            }
         }
     }
 
     @DisableFlags(Flags.FLAG_RETURN_ANIMATION_FRAMEWORK_LONG_LIVED)
     @Test
     fun doesNotRegisterLongLivedTransitionIfFlagIsDisabled() {
-        val factory = controllerFactory(component = null)
-        assertThrows(IllegalStateException::class.java) {
-            activityTransitionAnimator.register(factory.cookie, factory)
+        kosmos.runTest {
+            val factory = controllerFactory(component = null)
+            assertThrows(IllegalStateException::class.java) {
+                underTest.register(factory.cookie, factory, testScope)
+            }
         }
     }
 
     @EnableFlags(Flags.FLAG_RETURN_ANIMATION_FRAMEWORK_LONG_LIVED)
     @Test
     fun doesNotRegisterLongLivedTransitionIfMissingRequiredProperties() {
-        // No ComponentName
-        var factory = controllerFactory(component = null)
-        assertThrows(IllegalStateException::class.java) {
-            activityTransitionAnimator.register(factory.cookie, factory)
-        }
+        kosmos.runTest {
+            // No ComponentName
+            var factory = controllerFactory(component = null)
+            assertThrows(IllegalStateException::class.java) {
+                underTest.register(factory.cookie, factory, testScope)
+            }
 
-        // No TransitionRegister
-        activityTransitionAnimator =
-            ActivityTransitionAnimator(
-                mainExecutor,
-                transitionRegister = null,
-                testTransitionAnimator,
-                testTransitionAnimator,
-                disableWmTimeout = true,
-            )
-        factory = controllerFactory()
-        assertThrows(IllegalStateException::class.java) {
-            activityTransitionAnimator.register(factory.cookie, factory)
+            // No TransitionRegister
+            val activityTransitionAnimator =
+                ActivityTransitionAnimator(
+                    mainExecutor,
+                    transitionRegister = null,
+                    testTransitionAnimator,
+                    testTransitionAnimator,
+                    disableWmTimeout = true,
+                )
+            factory = controllerFactory()
+            assertThrows(IllegalStateException::class.java) {
+                activityTransitionAnimator.register(factory.cookie, factory, testScope)
+            }
         }
     }
 
@@ -281,27 +293,29 @@
     )
     @Test
     fun unregistersLongLivedTransition() {
-        val cookies = arrayOfNulls<ActivityTransitionAnimator.TransitionCookie>(3)
+        kosmos.runTest {
+            val cookies = arrayOfNulls<ActivityTransitionAnimator.TransitionCookie>(3)
 
-        for (index in 0 until 3) {
-            cookies[index] = mock(ActivityTransitionAnimator.TransitionCookie::class.java)
-            val factory = controllerFactory(cookies[index]!!)
-            activityTransitionAnimator.register(factory.cookie, factory)
+            for (index in 0 until 3) {
+                cookies[index] = mock(ActivityTransitionAnimator.TransitionCookie::class.java)
+                val factory = controllerFactory(cookies[index]!!)
+                underTest.register(factory.cookie, factory, testScope)
+            }
+
+            underTest.unregister(cookies[0]!!)
+            assertEquals(4, testShellTransitions.remotes.size)
+
+            underTest.unregister(cookies[2]!!)
+            assertEquals(2, testShellTransitions.remotes.size)
+
+            underTest.unregister(cookies[1]!!)
+            assertThat(testShellTransitions.remotes).isEmpty()
         }
-
-        activityTransitionAnimator.unregister(cookies[0]!!)
-        assertEquals(4, testShellTransitions.remotes.size)
-
-        activityTransitionAnimator.unregister(cookies[2]!!)
-        assertEquals(2, testShellTransitions.remotes.size)
-
-        activityTransitionAnimator.unregister(cookies[1]!!)
-        assertThat(testShellTransitions.remotes).isEmpty()
     }
 
     @Test
     fun doesNotStartIfAnimationIsCancelled() {
-        val runner = activityTransitionAnimator.createEphemeralRunner(controller)
+        val runner = underTest.createEphemeralRunner(controller)
         runner.onAnimationCancelled()
         runner.onAnimationStart(TRANSIT_NONE, emptyArray(), emptyArray(), emptyArray(), iCallback)
 
@@ -315,7 +329,7 @@
 
     @Test
     fun cancelsIfNoOpeningWindowIsFound() {
-        val runner = activityTransitionAnimator.createEphemeralRunner(controller)
+        val runner = underTest.createEphemeralRunner(controller)
         runner.onAnimationStart(TRANSIT_NONE, emptyArray(), emptyArray(), emptyArray(), iCallback)
 
         waitForIdleSync()
@@ -328,7 +342,7 @@
 
     @Test
     fun startsAnimationIfWindowIsOpening() {
-        val runner = activityTransitionAnimator.createEphemeralRunner(controller)
+        val runner = underTest.createEphemeralRunner(controller)
         runner.onAnimationStart(
             TRANSIT_NONE,
             arrayOf(fakeWindow()),
@@ -354,9 +368,11 @@
     )
     @Test
     fun creatingRunnerWithLazyInitializationThrows_whenTheFlagsAreDisabled() {
-        assertThrows(IllegalStateException::class.java) {
-            val factory = controllerFactory()
-            activityTransitionAnimator.createLongLivedRunner(factory, forLaunch = true)
+        kosmos.runTest {
+            assertThrows(IllegalStateException::class.java) {
+                val factory = controllerFactory()
+                underTest.createLongLivedRunner(factory, testScope, forLaunch = true)
+            }
         }
     }
 
@@ -365,44 +381,34 @@
         Flags.FLAG_RETURN_ANIMATION_FRAMEWORK_LONG_LIVED,
     )
     @Test
-    fun runnerCreatesDelegateLazily_whenPostingTimeouts() {
-        val factory = controllerFactory()
-        val runner = activityTransitionAnimator.createLongLivedRunner(factory, forLaunch = true)
-        assertNull(runner.delegate)
-        runner.postTimeouts()
-        assertNotNull(runner.delegate)
-    }
-
-    @EnableFlags(
-        Flags.FLAG_RETURN_ANIMATION_FRAMEWORK_LIBRARY,
-        Flags.FLAG_RETURN_ANIMATION_FRAMEWORK_LONG_LIVED,
-    )
-    @Test
     fun runnerCreatesDelegateLazily_onAnimationStart() {
-        val factory = controllerFactory()
-        val runner = activityTransitionAnimator.createLongLivedRunner(factory, forLaunch = true)
-        assertNull(runner.delegate)
+        kosmos.runTest {
+            val factory = controllerFactory()
+            val runner = underTest.createLongLivedRunner(factory, testScope, forLaunch = true)
+            assertNull(runner.delegate)
 
-        var delegateInitialized = false
-        activityTransitionAnimator.addListener(
-            object : ActivityTransitionAnimator.Listener {
-                override fun onTransitionAnimationStart() {
-                    // This is called iff the delegate was initialized, so it's a good proxy for
-                    // checking the initialization.
-                    delegateInitialized = true
+            var delegateInitialized = false
+            underTest.addListener(
+                object : ActivityTransitionAnimator.Listener {
+                    override fun onTransitionAnimationStart() {
+                        // This is called iff the delegate was initialized, so it's a good proxy for
+                        // checking the initialization.
+                        delegateInitialized = true
+                    }
                 }
-            }
-        )
-        runner.onAnimationStart(
-            TRANSIT_NONE,
-            arrayOf(fakeWindow()),
-            emptyArray(),
-            emptyArray(),
-            iCallback,
-        )
+            )
+            runner.onAnimationStart(
+                TRANSIT_NONE,
+                arrayOf(fakeWindow()),
+                emptyArray(),
+                emptyArray(),
+                iCallback,
+            )
+            testScope.advanceUntilIdle()
+            waitForIdleSync()
 
-        waitForIdleSync()
-        assertTrue(delegateInitialized)
+            assertTrue(delegateInitialized)
+        }
     }
 
     @EnableFlags(
@@ -411,29 +417,32 @@
     )
     @Test
     fun runnerCreatesDelegateLazily_onAnimationTakeover() {
-        val factory = controllerFactory()
-        val runner = activityTransitionAnimator.createLongLivedRunner(factory, forLaunch = false)
-        assertNull(runner.delegate)
+        kosmos.runTest {
+            val factory = controllerFactory()
+            val runner = underTest.createLongLivedRunner(factory, testScope, forLaunch = false)
+            assertNull(runner.delegate)
 
-        var delegateInitialized = false
-        activityTransitionAnimator.addListener(
-            object : ActivityTransitionAnimator.Listener {
-                override fun onTransitionAnimationStart() {
-                    // This is called iff the delegate was initialized, so it's a good proxy for
-                    // checking the initialization.
-                    delegateInitialized = true
+            var delegateInitialized = false
+            underTest.addListener(
+                object : ActivityTransitionAnimator.Listener {
+                    override fun onTransitionAnimationStart() {
+                        // This is called iff the delegate was initialized, so it's a good proxy for
+                        // checking the initialization.
+                        delegateInitialized = true
+                    }
                 }
-            }
-        )
-        runner.takeOverAnimation(
-            arrayOf(fakeWindow(MODE_CLOSING)),
-            arrayOf(WindowAnimationState()),
-            SurfaceControl.Transaction(),
-            iCallback,
-        )
+            )
+            runner.takeOverAnimation(
+                arrayOf(fakeWindow(MODE_CLOSING)),
+                arrayOf(WindowAnimationState()),
+                SurfaceControl.Transaction(),
+                iCallback,
+            )
+            testScope.advanceUntilIdle()
+            waitForIdleSync()
 
-        waitForIdleSync()
-        assertTrue(delegateInitialized)
+            assertTrue(delegateInitialized)
+        }
     }
 
     @DisableFlags(
@@ -442,7 +451,7 @@
     )
     @Test
     fun animationTakeoverThrows_whenTheFlagsAreDisabled() {
-        val runner = activityTransitionAnimator.createEphemeralRunner(controller)
+        val runner = underTest.createEphemeralRunner(controller)
         assertThrows(IllegalStateException::class.java) {
             runner.takeOverAnimation(
                 arrayOf(fakeWindow()),
@@ -459,7 +468,7 @@
     )
     @Test
     fun disposeRunner_delegateDereferenced() {
-        val runner = activityTransitionAnimator.createEphemeralRunner(controller)
+        val runner = underTest.createEphemeralRunner(controller)
         assertNotNull(runner.delegate)
         runner.dispose()
         waitForIdleSync()
@@ -469,13 +478,13 @@
     @Test
     fun concurrentListenerModification_doesNotThrow() {
         // Need a second listener to trigger the concurrent modification.
-        activityTransitionAnimator.addListener(object : ActivityTransitionAnimator.Listener {})
+        underTest.addListener(object : ActivityTransitionAnimator.Listener {})
         `when`(listener.onTransitionAnimationStart()).thenAnswer {
-            activityTransitionAnimator.removeListener(listener)
+            underTest.removeListener(listener)
             listener
         }
 
-        val runner = activityTransitionAnimator.createEphemeralRunner(controller)
+        val runner = underTest.createEphemeralRunner(controller)
         runner.onAnimationStart(
             TRANSIT_NONE,
             arrayOf(fakeWindow()),
@@ -494,7 +503,7 @@
         component: ComponentName? = mock(ComponentName::class.java),
     ): ActivityTransitionAnimator.ControllerFactory {
         return object : ActivityTransitionAnimator.ControllerFactory(cookie, component) {
-            override fun createController(forLaunch: Boolean) =
+            override suspend fun createController(forLaunch: Boolean) =
                 object : DelegateTransitionAnimatorController(controller) {
                     override val isLaunching: Boolean
                         get() = forLaunch
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
index 4baca71..5249620 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -63,7 +63,6 @@
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor
 import com.google.common.truth.Truth.assertThat
 import dagger.Lazy
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -89,7 +88,6 @@
 private const val SENSOR_WIDTH = 30
 private const val SENSOR_HEIGHT = 60
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelTest.kt
index 655b2cc..f3aaa3d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelTest.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runCurrent
@@ -43,7 +42,6 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt
index e61acc4..9ae5715 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.statusbar.phone.SystemUIDialog
 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.After
@@ -56,7 +55,6 @@
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-@OptIn(ExperimentalCoroutinesApi::class)
 class AudioSharingDeviceItemActionInteractorTest : SysuiTestCase() {
     @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
     private val kosmos = testKosmos().apply { testDispatcher = UnconfinedTestDispatcher() }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentManagerTest.kt
new file mode 100644
index 0000000..6ed990d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentManagerTest.kt
@@ -0,0 +1,461 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bluetooth.qsdialog
+
+import android.graphics.drawable.Drawable
+import android.testing.TestableLooper
+import android.view.LayoutInflater
+import android.view.View
+import android.view.View.GONE
+import android.view.View.VISIBLE
+import android.view.ViewGroup.LayoutParams.MATCH_PARENT
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.UiEventLogger
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.DialogTransitionAnimator
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.model.SysUiState
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.statusbar.phone.SystemUIDialogManager
+import com.android.systemui.testKosmos
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+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
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyLong
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class BluetoothDetailsContentManagerTest : SysuiTestCase() {
+    companion object {
+        const val DEVICE_NAME = "device"
+        const val DEVICE_CONNECTION_SUMMARY = "active"
+        const val ENABLED = true
+        const val CONTENT_HEIGHT = WRAP_CONTENT
+    }
+
+    @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+    private val cachedBluetoothDevice = mock<CachedBluetoothDevice>()
+
+    private val bluetoothTileDialogCallback = mock<BluetoothTileDialogCallback>()
+
+    private val drawable = mock<Drawable>()
+
+    private val uiEventLogger = mock<UiEventLogger>()
+
+    private val logger = mock<BluetoothTileDialogLogger>()
+
+    private val sysuiDialogFactory = mock<SystemUIDialog.Factory>()
+    private val dialogManager = mock<SystemUIDialogManager>()
+    private val sysuiState = mock<SysUiState>()
+    private val dialogTransitionAnimator = mock<DialogTransitionAnimator>()
+
+    private val fakeSystemClock = FakeSystemClock()
+
+    private val uiProperties =
+        BluetoothTileDialogViewModel.UiProperties.build(
+            isBluetoothEnabled = ENABLED,
+            isAutoOnToggleFeatureAvailable = ENABLED,
+        )
+
+    private lateinit var icon: Pair<Drawable, String>
+    private lateinit var mBluetoothDetailsContentManager: BluetoothDetailsContentManager
+    private lateinit var deviceItem: DeviceItem
+    private lateinit var contentView: View
+
+    private val kosmos = testKosmos()
+
+    @Before
+    fun setUp() {
+        with(kosmos) {
+            contentView =
+                LayoutInflater.from(mContext).inflate(R.layout.bluetooth_tile_dialog, null)
+
+            whenever(sysuiState.setFlag(anyLong(), anyBoolean())).thenReturn(sysuiState)
+
+            mBluetoothDetailsContentManager =
+                BluetoothDetailsContentManager(
+                    uiProperties,
+                    CONTENT_HEIGHT,
+                    bluetoothTileDialogCallback,
+                    /* isInDialog= */ true,
+                    {},
+                    testDispatcher,
+                    fakeSystemClock,
+                    uiEventLogger,
+                    logger,
+                )
+
+            whenever(sysuiDialogFactory.create(any<SystemUIDialog.Delegate>(), any())).thenAnswer {
+                SystemUIDialog(
+                    mContext,
+                    0,
+                    SystemUIDialog.DEFAULT_DISMISS_ON_DEVICE_LOCK,
+                    dialogManager,
+                    sysuiState,
+                    fakeBroadcastDispatcher,
+                    dialogTransitionAnimator,
+                    it.getArgument(0),
+                )
+            }
+
+            icon = Pair(drawable, DEVICE_NAME)
+            deviceItem =
+                DeviceItem(
+                    type = DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE,
+                    cachedBluetoothDevice = cachedBluetoothDevice,
+                    deviceName = DEVICE_NAME,
+                    connectionSummary = DEVICE_CONNECTION_SUMMARY,
+                    iconWithDescription = icon,
+                    background = null,
+                )
+            whenever(cachedBluetoothDevice.isBusy).thenReturn(false)
+        }
+    }
+
+    @Test
+    fun testShowDialog_createRecyclerViewWithAdapter() {
+        mBluetoothDetailsContentManager.bind(contentView)
+        mBluetoothDetailsContentManager.start()
+
+        val recyclerView = contentView.requireViewById<RecyclerView>(R.id.device_list)
+
+        assertThat(recyclerView).isNotNull()
+        assertThat(recyclerView.visibility).isEqualTo(VISIBLE)
+        assertThat(recyclerView.adapter).isNotNull()
+        assertThat(recyclerView.layoutManager is LinearLayoutManager).isTrue()
+        mBluetoothDetailsContentManager.releaseView()
+    }
+
+    @Test
+    fun testShowDialog_displayBluetoothDevice() {
+        with(kosmos) {
+            testScope.runTest {
+                mBluetoothDetailsContentManager.bind(contentView)
+                mBluetoothDetailsContentManager.start()
+                fakeSystemClock.setElapsedRealtime(Long.MAX_VALUE)
+                mBluetoothDetailsContentManager.onDeviceItemUpdated(
+                    listOf(deviceItem),
+                    showSeeAll = false,
+                    showPairNewDevice = false,
+                )
+
+                val recyclerView = contentView.requireViewById<RecyclerView>(R.id.device_list)
+                val adapter = recyclerView?.adapter as BluetoothDetailsContentManager.Adapter
+                assertThat(adapter.itemCount).isEqualTo(1)
+                assertThat(adapter.getItem(0).deviceName).isEqualTo(DEVICE_NAME)
+                assertThat(adapter.getItem(0).connectionSummary)
+                    .isEqualTo(DEVICE_CONNECTION_SUMMARY)
+                assertThat(adapter.getItem(0).iconWithDescription).isEqualTo(icon)
+                mBluetoothDetailsContentManager.releaseView()
+            }
+        }
+    }
+
+    @Test
+    fun testDeviceItemViewHolder_cachedDeviceNotBusy() {
+        with(kosmos) {
+            testScope.runTest {
+                deviceItem.isEnabled = true
+
+                val view =
+                    LayoutInflater.from(mContext)
+                        .inflate(R.layout.bluetooth_device_item, null, false)
+                val viewHolder =
+                    mBluetoothDetailsContentManager.Adapter().DeviceItemViewHolder(view)
+                viewHolder.bind(deviceItem)
+                val container = view.requireViewById<View>(R.id.bluetooth_device_row)
+
+                assertThat(container).isNotNull()
+                assertThat(container.isEnabled).isTrue()
+                assertThat(container.hasOnClickListeners()).isTrue()
+                val value by collectLastValue(mBluetoothDetailsContentManager.deviceItemClick)
+                runCurrent()
+                container.performClick()
+                runCurrent()
+                assertThat(value).isNotNull()
+                value?.let {
+                    assertThat(it.target).isEqualTo(DeviceItemClick.Target.ENTIRE_ROW)
+                    assertThat(it.clickedView).isEqualTo(container)
+                    assertThat(it.deviceItem).isEqualTo(deviceItem)
+                }
+            }
+        }
+    }
+
+    @Test
+    fun testDeviceItemViewHolder_cachedDeviceBusy() {
+        with(kosmos) {
+            deviceItem.isEnabled = false
+
+            val view =
+                LayoutInflater.from(mContext).inflate(R.layout.bluetooth_device_item, null, false)
+            val viewHolder =
+                BluetoothDetailsContentManager(
+                        uiProperties,
+                        CONTENT_HEIGHT,
+                        bluetoothTileDialogCallback,
+                        /* isInDialog= */ true,
+                        {},
+                        testDispatcher,
+                        fakeSystemClock,
+                        uiEventLogger,
+                        logger,
+                    )
+                    .Adapter()
+                    .DeviceItemViewHolder(view)
+            viewHolder.bind(deviceItem)
+            val container = view.requireViewById<View>(R.id.bluetooth_device_row)
+
+            assertThat(container).isNotNull()
+            assertThat(container.isEnabled).isFalse()
+            assertThat(container.hasOnClickListeners()).isTrue()
+        }
+    }
+
+    @Test
+    fun testDeviceItemViewHolder_clickActionIcon() {
+        with(kosmos) {
+            testScope.runTest {
+                deviceItem.isEnabled = true
+
+                val view =
+                    LayoutInflater.from(mContext)
+                        .inflate(R.layout.bluetooth_device_item, null, false)
+                val viewHolder =
+                    mBluetoothDetailsContentManager.Adapter().DeviceItemViewHolder(view)
+                viewHolder.bind(deviceItem)
+                val actionIconView = view.requireViewById<View>(R.id.gear_icon)
+
+                assertThat(actionIconView).isNotNull()
+                assertThat(actionIconView.hasOnClickListeners()).isTrue()
+                val value by collectLastValue(mBluetoothDetailsContentManager.deviceItemClick)
+                runCurrent()
+                actionIconView.performClick()
+                runCurrent()
+                assertThat(value).isNotNull()
+                value?.let {
+                    assertThat(it.target).isEqualTo(DeviceItemClick.Target.ACTION_ICON)
+                    assertThat(it.clickedView).isEqualTo(actionIconView)
+                    assertThat(it.deviceItem).isEqualTo(deviceItem)
+                }
+            }
+        }
+    }
+
+    @Test
+    fun testOnDeviceUpdated_hideSeeAll_showPairNew() {
+        with(kosmos) {
+            testScope.runTest {
+                mBluetoothDetailsContentManager.bind(contentView)
+                mBluetoothDetailsContentManager.start()
+                fakeSystemClock.setElapsedRealtime(Long.MAX_VALUE)
+                mBluetoothDetailsContentManager.onDeviceItemUpdated(
+                    listOf(deviceItem),
+                    showSeeAll = false,
+                    showPairNewDevice = true,
+                )
+
+                val seeAllButton = contentView.requireViewById<View>(R.id.see_all_button)
+                val pairNewButton = contentView.requireViewById<View>(R.id.pair_new_device_button)
+                val recyclerView = contentView.requireViewById<RecyclerView>(R.id.device_list)
+                val adapter = recyclerView?.adapter as BluetoothDetailsContentManager.Adapter
+                val scrollViewContent = contentView.requireViewById<View>(R.id.scroll_view)
+
+                assertThat(seeAllButton).isNotNull()
+                assertThat(seeAllButton.visibility).isEqualTo(GONE)
+                assertThat(pairNewButton).isNotNull()
+                assertThat(pairNewButton.visibility).isEqualTo(VISIBLE)
+                assertThat(adapter.itemCount).isEqualTo(1)
+                assertThat(scrollViewContent.layoutParams.height).isEqualTo(WRAP_CONTENT)
+                mBluetoothDetailsContentManager.releaseView()
+            }
+        }
+    }
+
+    @Test
+    fun testShowDialog_cachedHeightLargerThanMinHeight_displayFromCachedHeight() {
+        with(kosmos) {
+            testScope.runTest {
+                val cachedHeight = Int.MAX_VALUE
+                val contentManager =
+                    BluetoothDetailsContentManager(
+                        BluetoothTileDialogViewModel.UiProperties.build(ENABLED, ENABLED),
+                        cachedHeight,
+                        bluetoothTileDialogCallback,
+                        /* isInDialog= */ true,
+                        {},
+                        testDispatcher,
+                        fakeSystemClock,
+                        uiEventLogger,
+                        logger,
+                    )
+                contentManager.bind(contentView)
+                contentManager.start()
+                assertThat(contentView.requireViewById<View>(R.id.scroll_view).layoutParams.height)
+                    .isEqualTo(cachedHeight)
+                contentManager.releaseView()
+            }
+        }
+    }
+
+    @Test
+    fun testShowDialog_cachedHeightLessThanMinHeight_displayFromUiProperties() {
+        with(kosmos) {
+            testScope.runTest {
+                val contentManager =
+                    BluetoothDetailsContentManager(
+                        BluetoothTileDialogViewModel.UiProperties.build(ENABLED, ENABLED),
+                        MATCH_PARENT,
+                        bluetoothTileDialogCallback,
+                        /* isInDialog= */ true,
+                        {},
+                        testDispatcher,
+                        fakeSystemClock,
+                        uiEventLogger,
+                        logger,
+                    )
+                contentManager.bind(contentView)
+                contentManager.start()
+                assertThat(contentView.requireViewById<View>(R.id.scroll_view).layoutParams.height)
+                    .isGreaterThan(MATCH_PARENT)
+                contentManager.releaseView()
+            }
+        }
+    }
+
+    @Test
+    fun testShowDialog_bluetoothEnabled_autoOnToggleGone() {
+        with(kosmos) {
+            testScope.runTest {
+                val contentManager =
+                    BluetoothDetailsContentManager(
+                        BluetoothTileDialogViewModel.UiProperties.build(ENABLED, ENABLED),
+                        MATCH_PARENT,
+                        bluetoothTileDialogCallback,
+                        /* isInDialog= */ true,
+                        {},
+                        testDispatcher,
+                        fakeSystemClock,
+                        uiEventLogger,
+                        logger,
+                    )
+                contentManager.bind(contentView)
+                contentManager.start()
+                assertThat(
+                        contentView
+                            .requireViewById<View>(R.id.bluetooth_auto_on_toggle_layout)
+                            .visibility
+                    )
+                    .isEqualTo(GONE)
+                contentManager.releaseView()
+            }
+        }
+    }
+
+    @Test
+    fun testOnAudioSharingButtonUpdated_visibleActive_activateButton() {
+        with(kosmos) {
+            testScope.runTest {
+                mBluetoothDetailsContentManager.bind(contentView)
+                mBluetoothDetailsContentManager.start()
+                fakeSystemClock.setElapsedRealtime(Long.MAX_VALUE)
+                mBluetoothDetailsContentManager.onAudioSharingButtonUpdated(
+                    visibility = VISIBLE,
+                    label = null,
+                    isActive = true,
+                )
+
+                val audioSharingButton =
+                    contentView.requireViewById<View>(R.id.audio_sharing_button)
+
+                assertThat(audioSharingButton).isNotNull()
+                assertThat(audioSharingButton.visibility).isEqualTo(VISIBLE)
+                assertThat(audioSharingButton.isActivated).isTrue()
+                mBluetoothDetailsContentManager.releaseView()
+            }
+        }
+    }
+
+    @Test
+    fun testOnAudioSharingButtonUpdated_visibleNotActive_inactivateButton() {
+        with(kosmos) {
+            testScope.runTest {
+                mBluetoothDetailsContentManager.bind(contentView)
+                mBluetoothDetailsContentManager.start()
+                fakeSystemClock.setElapsedRealtime(Long.MAX_VALUE)
+                mBluetoothDetailsContentManager.onAudioSharingButtonUpdated(
+                    visibility = VISIBLE,
+                    label = null,
+                    isActive = false,
+                )
+
+                val audioSharingButton =
+                    contentView.requireViewById<View>(R.id.audio_sharing_button)
+
+                assertThat(audioSharingButton).isNotNull()
+                assertThat(audioSharingButton.visibility).isEqualTo(VISIBLE)
+                assertThat(audioSharingButton.isActivated).isFalse()
+                mBluetoothDetailsContentManager.releaseView()
+            }
+        }
+    }
+
+    @Test
+    fun testOnAudioSharingButtonUpdated_gone_inactivateButton() {
+        with(kosmos) {
+            testScope.runTest {
+                mBluetoothDetailsContentManager.bind(contentView)
+                mBluetoothDetailsContentManager.start()
+                fakeSystemClock.setElapsedRealtime(Long.MAX_VALUE)
+                mBluetoothDetailsContentManager.onAudioSharingButtonUpdated(
+                    visibility = GONE,
+                    label = null,
+                    isActive = false,
+                )
+
+                val audioSharingButton =
+                    contentView.requireViewById<View>(R.id.audio_sharing_button)
+
+                assertThat(audioSharingButton).isNotNull()
+                assertThat(audioSharingButton.visibility).isEqualTo(GONE)
+                assertThat(audioSharingButton.isActivated).isFalse()
+                mBluetoothDetailsContentManager.releaseView()
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegateTest.kt
index 4396b0a..ffc7518 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegateTest.kt
@@ -16,47 +16,34 @@
 
 package com.android.systemui.bluetooth.qsdialog
 
-import android.graphics.drawable.Drawable
 import android.testing.TestableLooper
-import android.view.LayoutInflater
-import android.view.View
-import android.view.View.GONE
-import android.view.View.VISIBLE
-import android.view.ViewGroup.LayoutParams.MATCH_PARENT
 import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
-import com.android.settingslib.bluetooth.CachedBluetoothDevice
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogTransitionAnimator
-import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.model.SysUiState
-import com.android.systemui.res.R
 import com.android.systemui.shade.data.repository.shadeDialogContextInteractor
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.statusbar.phone.SystemUIDialogManager
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.time.FakeSystemClock
-import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.test.TestCoroutineScheduler
 import kotlinx.coroutines.test.TestScope
-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
 import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.anyLong
 import org.mockito.Mock
-import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
 import org.mockito.junit.MockitoRule
 
@@ -73,33 +60,31 @@
 
     @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
 
-    @Mock private lateinit var cachedBluetoothDevice: CachedBluetoothDevice
+    @Mock
+    private lateinit var bluetoothDetailsContentManagerFactory:
+        BluetoothDetailsContentManager.Factory
+
+    @Mock private lateinit var bluetoothDetailsContentManager: BluetoothDetailsContentManager
 
     @Mock private lateinit var bluetoothTileDialogCallback: BluetoothTileDialogCallback
 
-    @Mock private lateinit var drawable: Drawable
-
     @Mock private lateinit var uiEventLogger: UiEventLogger
 
-    @Mock private lateinit var logger: BluetoothTileDialogLogger
+    @Mock private lateinit var sysuiDialogFactory: SystemUIDialog.Factory
+    @Mock private lateinit var dialogManager: SystemUIDialogManager
+    @Mock private lateinit var sysuiState: SysUiState
+    @Mock private lateinit var dialogTransitionAnimator: DialogTransitionAnimator
 
     private val uiProperties =
         BluetoothTileDialogViewModel.UiProperties.build(
             isBluetoothEnabled = ENABLED,
             isAutoOnToggleFeatureAvailable = ENABLED,
         )
-    @Mock private lateinit var sysuiDialogFactory: SystemUIDialog.Factory
-    @Mock private lateinit var dialogManager: SystemUIDialogManager
-    @Mock private lateinit var sysuiState: SysUiState
-    @Mock private lateinit var dialogTransitionAnimator: DialogTransitionAnimator
 
-    private val fakeSystemClock = FakeSystemClock()
-
+    private lateinit var scheduler: TestCoroutineScheduler
     private lateinit var dispatcher: CoroutineDispatcher
     private lateinit var testScope: TestScope
-    private lateinit var icon: Pair<Drawable, String>
     private lateinit var mBluetoothTileDialogDelegate: BluetoothTileDialogDelegate
-    private lateinit var deviceItem: DeviceItem
 
     private val kosmos = testKosmos()
 
@@ -116,12 +101,10 @@
                 CONTENT_HEIGHT,
                 bluetoothTileDialogCallback,
                 {},
-                dispatcher,
-                fakeSystemClock,
                 uiEventLogger,
-                logger,
                 sysuiDialogFactory,
                 kosmos.shadeDialogContextInteractor,
+                bluetoothDetailsContentManagerFactory,
             )
 
         whenever(sysuiDialogFactory.create(any(SystemUIDialog.Delegate::class.java), any()))
@@ -138,17 +121,16 @@
                 )
             }
 
-        icon = Pair(drawable, DEVICE_NAME)
-        deviceItem =
-            DeviceItem(
-                type = DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE,
-                cachedBluetoothDevice = cachedBluetoothDevice,
-                deviceName = DEVICE_NAME,
-                connectionSummary = DEVICE_CONNECTION_SUMMARY,
-                iconWithDescription = icon,
-                background = null,
+        whenever(
+                bluetoothDetailsContentManagerFactory.create(
+                    any(),
+                    anyInt(),
+                    any(),
+                    anyBoolean(),
+                    any(),
+                )
             )
-        `when`(cachedBluetoothDevice.isBusy).thenReturn(false)
+            .thenReturn(bluetoothDetailsContentManager)
     }
 
     @Test
@@ -156,287 +138,9 @@
         val dialog = mBluetoothTileDialogDelegate.createDialog()
         dialog.show()
 
-        val recyclerView = dialog.requireViewById<RecyclerView>(R.id.device_list)
-
-        assertThat(recyclerView).isNotNull()
-        assertThat(recyclerView.visibility).isEqualTo(VISIBLE)
-        assertThat(recyclerView.adapter).isNotNull()
-        assertThat(recyclerView.layoutManager is LinearLayoutManager).isTrue()
+        verify(bluetoothDetailsContentManager).bind(any())
+        verify(bluetoothDetailsContentManager).start()
         dialog.dismiss()
-    }
-
-    @Test
-    fun testShowDialog_displayBluetoothDevice() {
-        testScope.runTest {
-            val dialog = mBluetoothTileDialogDelegate.createDialog()
-            dialog.show()
-            fakeSystemClock.setElapsedRealtime(Long.MAX_VALUE)
-            mBluetoothTileDialogDelegate.onDeviceItemUpdated(
-                dialog,
-                listOf(deviceItem),
-                showSeeAll = false,
-                showPairNewDevice = false,
-            )
-
-            val recyclerView = dialog.requireViewById<RecyclerView>(R.id.device_list)
-            val adapter = recyclerView?.adapter as BluetoothTileDialogDelegate.Adapter
-            assertThat(adapter.itemCount).isEqualTo(1)
-            assertThat(adapter.getItem(0).deviceName).isEqualTo(DEVICE_NAME)
-            assertThat(adapter.getItem(0).connectionSummary).isEqualTo(DEVICE_CONNECTION_SUMMARY)
-            assertThat(adapter.getItem(0).iconWithDescription).isEqualTo(icon)
-            dialog.dismiss()
-        }
-    }
-
-    @Test
-    fun testDeviceItemViewHolder_cachedDeviceNotBusy() {
-        testScope.runTest {
-            deviceItem.isEnabled = true
-
-            val view =
-                LayoutInflater.from(mContext).inflate(R.layout.bluetooth_device_item, null, false)
-            val viewHolder = mBluetoothTileDialogDelegate.Adapter().DeviceItemViewHolder(view)
-            viewHolder.bind(deviceItem)
-            val container = view.requireViewById<View>(R.id.bluetooth_device_row)
-
-            assertThat(container).isNotNull()
-            assertThat(container.isEnabled).isTrue()
-            assertThat(container.hasOnClickListeners()).isTrue()
-            val value by collectLastValue(mBluetoothTileDialogDelegate.deviceItemClick)
-            runCurrent()
-            container.performClick()
-            runCurrent()
-            assertThat(value).isNotNull()
-            value?.let {
-                assertThat(it.target).isEqualTo(DeviceItemClick.Target.ENTIRE_ROW)
-                assertThat(it.clickedView).isEqualTo(container)
-                assertThat(it.deviceItem).isEqualTo(deviceItem)
-            }
-        }
-    }
-
-    @Test
-    fun testDeviceItemViewHolder_cachedDeviceBusy() {
-        deviceItem.isEnabled = false
-
-        val view =
-            LayoutInflater.from(mContext).inflate(R.layout.bluetooth_device_item, null, false)
-        val viewHolder =
-            BluetoothTileDialogDelegate(
-                    uiProperties,
-                    CONTENT_HEIGHT,
-                    bluetoothTileDialogCallback,
-                    {},
-                    dispatcher,
-                    fakeSystemClock,
-                    uiEventLogger,
-                    logger,
-                    sysuiDialogFactory,
-                    kosmos.shadeDialogContextInteractor,
-                )
-                .Adapter()
-                .DeviceItemViewHolder(view)
-        viewHolder.bind(deviceItem)
-        val container = view.requireViewById<View>(R.id.bluetooth_device_row)
-
-        assertThat(container).isNotNull()
-        assertThat(container.isEnabled).isFalse()
-        assertThat(container.hasOnClickListeners()).isTrue()
-    }
-
-    @Test
-    fun testDeviceItemViewHolder_clickActionIcon() {
-        testScope.runTest {
-            deviceItem.isEnabled = true
-
-            val view =
-                LayoutInflater.from(mContext).inflate(R.layout.bluetooth_device_item, null, false)
-            val viewHolder = mBluetoothTileDialogDelegate.Adapter().DeviceItemViewHolder(view)
-            viewHolder.bind(deviceItem)
-            val actionIconView = view.requireViewById<View>(R.id.gear_icon)
-
-            assertThat(actionIconView).isNotNull()
-            assertThat(actionIconView.hasOnClickListeners()).isTrue()
-            val value by collectLastValue(mBluetoothTileDialogDelegate.deviceItemClick)
-            runCurrent()
-            actionIconView.performClick()
-            runCurrent()
-            assertThat(value).isNotNull()
-            value?.let {
-                assertThat(it.target).isEqualTo(DeviceItemClick.Target.ACTION_ICON)
-                assertThat(it.clickedView).isEqualTo(actionIconView)
-                assertThat(it.deviceItem).isEqualTo(deviceItem)
-            }
-        }
-    }
-
-    @Test
-    fun testOnDeviceUpdated_hideSeeAll_showPairNew() {
-        testScope.runTest {
-            val dialog = mBluetoothTileDialogDelegate.createDialog()
-            dialog.show()
-            fakeSystemClock.setElapsedRealtime(Long.MAX_VALUE)
-            mBluetoothTileDialogDelegate.onDeviceItemUpdated(
-                dialog,
-                listOf(deviceItem),
-                showSeeAll = false,
-                showPairNewDevice = true,
-            )
-
-            val seeAllButton = dialog.requireViewById<View>(R.id.see_all_button)
-            val pairNewButton = dialog.requireViewById<View>(R.id.pair_new_device_button)
-            val recyclerView = dialog.requireViewById<RecyclerView>(R.id.device_list)
-            val adapter = recyclerView?.adapter as BluetoothTileDialogDelegate.Adapter
-            val scrollViewContent = dialog.requireViewById<View>(R.id.scroll_view)
-
-            assertThat(seeAllButton).isNotNull()
-            assertThat(seeAllButton.visibility).isEqualTo(GONE)
-            assertThat(pairNewButton).isNotNull()
-            assertThat(pairNewButton.visibility).isEqualTo(VISIBLE)
-            assertThat(adapter.itemCount).isEqualTo(1)
-            assertThat(scrollViewContent.layoutParams.height).isEqualTo(WRAP_CONTENT)
-            dialog.dismiss()
-        }
-    }
-
-    @Test
-    fun testShowDialog_cachedHeightLargerThanMinHeight_displayFromCachedHeight() {
-        testScope.runTest {
-            val cachedHeight = Int.MAX_VALUE
-            val dialog =
-                BluetoothTileDialogDelegate(
-                        BluetoothTileDialogViewModel.UiProperties.build(ENABLED, ENABLED),
-                        cachedHeight,
-                        bluetoothTileDialogCallback,
-                        {},
-                        dispatcher,
-                        fakeSystemClock,
-                        uiEventLogger,
-                        logger,
-                        sysuiDialogFactory,
-                        kosmos.shadeDialogContextInteractor,
-                    )
-                    .createDialog()
-            dialog.show()
-            assertThat(dialog.requireViewById<View>(R.id.scroll_view).layoutParams.height)
-                .isEqualTo(cachedHeight)
-            dialog.dismiss()
-        }
-    }
-
-    @Test
-    fun testShowDialog_cachedHeightLessThanMinHeight_displayFromUiProperties() {
-        testScope.runTest {
-            val dialog =
-                BluetoothTileDialogDelegate(
-                        BluetoothTileDialogViewModel.UiProperties.build(ENABLED, ENABLED),
-                        MATCH_PARENT,
-                        bluetoothTileDialogCallback,
-                        {},
-                        dispatcher,
-                        fakeSystemClock,
-                        uiEventLogger,
-                        logger,
-                        sysuiDialogFactory,
-                        kosmos.shadeDialogContextInteractor,
-                    )
-                    .createDialog()
-            dialog.show()
-            assertThat(dialog.requireViewById<View>(R.id.scroll_view).layoutParams.height)
-                .isGreaterThan(MATCH_PARENT)
-            dialog.dismiss()
-        }
-    }
-
-    @Test
-    fun testShowDialog_bluetoothEnabled_autoOnToggleGone() {
-        testScope.runTest {
-            val dialog =
-                BluetoothTileDialogDelegate(
-                        BluetoothTileDialogViewModel.UiProperties.build(ENABLED, ENABLED),
-                        MATCH_PARENT,
-                        bluetoothTileDialogCallback,
-                        {},
-                        dispatcher,
-                        fakeSystemClock,
-                        uiEventLogger,
-                        logger,
-                        sysuiDialogFactory,
-                        kosmos.shadeDialogContextInteractor,
-                    )
-                    .createDialog()
-            dialog.show()
-            assertThat(
-                    dialog.requireViewById<View>(R.id.bluetooth_auto_on_toggle_layout).visibility
-                )
-                .isEqualTo(GONE)
-            dialog.dismiss()
-        }
-    }
-
-    @Test
-    fun testOnAudioSharingButtonUpdated_visibleActive_activateButton() {
-        testScope.runTest {
-            val dialog = mBluetoothTileDialogDelegate.createDialog()
-            dialog.show()
-            fakeSystemClock.setElapsedRealtime(Long.MAX_VALUE)
-            mBluetoothTileDialogDelegate.onAudioSharingButtonUpdated(
-                dialog,
-                visibility = VISIBLE,
-                label = null,
-                isActive = true,
-            )
-
-            val audioSharingButton = dialog.requireViewById<View>(R.id.audio_sharing_button)
-
-            assertThat(audioSharingButton).isNotNull()
-            assertThat(audioSharingButton.visibility).isEqualTo(VISIBLE)
-            assertThat(audioSharingButton.isActivated).isTrue()
-            dialog.dismiss()
-        }
-    }
-
-    @Test
-    fun testOnAudioSharingButtonUpdated_visibleNotActive_inactivateButton() {
-        testScope.runTest {
-            val dialog = mBluetoothTileDialogDelegate.createDialog()
-            dialog.show()
-            fakeSystemClock.setElapsedRealtime(Long.MAX_VALUE)
-            mBluetoothTileDialogDelegate.onAudioSharingButtonUpdated(
-                dialog,
-                visibility = VISIBLE,
-                label = null,
-                isActive = false,
-            )
-
-            val audioSharingButton = dialog.requireViewById<View>(R.id.audio_sharing_button)
-
-            assertThat(audioSharingButton).isNotNull()
-            assertThat(audioSharingButton.visibility).isEqualTo(VISIBLE)
-            assertThat(audioSharingButton.isActivated).isFalse()
-            dialog.dismiss()
-        }
-    }
-
-    @Test
-    fun testOnAudioSharingButtonUpdated_gone_inactivateButton() {
-        testScope.runTest {
-            val dialog = mBluetoothTileDialogDelegate.createDialog()
-            dialog.show()
-            fakeSystemClock.setElapsedRealtime(Long.MAX_VALUE)
-            mBluetoothTileDialogDelegate.onAudioSharingButtonUpdated(
-                dialog,
-                visibility = GONE,
-                label = null,
-                isActive = false,
-            )
-
-            val audioSharingButton = dialog.requireViewById<View>(R.id.audio_sharing_button)
-
-            assertThat(audioSharingButton).isNotNull()
-            assertThat(audioSharingButton.visibility).isEqualTo(GONE)
-            assertThat(audioSharingButton.isActivated).isFalse()
-            dialog.dismiss()
-        }
+        verify(bluetoothDetailsContentManager).releaseView()
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt
index a56c2cb..47a834b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt
@@ -45,7 +45,6 @@
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.asStateFlow
@@ -67,7 +66,6 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-@OptIn(ExperimentalCoroutinesApi::class)
 @EnableFlags(Flags.FLAG_BLUETOOTH_QS_TILE_DIALOG_AUTO_ON_TOGGLE)
 class BluetoothTileDialogViewModelTest : SysuiTestCase() {
 
@@ -78,8 +76,6 @@
 
     private lateinit var bluetoothTileDialogViewModel: BluetoothTileDialogViewModel
 
-    @Mock private lateinit var bluetoothStateInteractor: BluetoothStateInteractor
-
     @Mock private lateinit var bluetoothDeviceMetadataInteractor: BluetoothDeviceMetadataInteractor
 
     @Mock private lateinit var deviceItemInteractor: DeviceItemInteractor
@@ -108,9 +104,16 @@
 
     @Mock private lateinit var bluetoothTileDialogDelegate: BluetoothTileDialogDelegate
 
+    @Mock
+    private lateinit var bluetoothDetailsContentManagerFactory:
+        BluetoothDetailsContentManager.Factory
+
+    @Mock private lateinit var bluetoothDetailsContentManager: BluetoothDetailsContentManager
+
     @Mock private lateinit var sysuiDialog: SystemUIDialog
     @Mock private lateinit var expandable: Expandable
     @Mock private lateinit var controller: DialogTransitionAnimator.Controller
+    @Mock private lateinit var mockView: View
 
     private val sharedPreferences = FakeSharedPreferences()
 
@@ -131,7 +134,7 @@
                     localBluetoothManager,
                     bluetoothTileDialogLogger,
                     testScope.backgroundScope,
-                    dispatcher
+                    dispatcher,
                 ),
                 // TODO(b/316822488): Create FakeBluetoothAutoOnInteractor.
                 BluetoothAutoOnInteractor(
@@ -139,7 +142,7 @@
                         localBluetoothManager,
                         bluetoothAdapter,
                         testScope.backgroundScope,
-                        dispatcher
+                        dispatcher,
                     )
                 ),
                 kosmos.audioSharingInteractor,
@@ -153,7 +156,8 @@
                 dispatcher,
                 dispatcher,
                 sharedPreferences,
-                mBluetoothTileDialogDelegateDelegateFactory
+                mBluetoothTileDialogDelegateDelegateFactory,
+                bluetoothDetailsContentManagerFactory,
             )
         whenever(deviceItemInteractor.deviceItemUpdate).thenReturn(MutableSharedFlow())
         whenever(deviceItemInteractor.deviceItemUpdateRequest)
@@ -163,20 +167,34 @@
         whenever(mBluetoothTileDialogDelegateDelegateFactory.create(any(), anyInt(), any(), any()))
             .thenReturn(bluetoothTileDialogDelegate)
         whenever(bluetoothTileDialogDelegate.createDialog()).thenReturn(sysuiDialog)
+        whenever(bluetoothTileDialogDelegate.contentManager)
+            .thenReturn(bluetoothDetailsContentManager)
+        whenever(
+                bluetoothDetailsContentManagerFactory.create(
+                    any(),
+                    anyInt(),
+                    any(),
+                    anyBoolean(),
+                    any(),
+                )
+            )
+            .thenReturn(bluetoothDetailsContentManager)
         whenever(sysuiDialog.context).thenReturn(mContext)
-        whenever(bluetoothTileDialogDelegate.bluetoothStateToggle)
+        whenever(bluetoothDetailsContentManager.bluetoothStateToggle)
             .thenReturn(getMutableStateFlow(false))
-        whenever(bluetoothTileDialogDelegate.deviceItemClick).thenReturn(MutableSharedFlow())
-        whenever(bluetoothTileDialogDelegate.contentHeight).thenReturn(getMutableStateFlow(0))
-        whenever(bluetoothTileDialogDelegate.bluetoothAutoOnToggle)
+        whenever(bluetoothDetailsContentManager.deviceItemClick)
+            .thenReturn(getMutableStateFlow(null))
+        whenever(bluetoothDetailsContentManager.contentHeight).thenReturn(getMutableStateFlow(0))
+        whenever(bluetoothDetailsContentManager.bluetoothAutoOnToggle)
             .thenReturn(getMutableStateFlow(false))
         whenever(expandable.dialogTransitionController(any())).thenReturn(controller)
+        whenever(mockView.context).thenReturn(mContext)
     }
 
     @Test
-    fun testShowDialog_noAnimation() {
+    fun testShowDetailsContent_noAnimation() {
         testScope.runTest {
-            bluetoothTileDialogViewModel.showDialog(null)
+            bluetoothTileDialogViewModel.showDetailsContent(null, null)
             runCurrent()
 
             verify(mDialogTransitionAnimator, never()).show(any(), any(), any())
@@ -184,9 +202,9 @@
     }
 
     @Test
-    fun testShowDialog_animated() {
+    fun testShowDetailsContent_animated() {
         testScope.runTest {
-            bluetoothTileDialogViewModel.showDialog(expandable)
+            bluetoothTileDialogViewModel.showDetailsContent(expandable, null)
             runCurrent()
 
             verify(mDialogTransitionAnimator).show(any(), any(), anyBoolean())
@@ -194,10 +212,21 @@
     }
 
     @Test
-    fun testShowDialog_animated_callInBackgroundThread() {
+    fun testShowDetailsContent_animated_inDetailsView() {
+        testScope.runTest {
+            bluetoothTileDialogViewModel.showDetailsContent(expandable, mockView)
+            runCurrent()
+
+            verify(bluetoothDetailsContentManager).bind(mockView)
+            verify(bluetoothDetailsContentManager).start()
+        }
+    }
+
+    @Test
+    fun testShowDetailsContent_animated_callInBackgroundThread() {
         testScope.runTest {
             backgroundExecutor.execute {
-                bluetoothTileDialogViewModel.showDialog(expandable)
+                bluetoothTileDialogViewModel.showDetailsContent(expandable, null)
                 runCurrent()
 
                 verify(mDialogTransitionAnimator).show(any(), any(), anyBoolean())
@@ -206,9 +235,22 @@
     }
 
     @Test
-    fun testShowDialog_fetchDeviceItem() {
+    fun testShowDetailsContent_animated_callInBackgroundThread_inDetailsView() {
         testScope.runTest {
-            bluetoothTileDialogViewModel.showDialog(null)
+            backgroundExecutor.execute {
+                bluetoothTileDialogViewModel.showDetailsContent(expandable, mockView)
+                runCurrent()
+
+                verify(bluetoothDetailsContentManager).bind(mockView)
+                verify(bluetoothDetailsContentManager).start()
+            }
+        }
+    }
+
+    @Test
+    fun testShowDetailsContent_fetchDeviceItem() {
+        testScope.runTest {
+            bluetoothTileDialogViewModel.showDetailsContent(null, null)
             runCurrent()
 
             verify(deviceItemInteractor).deviceItemUpdate
@@ -219,7 +261,7 @@
     fun testStartSettingsActivity_activityLaunched_dialogDismissed() {
         testScope.runTest {
             whenever(deviceItem.cachedBluetoothDevice).thenReturn(cachedBluetoothDevice)
-            bluetoothTileDialogViewModel.showDialog(null)
+            bluetoothTileDialogViewModel.showDetailsContent(null, null)
             runCurrent()
 
             val clickedView = View(context)
@@ -236,7 +278,7 @@
             val actual =
                 BluetoothTileDialogViewModel.UiProperties.build(
                     isBluetoothEnabled = true,
-                    isAutoOnToggleFeatureAvailable = true
+                    isAutoOnToggleFeatureAvailable = true,
                 )
             assertThat(actual.autoOnToggleVisibility).isEqualTo(GONE)
         }
@@ -248,7 +290,7 @@
             val actual =
                 BluetoothTileDialogViewModel.UiProperties.build(
                     isBluetoothEnabled = false,
-                    isAutoOnToggleFeatureAvailable = true
+                    isAutoOnToggleFeatureAvailable = true,
                 )
             assertThat(actual.autoOnToggleVisibility).isEqualTo(VISIBLE)
         }
@@ -260,7 +302,7 @@
             val actual =
                 BluetoothTileDialogViewModel.UiProperties.build(
                     isBluetoothEnabled = false,
-                    isAutoOnToggleFeatureAvailable = false
+                    isAutoOnToggleFeatureAvailable = false,
                 )
             assertThat(actual.autoOnToggleVisibility).isEqualTo(GONE)
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/brightness/ui/compose/BrightnessSliderMotionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/brightness/ui/compose/BrightnessSliderMotionTest.kt
new file mode 100644
index 0000000..9dab9d7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/brightness/ui/compose/BrightnessSliderMotionTest.kt
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.brightness.ui.compose
+
+import android.platform.test.annotations.MotionTest
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.wrapContentHeight
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
+import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.swipeLeft
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import com.android.compose.theme.PlatformTheme
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel
+import com.android.systemui.common.shared.model.asIcon
+import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.motion.createSysUiComposeMotionTestRule
+import com.android.systemui.utils.PolicyRestriction
+import kotlin.test.Test
+import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.async
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.joinAll
+import org.junit.Rule
+import org.junit.runner.RunWith
+import platform.test.motion.compose.ComposeRecordingSpec
+import platform.test.motion.compose.MotionControl
+import platform.test.motion.compose.MotionControlScope
+import platform.test.motion.compose.feature
+import platform.test.motion.compose.motionTestValueOfNode
+import platform.test.motion.compose.recordMotion
+import platform.test.motion.compose.runTest
+import platform.test.motion.compose.values.MotionTestValueKey
+import platform.test.motion.golden.FeatureCapture
+import platform.test.motion.golden.TimeSeriesCaptureScope
+import platform.test.motion.golden.asDataPoint
+import platform.test.screenshot.DeviceEmulationSpec
+import platform.test.screenshot.Displays.Phone
+
+@RunWith(AndroidJUnit4::class)
+@LargeTest
+@MotionTest
+class BrightnessSliderMotionTest : SysuiTestCase() {
+
+    private val deviceSpec = DeviceEmulationSpec(Phone)
+    private val kosmos = Kosmos()
+
+    @get:Rule val motionTestRule = createSysUiComposeMotionTestRule(kosmos, deviceSpec)
+
+    @Composable
+    private fun BrightnessSliderUnderTest(startingValue: Int) {
+        PlatformTheme {
+            BrightnessSlider(
+                gammaValue = startingValue,
+                modifier = Modifier.wrapContentHeight().fillMaxWidth(),
+                valueRange = 0..100,
+                iconResProvider = BrightnessSliderViewModel::getIconForPercentage,
+                imageLoader = { resId, context -> context.getDrawable(resId)!!.asIcon(null) },
+                restriction = PolicyRestriction.NoRestriction,
+                onRestrictedClick = {},
+                onDrag = {},
+                onStop = {},
+                overriddenByAppState = false,
+                hapticsViewModelFactory = kosmos.sliderHapticsViewModelFactory,
+            )
+        }
+    }
+
+    @Test
+    fun iconAlphaChanges() {
+        motionTestRule.runTest(timeout = 30.seconds) {
+            val motion =
+                recordMotion(
+                    content = { BrightnessSliderUnderTest(100) },
+                    ComposeRecordingSpec(
+                        MotionControl(delayReadyToPlay = { awaitCondition { !isAnimating } }) {
+                            coroutineScope {
+                                val gesture = async {
+                                    performTouchInputAsync(
+                                        onNode(hasTestTag("com.android.systemui:id/slider"))
+                                    ) {
+                                        swipeLeft(startX = right, endX = left, durationMillis = 500)
+                                    }
+                                }
+                                val animationEnd = async {
+                                    awaitCondition { isAnimating }
+                                    awaitCondition { !isAnimating }
+                                }
+                                joinAll(gesture, animationEnd)
+                            }
+                        }
+                    ) {
+                        featureFloat(BrightnessSliderMotionTestKeys.ActiveIconAlpha)
+                        featureFloat(BrightnessSliderMotionTestKeys.InactiveIconAlpha)
+                    },
+                )
+            assertThat(motion).timeSeriesMatchesGolden("brightnessSlider_iconAlphaChanges")
+        }
+    }
+
+    private companion object {
+
+        val MotionControlScope.isAnimating: Boolean
+            get() = motionTestValueOfNode(BrightnessSliderMotionTestKeys.AnimatingIcon)
+
+        fun TimeSeriesCaptureScope<SemanticsNodeInteractionsProvider>.featureFloat(
+            motionTestValueKey: MotionTestValueKey<Float>
+        ) {
+            feature(
+                motionTestValueKey = motionTestValueKey,
+                capture =
+                    FeatureCapture(motionTestValueKey.semanticsPropertyKey.name) {
+                        it.asDataPoint()
+                    },
+            )
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderContentProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderContentProviderTest.kt
index 8d9fa6a..e50035d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderContentProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderContentProviderTest.kt
@@ -41,7 +41,6 @@
 val TEST_URI = Uri.Builder().scheme("content").authority(AUTHORITY).path("path").build()
 
 @SmallTest
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 @RunWith(AndroidJUnit4::class)
 class ImageLoaderContentProviderTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderTest.kt
index 76c3349..de70bca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderTest.kt
@@ -29,7 +29,6 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 @RunWith(AndroidJUnit4::class)
 class ImageLoaderTest : SysuiTestCase() {
 
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 a3c3d2c..a6cf5e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -34,7 +34,6 @@
 import com.android.systemui.SystemUIAppComponentFactoryBase
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogTransitionAnimator
-import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
 import com.android.systemui.dock.DockManagerFake
 import com.android.systemui.flags.FakeFeatureFlags
 import com.android.systemui.flags.Flags
@@ -70,7 +69,6 @@
 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
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -84,7 +82,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -134,7 +131,6 @@
                             .thenReturn(FakeSharedPreferences())
                     },
                 userTracker = userTracker,
-                communalSettingsInteractor = kosmos.communalSettingsInteractor,
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
         val remoteUserSelectionManager =
@@ -206,7 +202,6 @@
                 backgroundDispatcher = testDispatcher,
                 appContext = mContext,
                 accessibilityManager = mock(),
-                communalSettingsInteractor = kosmos.communalSettingsInteractor,
                 sceneInteractor = { kosmos.sceneInteractor },
             )
         underTest.previewManager =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 38acd23..0c9213c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -206,6 +206,7 @@
     private @Mock ShadeInteractor mShadeInteractor;
     private @Mock ShadeWindowLogger mShadeWindowLogger;
     private @Mock SelectedUserInteractor mSelectedUserInteractor;
+    private @Mock UserTracker.Callback mUserTrackerCallback;
     private @Mock KeyguardInteractor mKeyguardInteractor;
     private @Mock KeyguardTransitionBootInteractor mKeyguardTransitionBootInteractor;
     private @Captor ArgumentCaptor<KeyguardStateController.Callback>
@@ -280,7 +281,7 @@
                 () -> mShadeInteractor,
                 mShadeWindowLogger,
                 () -> mSelectedUserInteractor,
-                mUserTracker,
+                mock(UserTracker.class),
                 mKosmos.getNotificationShadeWindowModel(),
                 mSecureSettings,
                 mKosmos::getCommunalInteractor,
@@ -318,7 +319,7 @@
 
         } catch (Exception e) {
             // Just so we don't have to add the exception signature to every test.
-            fail();
+            fail(e.getMessage());
         }
     }
 
@@ -330,18 +331,156 @@
 
         /* First test the default behavior: handleUserSwitching() is not invoked */
         when(mUserTracker.isUserSwitching()).thenReturn(false);
-        mViewMediator.mUpdateCallback = mock(KeyguardUpdateMonitorCallback.class);
         mViewMediator.onSystemReady();
         TestableLooper.get(this).processAllMessages();
 
-        verify(mViewMediator.mUpdateCallback, never()).onUserSwitching(userId);
+        verify(mUserTrackerCallback, never()).onUserChanging(eq(userId), eq(mContext),
+                any(Runnable.class));
 
         /* Next test user switching is already in progress when started */
         when(mUserTracker.isUserSwitching()).thenReturn(true);
         mViewMediator.onSystemReady();
         TestableLooper.get(this).processAllMessages();
 
-        verify(mViewMediator.mUpdateCallback).onUserSwitching(userId);
+        verify(mUserTrackerCallback).onUserChanging(eq(userId), eq(mContext),
+                any(Runnable.class));
+    }
+
+    @Test
+    @TestableLooper.RunWithLooper(setAsMainLooper = true)
+    public void testGoingAwayFollowedByBeforeUserSwitchDoesNotHideKeyguard() {
+        setCurrentUser(/* userId= */1099, /* isSecure= */false);
+
+        // Setup keyguard
+        mViewMediator.onSystemReady();
+        processAllMessagesAndBgExecutorMessages();
+        mViewMediator.setShowingLocked(true, "");
+
+        // Request keyguard going away
+        when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(true);
+        mViewMediator.mKeyguardGoingAwayRunnable.run();
+
+        // After the request, begin a switch to a new secure user
+        int nextUserId = 500;
+        setCurrentUser(nextUserId, /* isSecure= */true);
+        Runnable result = mock(Runnable.class);
+        mViewMediator.handleBeforeUserSwitching(nextUserId, result);
+        processAllMessagesAndBgExecutorMessages();
+        verify(result).run();
+
+        // After that request has begun, have WM tell us to exit keyguard
+        RemoteAnimationTarget[] apps = new RemoteAnimationTarget[]{
+                mock(RemoteAnimationTarget.class)
+        };
+        RemoteAnimationTarget[] wallpapers = new RemoteAnimationTarget[]{
+                mock(RemoteAnimationTarget.class)
+        };
+        IRemoteAnimationFinishedCallback callback = mock(IRemoteAnimationFinishedCallback.class);
+        mViewMediator.startKeyguardExitAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY, apps, wallpapers,
+                null, callback);
+        processAllMessagesAndBgExecutorMessages();
+
+        // The call to exit should be rejected, and keyguard should still be visible
+        verify(mKeyguardUnlockAnimationController, never()).notifyStartSurfaceBehindRemoteAnimation(
+                any(), any(), any(), anyLong(), anyBoolean());
+        try {
+            assertATMSLockScreenShowing(true);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+        assertTrue(mViewMediator.isShowingAndNotOccluded());
+    }
+
+    @Test
+    @TestableLooper.RunWithLooper(setAsMainLooper = true)
+    public void testUserSwitchToSecureUserShowsBouncer() {
+        setCurrentUser(/* userId= */1099, /* isSecure= */true);
+
+        // Setup keyguard
+        mViewMediator.onSystemReady();
+        processAllMessagesAndBgExecutorMessages();
+        mViewMediator.setShowingLocked(true, "");
+
+        // After the request, begin a switch to a new secure user
+        int nextUserId = 500;
+        setCurrentUser(nextUserId, /* isSecure= */true);
+
+        Runnable beforeResult = mock(Runnable.class);
+        mViewMediator.handleBeforeUserSwitching(nextUserId, beforeResult);
+        processAllMessagesAndBgExecutorMessages();
+        verify(beforeResult).run();
+
+        // Dismiss should not be called while user switch is in progress
+        Runnable onSwitchResult = mock(Runnable.class);
+        mViewMediator.handleUserSwitching(nextUserId, onSwitchResult);
+        processAllMessagesAndBgExecutorMessages();
+        verify(onSwitchResult).run();
+        verify(mStatusBarKeyguardViewManager, never()).dismissAndCollapse();
+
+        // The attempt to dismiss only comes on user switch complete, which will trigger a call to
+        // show the bouncer in StatusBarKeyguardViewManager
+        mViewMediator.handleUserSwitchComplete(nextUserId);
+        TestableLooper.get(this).moveTimeForward(600);
+        processAllMessagesAndBgExecutorMessages();
+
+        verify(mStatusBarKeyguardViewManager).dismissAndCollapse();
+    }
+
+    @Test
+    @TestableLooper.RunWithLooper(setAsMainLooper = true)
+    public void testUserSwitchToInsecureUserDismissesKeyguard() {
+        int userId = 1099;
+        when(mUserTracker.getUserId()).thenReturn(userId);
+
+        // Setup keyguard
+        mViewMediator.onSystemReady();
+        processAllMessagesAndBgExecutorMessages();
+        mViewMediator.setShowingLocked(true, "");
+
+        // After the request, begin a switch to an insecure user
+        int nextUserId = 500;
+        when(mLockPatternUtils.isSecure(nextUserId)).thenReturn(false);
+
+        Runnable beforeResult = mock(Runnable.class);
+        mViewMediator.handleBeforeUserSwitching(nextUserId, beforeResult);
+        processAllMessagesAndBgExecutorMessages();
+        verify(beforeResult).run();
+
+        // The call to dismiss comes during the user switch
+        Runnable onSwitchResult = mock(Runnable.class);
+        mViewMediator.handleUserSwitching(nextUserId, onSwitchResult);
+        processAllMessagesAndBgExecutorMessages();
+        verify(onSwitchResult).run();
+
+        verify(mStatusBarKeyguardViewManager).dismissAndCollapse();
+    }
+
+    @Test
+    @TestableLooper.RunWithLooper(setAsMainLooper = true)
+    public void testUserSwitchToSecureUserWhileKeyguardNotVisibleShowsKeyguard() {
+        setCurrentUser(/* userId= */1099, /* isSecure= */true);
+
+        // Setup keyguard as not visible
+        mViewMediator.onSystemReady();
+        processAllMessagesAndBgExecutorMessages();
+        mViewMediator.setShowingLocked(false, "");
+        processAllMessagesAndBgExecutorMessages();
+
+        // Begin a switch to a new secure user
+        int nextUserId = 500;
+        setCurrentUser(nextUserId, /* isSecure= */true);
+
+        Runnable beforeResult = mock(Runnable.class);
+        mViewMediator.handleBeforeUserSwitching(nextUserId, beforeResult);
+        processAllMessagesAndBgExecutorMessages();
+        verify(beforeResult).run();
+
+        try {
+            assertATMSLockScreenShowing(true);
+        } catch (Exception e) {
+            fail();
+        }
+        assertTrue(mViewMediator.isShowingAndNotOccluded());
     }
 
     @Test
@@ -1105,7 +1244,7 @@
         processAllMessagesAndBgExecutorMessages();
 
         verify(mStatusBarKeyguardViewManager, never()).reset(anyBoolean());
-        assertATMSAndKeyguardViewMediatorStatesMatch();
+
     }
 
     @Test
@@ -1149,6 +1288,7 @@
         IRemoteAnimationFinishedCallback callback = mock(IRemoteAnimationFinishedCallback.class);
 
         when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(true);
+        mViewMediator.mKeyguardGoingAwayRunnable.run();
         mViewMediator.startKeyguardExitAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY, apps, wallpapers,
                 null, callback);
         processAllMessagesAndBgExecutorMessages();
@@ -1203,13 +1343,6 @@
 
         // The captor will have the most recent setLockScreenShown call's value.
         assertEquals(showing, showingCaptor.getValue());
-
-        // We're now just after the last setLockScreenShown call. If we expect the lockscreen to be
-        // showing, ensure that we didn't subsequently ask for it to go away.
-        if (showing) {
-            orderedSetLockScreenShownCalls.verify(mActivityTaskManagerService, never())
-                    .keyguardGoingAway(anyInt());
-        }
     }
 
     /**
@@ -1370,6 +1503,7 @@
                 mKeyguardInteractor,
                 mKeyguardTransitionBootInteractor,
                 mock(WindowManagerOcclusionManager.class));
+        mViewMediator.mUserChangedCallback = mUserTrackerCallback;
         mViewMediator.start();
 
         mViewMediator.registerCentralSurfaces(mCentralSurfaces, null, null, null, null);
@@ -1383,4 +1517,10 @@
     private void captureKeyguardUpdateMonitorCallback() {
         verify(mUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallbackCaptor.capture());
     }
+
+    private void setCurrentUser(int userId, boolean isSecure) {
+        when(mUserTracker.getUserId()).thenReturn(userId);
+        when(mSelectedUserInteractor.getSelectedUserId()).thenReturn(userId);
+        when(mLockPatternUtils.isSecure(userId)).thenReturn(isSecure);
+    }
 }
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 ab691c6..0027a8b 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
@@ -29,7 +29,6 @@
 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.domain.interactor.communalSettingsInteractor
 import com.android.systemui.dock.DockManagerFake
 import com.android.systemui.flags.DisableSceneContainer
 import com.android.systemui.flags.FakeFeatureFlags
@@ -59,7 +58,6 @@
 import com.android.systemui.util.settings.FakeSettings
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
@@ -79,7 +77,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 @DisableSceneContainer
@@ -271,7 +268,6 @@
                             .thenReturn(FakeSharedPreferences())
                     },
                 userTracker = userTracker,
-                communalSettingsInteractor = kosmos.communalSettingsInteractor,
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
         val remoteUserSelectionManager =
@@ -321,7 +317,6 @@
                 backgroundDispatcher = testDispatcher,
                 appContext = mContext,
                 accessibilityManager = mock(),
-                communalSettingsInteractor = kosmos.communalSettingsInteractor,
                 sceneInteractor = { kosmos.sceneInteractor },
             )
     }
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 caf08ef..b274f1c 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
@@ -30,7 +30,6 @@
 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.domain.interactor.communalSettingsInteractor
 import com.android.systemui.dock.DockManagerFake
 import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.flags.FakeFeatureFlags
@@ -60,7 +59,6 @@
 import com.android.systemui.util.settings.FakeSettings
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
@@ -79,7 +77,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @FlakyTest(
     bugId = 292574995,
     detail = "on certain architectures all permutations with startActivity=true is causing failures",
@@ -274,7 +271,6 @@
                             .thenReturn(FakeSharedPreferences())
                     },
                 userTracker = userTracker,
-                communalSettingsInteractor = kosmos.communalSettingsInteractor,
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
         val remoteUserSelectionManager =
@@ -326,7 +322,6 @@
                 backgroundDispatcher = testDispatcher,
                 appContext = mContext,
                 accessibilityManager = mock(),
-                communalSettingsInteractor = kosmos.communalSettingsInteractor,
                 sceneInteractor = { kosmos.sceneInteractor },
             )
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySectionTest.kt
index 4189720..df24bff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySectionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySectionTest.kt
@@ -38,7 +38,6 @@
 import com.android.systemui.statusbar.VibratorHelper
 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.test.TestScope
 import org.junit.Before
@@ -49,7 +48,6 @@
 import org.mockito.Mockito.mock
 import org.mockito.MockitoAnnotations
 
-@ExperimentalCoroutinesApi
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class DefaultDeviceEntrySectionTest : SysuiTestCase() {
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 051aba3..62c8275 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
@@ -29,7 +29,6 @@
 import com.android.systemui.animation.DialogTransitionAnimator
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.dock.DockManagerFake
 import com.android.systemui.flags.Flags
@@ -77,7 +76,6 @@
 import com.google.common.truth.Truth
 import kotlin.math.min
 import kotlin.test.assertEquals
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.flow.map
@@ -90,7 +88,6 @@
 import org.mockito.Mockito
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
@@ -214,7 +211,6 @@
                             .thenReturn(FakeSharedPreferences())
                     },
                 userTracker = userTracker,
-                communalSettingsInteractor = kosmos.communalSettingsInteractor,
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
         val remoteUserSelectionManager =
@@ -295,7 +291,6 @@
                         backgroundDispatcher = kosmos.testDispatcher,
                         appContext = mContext,
                         accessibilityManager = mock(),
-                        communalSettingsInteractor = kosmos.communalSettingsInteractor,
                         sceneInteractor = { kosmos.sceneInteractor },
                     ),
                 keyguardInteractor = keyguardInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/lifecycle/RepeatWhenAttachedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/lifecycle/RepeatWhenAttachedTest.kt
index e3aeaa8..fe5acb5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/lifecycle/RepeatWhenAttachedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/lifecycle/RepeatWhenAttachedTest.kt
@@ -28,7 +28,6 @@
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.DisposableHandle
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.awaitCancellation
 import kotlinx.coroutines.launch
@@ -52,7 +51,6 @@
 import org.mockito.kotlin.KArgumentCaptor
 import org.mockito.kotlin.argumentCaptor
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(JUnit4::class)
 class RepeatWhenAttachedTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/AmbientLightModeMonitorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/AmbientLightModeMonitorTest.kt
index 43ee388e..8a2dc15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/AmbientLightModeMonitorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/AmbientLightModeMonitorTest.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.sensors.AsyncSensorManager
 import java.util.Optional
+import javax.inject.Provider
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -50,7 +51,11 @@
         MockitoAnnotations.initMocks(this)
 
         ambientLightModeMonitor =
-            AmbientLightModeMonitor(Optional.of(algorithm), sensorManager, Optional.of(sensor))
+            AmbientLightModeMonitor(
+                Optional.of(algorithm),
+                sensorManager,
+                Optional.of(Provider { sensor }),
+            )
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt
index 676d8fa0..122af06 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt
@@ -73,7 +73,6 @@
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.runCurrent
@@ -117,7 +116,6 @@
 private const val USER_ID = 0
 private val DISMISS_INTENT = Intent().apply { action = "dismiss" }
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWithLooper(setAsMainLooper = true)
 @RunWith(ParameterizedAndroidJunit4::class)
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 811d2e2..b731c4f 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
@@ -49,7 +49,6 @@
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import java.util.concurrent.Executor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -81,7 +80,6 @@
 private const val SMARTSPACE_PACKAGE = "SMARTSPACE_PKG"
 private val SMARTSPACE_INSTANCE_ID = InstanceId.fakeInstanceId(456)!!
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt
index 496b319..f9e8cbfc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt
@@ -80,7 +80,6 @@
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.runCurrent
@@ -123,7 +122,6 @@
 private const val USER_ID = 0
 private val DISMISS_INTENT = Intent().apply { action = "dismiss" }
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWithLooper(setAsMainLooper = true)
 @RunWith(ParameterizedAndroidJunit4::class)
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 6c8a46f..a2bd5ec 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
@@ -79,7 +79,6 @@
 import javax.inject.Provider
 import junit.framework.Assert.assertEquals
 import junit.framework.Assert.assertTrue
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -112,7 +111,6 @@
 private const val PAUSED_LOCAL = "paused local"
 private const val PLAYING_LOCAL = "playing local"
 
-@ExperimentalCoroutinesApi
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @RunWith(ParameterizedAndroidJunit4::class)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt
index 072caa7..6ca4ae2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt
@@ -61,7 +61,6 @@
 import com.android.systemui.util.settings.FakeSettings
 import com.android.systemui.utils.os.FakeHandler
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -86,7 +85,6 @@
 import org.mockito.kotlin.atLeastOnce
 import org.mockito.kotlin.lastValue
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -458,7 +456,6 @@
         assertThat(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).isTrue()
     }
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
     fun isCurrentlyInGuidedTransformation_hostsVisible_expandImmediateEnabled_returnsFalse() =
         testScope.runTest {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java
index 2715cb3..86094d1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java
@@ -891,6 +891,13 @@
     }
 
     @Test
+    public void getTransferableMediaDevice_triggersFromLocalMediaManager() {
+        mMediaSwitchingController.getTransferableMediaDevices();
+
+        verify(mLocalMediaManager).getTransferableMediaDevices();
+    }
+
+    @Test
     public void getDeselectableMediaDevice_triggersFromLocalMediaManager() {
         mMediaSwitchingController.getDeselectableMediaDevice();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
index 7849ea5..042eb871 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -70,7 +70,6 @@
 import com.google.common.truth.Truth.assertThat
 import java.util.Optional
 import kotlin.test.assertNotNull
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runCurrent
@@ -90,7 +89,6 @@
 import org.mockito.kotlin.whenever
 
 /** atest SystemUITests:NoteTaskControllerTest */
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 internal class NoteTaskControllerTest : SysuiTestCase() {
@@ -179,7 +177,7 @@
             .apply { infoReference.set(expectedInfo) }
             .onBubbleExpandChanged(
                 isExpanding = true,
-                key = Bubble.getAppBubbleKeyForApp(expectedInfo.packageName, expectedInfo.user),
+                key = Bubble.getNoteBubbleKeyForApp(expectedInfo.packageName, expectedInfo.user),
             )
 
         verify(eventLogger).logNoteTaskOpened(expectedInfo)
@@ -194,7 +192,7 @@
             .apply { infoReference.set(expectedInfo) }
             .onBubbleExpandChanged(
                 isExpanding = false,
-                key = Bubble.getAppBubbleKeyForApp(expectedInfo.packageName, expectedInfo.user),
+                key = Bubble.getNoteBubbleKeyForApp(expectedInfo.packageName, expectedInfo.user),
             )
 
         verify(eventLogger).logNoteTaskClosed(expectedInfo)
@@ -209,7 +207,7 @@
             .apply { infoReference.set(expectedInfo) }
             .onBubbleExpandChanged(
                 isExpanding = true,
-                key = Bubble.getAppBubbleKeyForApp(expectedInfo.packageName, expectedInfo.user),
+                key = Bubble.getNoteBubbleKeyForApp(expectedInfo.packageName, expectedInfo.user),
             )
 
         verifyNoMoreInteractions(bubbles, keyguardManager, userManager, eventLogger)
@@ -223,14 +221,14 @@
             .apply { infoReference.set(expectedInfo) }
             .onBubbleExpandChanged(
                 isExpanding = false,
-                key = Bubble.getAppBubbleKeyForApp(expectedInfo.packageName, expectedInfo.user),
+                key = Bubble.getNoteBubbleKeyForApp(expectedInfo.packageName, expectedInfo.user),
             )
 
         verifyNoMoreInteractions(bubbles, keyguardManager, userManager, eventLogger)
     }
 
     @Test
-    fun onBubbleExpandChanged_notKeyAppBubble_shouldDoNothing() {
+    fun onBubbleExpandChanged_notKeyNoteBubble_shouldDoNothing() {
         createNoteTaskController().onBubbleExpandChanged(isExpanding = true, key = "any other key")
 
         verifyNoMoreInteractions(bubbles, keyguardManager, userManager, eventLogger)
@@ -241,7 +239,7 @@
         createNoteTaskController(isEnabled = false)
             .onBubbleExpandChanged(
                 isExpanding = true,
-                key = Bubble.getAppBubbleKeyForApp(NOTE_TASK_INFO.packageName, NOTE_TASK_INFO.user),
+                key = Bubble.getNoteBubbleKeyForApp(NOTE_TASK_INFO.packageName, NOTE_TASK_INFO.user),
             )
 
         verifyNoMoreInteractions(bubbles, keyguardManager, userManager, eventLogger)
@@ -740,7 +738,7 @@
         val intentCaptor = argumentCaptor<Intent>()
         val iconCaptor = argumentCaptor<Icon>()
         verify(bubbles)
-            .showOrHideAppBubble(capture(intentCaptor), eq(userHandle), capture(iconCaptor))
+            .showOrHideNoteBubble(capture(intentCaptor), eq(userHandle), capture(iconCaptor))
         assertThat(intentCaptor.value).run {
             hasAction(ACTION_CREATE_NOTE)
             hasPackage(NOTE_TASK_PACKAGE_NAME)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt
index 266cb51..8a4f1ad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt
@@ -47,7 +47,6 @@
 import com.android.wm.shell.bubbles.Bubbles
 import com.google.common.truth.Truth.assertThat
 import java.util.Optional
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -60,7 +59,7 @@
 import org.mockito.MockitoAnnotations.initMocks
 
 /** atest SystemUITests:NoteTaskInitializerTest */
-@OptIn(ExperimentalCoroutinesApi::class, InternalNoteTaskApi::class)
+@OptIn(InternalNoteTaskApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 internal class NoteTaskInitializerTest : SysuiTestCase() {
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 b7fb759..8d7de7e 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
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.notetask.quickaffordance
 
 import android.app.role.RoleManager
@@ -48,7 +46,6 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runTest
 import org.junit.After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceRequestControllerTestComposeOff.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceRequestControllerTestComposeOff.kt
index 82e24771..fbc6f84 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceRequestControllerTestComposeOff.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceRequestControllerTestComposeOff.kt
@@ -29,10 +29,10 @@
 import com.android.internal.statusbar.IAddTileResultCallback
 import com.android.systemui.InstanceIdSequenceFake
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.DisableSceneContainer
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.external.ui.dialog.tileRequestDialogComposeDelegateFactory
 import com.android.systemui.qs.flags.QSComposeFragment
-import com.android.systemui.shade.shared.flag.DualShade
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.commandline.CommandRegistry
 import com.android.systemui.testKosmos
@@ -57,7 +57,8 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@DisableFlags(value = [QSComposeFragment.FLAG_NAME, DualShade.FLAG_NAME])
+@DisableFlags(QSComposeFragment.FLAG_NAME)
+@DisableSceneContainer
 class TileServiceRequestControllerTestComposeOff : SysuiTestCase() {
 
     companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
index fc720b8..26cf4a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
@@ -68,6 +68,7 @@
             columns = 4,
             largeTilesSpan = 4,
             modifier = Modifier.fillMaxSize(),
+            onAddTile = {},
             onRemoveTile = {},
             onSetTiles = onSetTiles,
             onResize = { _, _ -> },
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/EditModeTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/EditModeTest.kt
new file mode 100644
index 0000000..4e8b0bc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/EditModeTest.kt
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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.fillMaxSize
+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.Modifier
+import androidx.compose.ui.semantics.SemanticsProperties
+import androidx.compose.ui.test.SemanticsMatcher
+import androidx.compose.ui.test.assert
+import androidx.compose.ui.test.filter
+import androidx.compose.ui.test.hasContentDescription
+import androidx.compose.ui.test.junit4.ComposeContentTestRule
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onChildren
+import androidx.compose.ui.test.onNodeWithContentDescription
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.test.performClick
+import androidx.compose.ui.text.AnnotatedString
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.shared.model.ContentDescription
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.qs.panels.shared.model.SizedTile
+import com.android.systemui.qs.panels.shared.model.SizedTileImpl
+import com.android.systemui.qs.panels.ui.compose.infinitegrid.DefaultEditTileGrid
+import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class EditModeTest : SysuiTestCase() {
+    @get:Rule val composeRule = createComposeRule()
+
+    @Composable
+    private fun EditTileGridUnderTest() {
+        var tiles by remember { mutableStateOf(TestEditTiles) }
+        val (currentTiles, otherTiles) = tiles.partition { it.tile.isCurrent }
+        val listState = EditTileListState(currentTiles, columns = 4, largeTilesSpan = 2)
+        DefaultEditTileGrid(
+            listState = listState,
+            otherTiles = otherTiles,
+            columns = 4,
+            largeTilesSpan = 4,
+            modifier = Modifier.fillMaxSize(),
+            onAddTile = { tiles = tiles.add(it) },
+            onRemoveTile = { tiles = tiles.remove(it) },
+            onSetTiles = {},
+            onResize = { _, _ -> },
+            onStopEditing = {},
+            onReset = null,
+        )
+    }
+
+    @Test
+    fun clickAvailableTile_shouldAdd() {
+        composeRule.setContent { EditTileGridUnderTest() }
+        composeRule.waitForIdle()
+
+        composeRule.onNodeWithContentDescription("tileF").performClick() // Tap to add
+        composeRule.waitForIdle()
+
+        composeRule.assertCurrentTilesGridContainsExactly(
+            listOf("tileA", "tileB", "tileC", "tileD_large", "tileE", "tileF")
+        )
+        composeRule.assertAvailableTilesGridContainsExactly(listOf("tileG_large"))
+    }
+
+    @Test
+    fun clickRemoveTarget_shouldRemoveSelection() {
+        composeRule.setContent { EditTileGridUnderTest() }
+        composeRule.waitForIdle()
+
+        composeRule.onNodeWithContentDescription("tileA").performClick() // Selects
+        composeRule.onNodeWithText("Remove").performClick() // Removes
+
+        composeRule.waitForIdle()
+
+        composeRule.assertCurrentTilesGridContainsExactly(
+            listOf("tileB", "tileC", "tileD_large", "tileE")
+        )
+        composeRule.assertAvailableTilesGridContainsExactly(listOf("tileA", "tileF", "tileG_large"))
+    }
+
+    private fun ComposeContentTestRule.assertCurrentTilesGridContainsExactly(specs: List<String>) =
+        assertGridContainsExactly(CURRENT_TILES_GRID_TEST_TAG, specs)
+
+    private fun ComposeContentTestRule.assertAvailableTilesGridContainsExactly(
+        specs: List<String>
+    ) = assertGridContainsExactly(AVAILABLE_TILES_GRID_TEST_TAG, specs)
+
+    private fun ComposeContentTestRule.assertGridContainsExactly(
+        testTag: String,
+        specs: List<String>,
+    ) {
+        onNodeWithTag(testTag)
+            .onChildren()
+            .filter(SemanticsMatcher.keyIsDefined(SemanticsProperties.ContentDescription))
+            .apply {
+                fetchSemanticsNodes().forEachIndexed { index, _ ->
+                    get(index).assert(hasContentDescription(specs[index]))
+                }
+            }
+    }
+
+    companion object {
+        private const val CURRENT_TILES_GRID_TEST_TAG = "CurrentTilesGrid"
+        private const val AVAILABLE_TILES_GRID_TEST_TAG = "AvailableTilesGrid"
+
+        private fun List<SizedTile<EditTileViewModel>>.add(
+            spec: TileSpec
+        ): List<SizedTile<EditTileViewModel>> {
+            return map {
+                if (it.tile.tileSpec == spec) {
+                    createEditTile(it.tile.tileSpec.spec)
+                } else {
+                    it
+                }
+            }
+        }
+
+        private fun List<SizedTile<EditTileViewModel>>.remove(
+            spec: TileSpec
+        ): List<SizedTile<EditTileViewModel>> {
+            return map {
+                if (it.tile.tileSpec == spec) {
+                    createEditTile(it.tile.tileSpec.spec, isCurrent = false)
+                } else {
+                    it
+                }
+            }
+        }
+
+        private fun createEditTile(
+            tileSpec: String,
+            isCurrent: Boolean = true,
+        ): SizedTile<EditTileViewModel> {
+            return SizedTileImpl(
+                EditTileViewModel(
+                    tileSpec = TileSpec.create(tileSpec),
+                    icon =
+                        Icon.Resource(
+                            android.R.drawable.star_on,
+                            ContentDescription.Loaded(tileSpec),
+                        ),
+                    label = AnnotatedString(tileSpec),
+                    appName = null,
+                    isCurrent = isCurrent,
+                    availableEditActions = emptySet(),
+                    category = TileCategory.UNKNOWN,
+                ),
+                getWidth(tileSpec),
+            )
+        }
+
+        private fun getWidth(tileSpec: String): Int {
+            return if (tileSpec.endsWith("large")) {
+                2
+            } else {
+                1
+            }
+        }
+
+        private val TestEditTiles =
+            listOf(
+                createEditTile("tileA"),
+                createEditTile("tileB"),
+                createEditTile("tileC"),
+                createEditTile("tileD_large"),
+                createEditTile("tileE"),
+                createEditTile("tileF", isCurrent = false),
+                createEditTile("tileG_large", isCurrent = false),
+            )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt
index f23553e..a0be02f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt
@@ -65,6 +65,7 @@
             columns = 4,
             largeTilesSpan = 4,
             modifier = Modifier.fillMaxSize(),
+            onAddTile = {},
             onRemoveTile = {},
             onSetTiles = {},
             onResize = onResize,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
index 330b887..1305b0c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
@@ -238,7 +238,8 @@
 
         tile.handleClick(null)
 
-        verify(bluetoothTileDialogViewModel).showDialog(null)
+        verify(bluetoothTileDialogViewModel)
+            .showDetailsContent(/* expandable= */ null, /* view= */ null)
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentManagerTest.kt
index 50b8f37..c20a801 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentManagerTest.kt
@@ -63,7 +63,7 @@
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
 @EnableSceneContainer
-@EnableFlags(Flags.FLAG_QS_TILE_DETAILED_VIEW, Flags.FLAG_DUAL_SHADE)
+@EnableFlags(Flags.FLAG_QS_TILE_DETAILED_VIEW)
 @UiThreadTest
 class InternetDetailsContentManagerTest : SysuiTestCase() {
     private val kosmos = Kosmos()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayCoreStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayCoreStartableTest.kt
index c8faa81..cf54df8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayCoreStartableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayCoreStartableTest.kt
@@ -45,7 +45,6 @@
 
 /** atest SystemUITests:com.android.systemui.reardisplay.RearDisplayCoreStartableTest */
 @SmallTest
-@kotlinx.coroutines.ExperimentalCoroutinesApi
 class RearDisplayCoreStartableTest : SysuiTestCase() {
 
     private val kosmos = testKosmos().useUnconfinedTestDispatcher()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt
index 69b762b..40547c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt
@@ -90,7 +90,7 @@
     private val kosmos = testKosmos()
     private lateinit var subject: LauncherProxyService
     @Mock private val dumpManager = DumpManager()
-    @Mock private val processWrapper = ProcessWrapper()
+    @Mock private lateinit var processWrapper: ProcessWrapper
     private val displayTracker = FakeDisplayTracker(mContext)
     private val fakeSystemClock = FakeSystemClock()
     private val sysUiState = SysUiState(displayTracker, kosmos.sceneContainerPlugin)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
index f695c13..1474def 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
@@ -38,7 +38,6 @@
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.TruthJUnit.assume
 import java.util.concurrent.Executor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -58,7 +57,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(Parameterized::class)
 class UserTrackerImplTest : SysuiTestCase() {
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 6724f82..732561e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
@@ -69,7 +69,6 @@
 import com.android.systemui.statusbar.notification.stack.notificationStackScrollLayoutController
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
@@ -87,7 +86,6 @@
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
-@ExperimentalCoroutinesApi
 @RunWith(AndroidTestingRunner::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
index 49d6909..856ece7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -89,7 +89,6 @@
 import com.google.common.truth.Truth.assertThat
 import java.util.Optional
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.test.TestScope
@@ -116,7 +115,6 @@
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 @RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt
index 9abe9aa..3de7db7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt
@@ -16,6 +16,8 @@
 
 package com.android.systemui.shade
 
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.View
@@ -26,6 +28,7 @@
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.fragments.FragmentHostManager
 import com.android.systemui.fragments.FragmentService
@@ -122,6 +125,7 @@
 
         overrideResource(R.dimen.split_shade_notifications_scrim_margin_bottom, SCRIM_MARGIN)
         overrideResource(R.dimen.notification_panel_margin_bottom, NOTIFICATIONS_MARGIN)
+        overrideResource(R.dimen.notification_2025_panel_margin_bottom, NOTIFICATIONS_MARGIN)
         overrideResource(R.bool.config_use_split_notification_shade, false)
         overrideResource(R.dimen.qs_footer_actions_bottom_padding, FOOTER_ACTIONS_PADDING)
         overrideResource(R.dimen.qs_footer_action_inset, FOOTER_ACTIONS_INSET)
@@ -360,6 +364,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_NOTIFICATIONS_REDESIGN_FOOTER_VIEW)
     fun testNotificationsMarginBottomIsUpdated() {
         Mockito.clearInvocations(view)
         enableSplitShade()
@@ -371,6 +376,18 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_NOTIFICATIONS_REDESIGN_FOOTER_VIEW)
+    fun testNotificationsMarginBottomIsUpdated_footerRedesign() {
+        Mockito.clearInvocations(view)
+        enableSplitShade()
+        verify(view).setNotificationsMarginBottom(NOTIFICATIONS_MARGIN)
+
+        overrideResource(R.dimen.notification_2025_panel_margin_bottom, 100)
+        disableSplitShade()
+        verify(view).setNotificationsMarginBottom(100)
+    }
+
+    @Test
     fun testSplitShadeLayout_qsFrameHasHorizontalMarginsOfZero() {
         enableSplitShade()
         underTest.updateResources()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt
index 4c12cc8..552fe8d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt
@@ -16,6 +16,8 @@
 
 package com.android.systemui.shade
 
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.View
@@ -26,6 +28,7 @@
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.fragments.FragmentHostManager
 import com.android.systemui.fragments.FragmentService
@@ -122,6 +125,7 @@
 
         overrideResource(R.dimen.split_shade_notifications_scrim_margin_bottom, SCRIM_MARGIN)
         overrideResource(R.dimen.notification_panel_margin_bottom, NOTIFICATIONS_MARGIN)
+        overrideResource(R.dimen.notification_2025_panel_margin_bottom, NOTIFICATIONS_MARGIN)
         overrideResource(R.bool.config_use_split_notification_shade, false)
         overrideResource(R.dimen.qs_footer_actions_bottom_padding, FOOTER_ACTIONS_PADDING)
         overrideResource(R.dimen.qs_footer_action_inset, FOOTER_ACTIONS_INSET)
@@ -358,6 +362,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_NOTIFICATIONS_REDESIGN_FOOTER_VIEW)
     fun testNotificationsMarginBottomIsUpdated() {
         Mockito.clearInvocations(view)
         enableSplitShade()
@@ -369,6 +374,18 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_NOTIFICATIONS_REDESIGN_FOOTER_VIEW)
+    fun testNotificationsMarginBottomIsUpdated_footerRedesign() {
+        Mockito.clearInvocations(view)
+        enableSplitShade()
+        verify(view).setNotificationsMarginBottom(NOTIFICATIONS_MARGIN)
+
+        overrideResource(R.dimen.notification_2025_panel_margin_bottom, 100)
+        disableSplitShade()
+        verify(view).setNotificationsMarginBottom(100)
+    }
+
+    @Test
     fun testSplitShadeLayout_isAlignedToGuideline() {
         enableSplitShade()
         underTest.updateResources()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt
index 57c2858..b75dd04 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt
@@ -58,7 +58,8 @@
                     },
                     ClockMessageBuffers(messageBuffer),
                     messageBuffer,
-                )
+                ),
+                isLargeClock = false,
             )
         underTest.textStyle = FontTextStyle()
         underTest.aodStyle = FontTextStyle()
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 cfc00a9..b7040ee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -35,7 +35,6 @@
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.mock
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.After
@@ -69,7 +68,6 @@
 @SmallTest
 @RunWithLooper(setAsMainLooper = true)
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalCoroutinesApi::class)
 class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
     private val kosmos =
         testKosmos().apply {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt
index 98487f7..f8154dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt
@@ -3,7 +3,6 @@
 import android.testing.TestableLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.qs.QS
@@ -30,7 +29,6 @@
 
     private val configurationController = FakeConfigurationController()
 
-    @OptIn(ExperimentalCoroutinesApi::class)
     @Mock private lateinit var scrimController: ScrimController
     @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
     private var qS: QS? = null
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt
index 77ca51c..3c4aecc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt
@@ -41,7 +41,6 @@
 import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
 import com.android.systemui.util.time.FakeSystemClock
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
@@ -64,7 +63,6 @@
 
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 class SystemStatusAnimationSchedulerImplTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt
index c8fbe61..3937d3d46 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt
@@ -20,6 +20,7 @@
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.NotificationLockscreenUserManager
 import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener
@@ -64,13 +65,14 @@
     fun setUp() {
         whenever(pipeline.allNotifs).thenReturn(listOf(entry))
         whenever(entry.row).thenReturn(row)
-        coordinator = ViewConfigCoordinator(
-            configurationController,
-            lockscreenUserManager,
-            gutsManager,
-            keyguardUpdateMonitor,
-            colorUpdateLogger,
-        )
+        coordinator =
+            ViewConfigCoordinator(
+                configurationController,
+                lockscreenUserManager,
+                gutsManager,
+                keyguardUpdateMonitor,
+                colorUpdateLogger,
+            )
         coordinator.attach(pipeline)
         userChangedListener = withArgCaptor {
             verify(lockscreenUserManager).addUserChangedListener(capture())
@@ -95,7 +97,7 @@
     fun themeChangePropagatesToEntry() {
         configurationListener.onThemeChanged()
         verify(entry).onDensityOrFontScaleChanged()
-        verify(entry).areGutsExposed()
+        checkGutsExposedCalled()
         verifyNoMoreInteractions(entry, row)
     }
 
@@ -103,7 +105,7 @@
     fun densityChangePropagatesToEntry() {
         configurationListener.onDensityOrFontScaleChanged()
         verify(entry).onDensityOrFontScaleChanged()
-        verify(entry).areGutsExposed()
+        checkGutsExposedCalled()
         verifyNoMoreInteractions(entry, row)
     }
 
@@ -127,7 +129,7 @@
         verify(entry).row
         verify(row).onUiModeChanged()
         verify(entry).onDensityOrFontScaleChanged()
-        verify(entry).areGutsExposed()
+        checkGutsExposedCalled()
         verifyNoMoreInteractions(entry, row)
         clearInvocations(entry, row)
 
@@ -158,7 +160,7 @@
         verify(entry).row
         verify(row).onUiModeChanged()
         verify(entry).onDensityOrFontScaleChanged()
-        verify(entry).areGutsExposed()
+        checkGutsExposedCalled()
         verifyNoMoreInteractions(entry, row)
         clearInvocations(entry, row)
 
@@ -194,8 +196,14 @@
         verify(entry).row
         verify(row).onUiModeChanged()
         verify(entry).onDensityOrFontScaleChanged()
-        verify(entry).areGutsExposed()
+        checkGutsExposedCalled()
         verifyNoMoreInteractions(entry, row)
         clearInvocations(entry, row)
     }
+
+    private fun checkGutsExposedCalled() {
+        if (!Flags.notificationUndoGutsOnConfigChanged()) {
+            verify(entry).areGutsExposed()
+        }
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt
index c4ef4f9..a16f2f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification.icon
 
 import android.app.ActivityManager
@@ -43,7 +41,6 @@
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 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
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index be89ab8..3061842 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -45,6 +45,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.Flags;
 import android.app.INotificationManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
@@ -52,11 +53,14 @@
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Person;
+import android.content.ComponentName;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutManager;
 import android.graphics.drawable.Drawable;
@@ -64,6 +68,9 @@
 import android.os.Handler;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.service.notification.StatusBarNotification;
 import android.testing.TestableLooper;
 import android.view.LayoutInflater;
@@ -80,6 +87,7 @@
 import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
 import com.android.systemui.res.R;
 import com.android.systemui.shade.ShadeController;
+import com.android.systemui.statusbar.RankingBuilder;
 import com.android.systemui.statusbar.SbnBuilder;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
@@ -155,6 +163,8 @@
     @Mock
     private Notification.BubbleMetadata mBubbleMetadata;
     private Handler mTestHandler;
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
     @Before
     public void setUp() throws Exception {
@@ -192,6 +202,14 @@
         when(mMockPackageManager.getPackageInfo(eq("android"), anyInt()))
                 .thenReturn(packageInfo);
 
+        ComponentName assistant = new ComponentName("package", "service");
+        when(mMockINotificationManager.getAllowedNotificationAssistant()).thenReturn(assistant);
+        ResolveInfo ri = new ResolveInfo();
+        ri.activityInfo = new ActivityInfo();
+        ri.activityInfo.packageName = assistant.getPackageName();
+        ri.activityInfo.name = "activity";
+        when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(List.of(ri));
+
         when(mShortcutInfo.getLabel()).thenReturn("Convo name");
         List<ShortcutInfo> shortcuts = Arrays.asList(mShortcutInfo);
         when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts);
@@ -216,8 +234,8 @@
                 new Intent(mContext, BubblesTestActivity.class),
                 PendingIntent.FLAG_MUTABLE);
         mBubbleSbn = new SbnBuilder(mSbn).setBubbleMetadata(
-                new Notification.BubbleMetadata.Builder(bubbleIntent,
-                        Icon.createWithResource(mContext, R.drawable.android)).build())
+                        new Notification.BubbleMetadata.Builder(bubbleIntent,
+                                Icon.createWithResource(mContext, R.drawable.android)).build())
                 .build();
         mBubbleEntry = new NotificationEntryBuilder()
                 .setSbn(mBubbleSbn)
@@ -237,8 +255,7 @@
         when(mPeopleSpaceWidgetManager.requestPinAppWidget(any(), any())).thenReturn(true);
     }
 
-    @Test
-    public void testBindNotification_SetsShortcutIcon() {
+    private void doStandardBind() {
         mNotificationInfo.bindNotification(
                 mShortcutManager,
                 mMockPackageManager,
@@ -251,12 +268,18 @@
                 mEntry,
                 mBubbleMetadata,
                 null,
+                null,
                 mIconFactory,
                 mContext,
                 true,
                 mTestHandler,
                 mTestHandler, null, Optional.of(mBubblesManager),
                 mShadeController);
+    }
+
+    @Test
+    public void testBindNotification_SetsShortcutIcon() {
+        doStandardBind();
         final ImageView view = mNotificationInfo.findViewById(R.id.conversation_icon);
         assertEquals(mIconDrawable, view.getDrawable());
     }
@@ -264,77 +287,43 @@
     @Test
     public void testBindNotification_SetsTextApplicationName() {
         when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
         final TextView textView = mNotificationInfo.findViewById(R.id.pkg_name);
         assertTrue(textView.getText().toString().contains("App Name"));
         assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
     }
-/**
-    @Test
-    public void testBindNotification_SetsTextChannelName() {
-        mNotificationInfo.bindNotification(
-                -1,
-                mShortcutManager,
-                mLauncherApps,
-                mMockPackageManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-    mBubbleMetadata,
-    null,
-                null,
-                null,
-                true);
-        final TextView textView = mNotificationInfo.findViewById(R.id.parent_channel_name);
-        assertTrue(textView.getText().toString().contains(mNotificationChannel.getName()));
-        assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
-    }
-*/
+
+    /**
+     * @Test public void testBindNotification_SetsTextChannelName() {
+     * mNotificationInfo.bindNotification(
+     * -1,
+     * mShortcutManager,
+     * mLauncherApps,
+     * mMockPackageManager,
+     * mMockINotificationManager,
+     * mOnUserInteractionCallback,
+     * TEST_PACKAGE_NAME,
+     * mNotificationChannel,
+     * mEntry,
+     * mBubbleMetadata,
+     * null,
+     * null,
+     * null,
+     * true);
+     * final TextView textView = mNotificationInfo.findViewById(R.id.parent_channel_name);
+     * assertTrue(textView.getText().toString().contains(mNotificationChannel.getName()));
+     * assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
+     * }
+     */
     @Test
     public void testBindNotification_SetsTextGroupName() throws Exception {
         NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
         when(mMockINotificationManager.getNotificationChannelGroupForPackage(
-               anyString(), anyString(), anyInt())).thenReturn(group);
+                anyString(), anyString(), anyInt())).thenReturn(group);
         mNotificationChannel.setGroup(group.getId());
         mConversationChannel.setGroup(group.getId());
 
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
         final TextView textView = mNotificationInfo.findViewById(R.id.group_name);
         assertTrue(textView.getText().toString().contains(group.getName()));
         assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
@@ -343,24 +332,7 @@
 
     @Test
     public void testBindNotification_GroupNameHiddenIfNoGroup() {
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
         final TextView textView = mNotificationInfo.findViewById(R.id.group_name);
         assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
         assertEquals(GONE, textView.getVisibility());
@@ -368,24 +340,7 @@
 
     @Test
     public void testBindNotification_noDelegate() {
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
         final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
         assertEquals(GONE, nameView.getVisibility());
     }
@@ -416,6 +371,7 @@
                 entry,
                 mBubbleMetadata,
                 null,
+                null,
                 mIconFactory,
                 mContext,
                 true,
@@ -428,6 +384,56 @@
     }
 
     @Test
+    @DisableFlags({Flags.FLAG_NM_SUMMARIZATION, Flags.FLAG_NM_SUMMARIZATION_UI})
+    public void testBindNotification_HidesFeedbackLink_flagOff() {
+        doStandardBind();
+        assertEquals(GONE, mNotificationInfo.findViewById(R.id.feedback).getVisibility());
+    }
+
+    @Test
+    @EnableFlags({Flags.FLAG_NM_SUMMARIZATION, Flags.FLAG_NM_SUMMARIZATION_UI})
+    public void testBindNotification_SetsFeedbackLink_ifSummaryInRanking() {
+        mEntry.setRanking(new RankingBuilder(mEntry.getRanking())
+                .setSummarization("something").build());
+        final CountDownLatch latch = new CountDownLatch(1);
+        mNotificationInfo.bindNotification(
+                mShortcutManager,
+                mMockPackageManager,
+                mUserManager,
+                mPeopleSpaceWidgetManager,
+                mMockINotificationManager,
+                mOnUserInteractionCallback,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mEntry,
+                mBubbleMetadata,
+                null,
+                (View v, Intent intent) -> {
+                    latch.countDown();
+                },
+                mIconFactory,
+                mContext,
+                true,
+                mTestHandler,
+                mTestHandler, null, Optional.of(mBubblesManager),
+                mShadeController);
+
+        final View feedback = mNotificationInfo.findViewById(R.id.feedback);
+        assertEquals(VISIBLE, feedback.getVisibility());
+        feedback.performClick();
+        // Verify that listener was triggered.
+        assertEquals(0, latch.getCount());
+    }
+
+    @Test
+    @EnableFlags({Flags.FLAG_NM_SUMMARIZATION, Flags.FLAG_NM_SUMMARIZATION_UI})
+    public void testBindNotification_hidesFeedbackLink_ifSummaryNotInRanking() {
+        doStandardBind();
+
+        assertEquals(GONE, mNotificationInfo.findViewById(R.id.feedback).getVisibility());
+    }
+
+    @Test
     public void testBindNotification_SetsOnClickListenerForSettings() {
         final CountDownLatch latch = new CountDownLatch(1);
         mNotificationInfo.bindNotification(
@@ -445,6 +451,7 @@
                     assertEquals(mConversationChannel, c);
                     latch.countDown();
                 },
+                null,
                 mIconFactory,
                 mContext,
                 true,
@@ -460,24 +467,7 @@
 
     @Test
     public void testBindNotification_SettingsButtonInvisibleWhenNoClickListener() {
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
         assertTrue(settingsButton.getVisibility() != View.VISIBLE);
     }
@@ -500,6 +490,7 @@
                     assertEquals(mNotificationChannel, c);
                     latch.countDown();
                 },
+                null,
                 mIconFactory,
                 mContext,
                 false,
@@ -514,24 +505,7 @@
     public void testBindNotification_silentSelected_isFave_isSilent() {
         mConversationChannel.setImportance(IMPORTANCE_LOW);
         mConversationChannel.setImportantConversation(true);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
         View view = mNotificationInfo.findViewById(R.id.silence);
         assertThat(view.isSelected()).isTrue();
     }
@@ -543,24 +517,7 @@
         mConversationChannel.setImportance(IMPORTANCE_HIGH);
         mConversationChannel.setImportantConversation(false);
         mConversationChannel.setAllowBubbles(true);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
         View view = mNotificationInfo.findViewById(R.id.default_behavior);
         assertThat(view.isSelected()).isTrue();
         assertThat(((TextView) view.findViewById(R.id.default_summary)).getText()).isEqualTo(
@@ -575,24 +532,7 @@
         mConversationChannel.setImportance(IMPORTANCE_HIGH);
         mConversationChannel.setImportantConversation(false);
         mConversationChannel.setAllowBubbles(true);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
         View view = mNotificationInfo.findViewById(R.id.default_behavior);
         assertThat(view.isSelected()).isTrue();
         assertThat(((TextView) view.findViewById(R.id.default_summary)).getText()).isEqualTo(
@@ -625,6 +565,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mIconFactory,
                 mContext,
                 true,
@@ -654,6 +595,7 @@
                 mEntry,
                 null,
                 null,
+                null,
                 mIconFactory,
                 mContext,
                 true,
@@ -678,24 +620,7 @@
         mConversationChannel.setImportance(IMPORTANCE_HIGH);
         mConversationChannel.setImportantConversation(false);
         mConversationChannel.setAllowBubbles(true);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
         assertThat(((TextView) mNotificationInfo.findViewById(R.id.priority_summary)).getText())
                 .isEqualTo(mContext.getString(
                         R.string.notification_channel_summary_priority_all));
@@ -707,24 +632,7 @@
         mConversationChannel.setImportance(IMPORTANCE_LOW);
         mConversationChannel.setImportantConversation(false);
 
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         View fave = mNotificationInfo.findViewById(R.id.priority);
         fave.performClick();
@@ -752,24 +660,7 @@
         mConversationChannel.setAllowBubbles(false);
         mConversationChannel.setImportance(IMPORTANCE_LOW);
         mConversationChannel.setImportantConversation(false);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         mNotificationInfo.findViewById(R.id.default_behavior).performClick();
         mTestableLooper.processAllMessages();
@@ -796,24 +687,7 @@
         mConversationChannel.setImportance(IMPORTANCE_DEFAULT);
         mConversationChannel.setImportantConversation(false);
 
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         View silence = mNotificationInfo.findViewById(R.id.silence);
 
@@ -841,24 +715,7 @@
         mConversationChannel.setImportance(IMPORTANCE_LOW);
         mConversationChannel.setImportantConversation(false);
 
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         View fave = mNotificationInfo.findViewById(R.id.priority);
         fave.performClick();
@@ -880,24 +737,7 @@
         mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
         mConversationChannel.setImportance(9);
 
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         View fave = mNotificationInfo.findViewById(R.id.priority);
         fave.performClick();
@@ -917,24 +757,7 @@
         mConversationChannel.setImportance(IMPORTANCE_HIGH);
         mConversationChannel.setImportantConversation(true);
 
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         View fave = mNotificationInfo.findViewById(R.id.priority);
         fave.performClick();
@@ -958,24 +781,7 @@
         mConversationChannel.setImportantConversation(false);
 
         // WHEN we indicate no selected action
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         // THEN the selected action is -1, so the selected option is "Default" priority
         assertEquals(mNotificationInfo.getSelectedAction(), -1);
@@ -990,24 +796,7 @@
 
         // WHEN we indicate the selected action should be "Favorite"
         mNotificationInfo.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         // THEN the selected action is "Favorite", so the selected option is "priority" priority
         assertEquals(mNotificationInfo.getSelectedAction(),
@@ -1020,24 +809,7 @@
         mConversationChannel.setAllowBubbles(true);
         mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
         mConversationChannel.setImportantConversation(true);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         mNotificationInfo.findViewById(R.id.default_behavior).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -1058,24 +830,7 @@
         mConversationChannel.setAllowBubbles(true);
         mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
         mConversationChannel.setImportantConversation(false);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         mNotificationInfo.findViewById(R.id.default_behavior).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -1095,24 +850,7 @@
         mConversationChannel.setImportance(9);
         mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
 
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         mNotificationInfo.findViewById(R.id.default_behavior).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -1131,24 +869,7 @@
         mConversationChannel.setImportantConversation(true);
         mConversationChannel.setAllowBubbles(true);
 
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         View silence = mNotificationInfo.findViewById(R.id.silence);
         silence.performClick();
@@ -1171,24 +892,7 @@
         mConversationChannel.setImportantConversation(true);
         mConversationChannel.setAllowBubbles(true);
 
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         mNotificationInfo.findViewById(R.id.silence).performClick();
         mNotificationInfo.handleCloseControls(false, false);
@@ -1202,24 +906,7 @@
 
     @Test
     public void testBindNotification_createsNewChannel() throws Exception {
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         verify(mMockINotificationManager, times(1)).createConversationNotificationChannelForPackage(
                 anyString(), anyInt(), any(), eq(CONVERSATION_ID));
@@ -1228,24 +915,7 @@
     @Test
     public void testBindNotification_doesNotCreateNewChannelIfExists() throws Exception {
         mNotificationChannel.setConversationId("", CONVERSATION_ID);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         verify(mMockINotificationManager, never()).createConversationNotificationChannelForPackage(
                 anyString(), anyInt(), any(), eq(CONVERSATION_ID));
@@ -1256,24 +926,7 @@
         when(mUserManager.isSameProfileGroup(anyInt(), anyInt())).thenReturn(true);
         //WHEN channel is default importance
         mNotificationChannel.setImportantConversation(false);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         // WHEN user clicks "priority"
         mNotificationInfo.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE);
@@ -1290,24 +943,7 @@
         when(mUserManager.isSameProfileGroup(anyInt(), anyInt())).thenReturn(false);
         //WHEN channel is default importance
         mNotificationChannel.setImportantConversation(false);
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         // WHEN user clicks "priority"
         mNotificationInfo.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE);
@@ -1321,24 +957,7 @@
 
     @Test
     public void testSelectDefaultDoesNotRequestPinPeopleTile() {
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         // WHEN user clicks "default"
         mNotificationInfo.setSelectedAction(NotificationConversationInfo.ACTION_DEFAULT);
@@ -1356,24 +975,7 @@
         mConversationChannel.setImportance(IMPORTANCE_HIGH);
         mConversationChannel.setImportantConversation(true);
 
-        mNotificationInfo.bindNotification(
-                mShortcutManager,
-                mMockPackageManager,
-                mUserManager,
-                mPeopleSpaceWidgetManager,
-                mMockINotificationManager,
-                mOnUserInteractionCallback,
-                TEST_PACKAGE_NAME,
-                mNotificationChannel,
-                mEntry,
-                mBubbleMetadata,
-                null,
-                mIconFactory,
-                mContext,
-                true,
-                mTestHandler,
-                mTestHandler, null, Optional.of(mBubblesManager),
-                mShadeController);
+        doStandardBind();
 
         // WHEN user clicks "priority"
         mNotificationInfo.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
index 8645a40..1b44752 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
@@ -75,7 +75,6 @@
 import com.android.systemui.wmshell.BubblesManager
 import java.util.Optional
 import kotlin.test.assertEquals
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runCurrent
 import org.junit.Assert
@@ -98,7 +97,6 @@
 import org.mockito.kotlin.whenever
 
 /** Tests for [NotificationGutsManager] with the scene container enabled. */
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper
@@ -438,6 +436,7 @@
                 eq(entry),
                 any<NotificationInfo.OnSettingsClickListener>(),
                 any<NotificationInfo.OnAppSettingsClickListener>(),
+                any<NotificationInfo.OnFeedbackClickListener>(),
                 any<UiEventLogger>(),
                 eq(true),
                 eq(false),
@@ -471,6 +470,7 @@
                 eq(entry),
                 any<NotificationInfo.OnSettingsClickListener>(),
                 any<NotificationInfo.OnAppSettingsClickListener>(),
+                any<NotificationInfo.OnFeedbackClickListener>(),
                 any<UiEventLogger>(),
                 eq(true),
                 eq(false),
@@ -504,6 +504,7 @@
                 eq(entry),
                 any<NotificationInfo.OnSettingsClickListener>(),
                 any<NotificationInfo.OnAppSettingsClickListener>(),
+                any<NotificationInfo.OnFeedbackClickListener>(),
                 any<UiEventLogger>(),
                 eq(true),
                 eq(false),
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 a7fe1ba..08409ab 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
@@ -46,7 +46,6 @@
 import android.content.Context;
 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;
@@ -78,7 +77,7 @@
 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.domain.interactor.ShadeModeInteractor;
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
 import com.android.systemui.shade.transition.LinearLargeScreenShadeInterpolator;
 import com.android.systemui.statusbar.policy.FakeConfigurationController;
@@ -156,6 +155,7 @@
     private final FakeKeyguardTransitionRepository mKeyguardTransitionRepository =
             mKosmos.getKeyguardTransitionRepository();
     @Mock private KeyguardInteractor mKeyguardInteractor;
+    @Mock private ShadeModeInteractor mShadeModeInteractor;
 
     // TODO(b/204991468): Use a real PanelExpansionStateManager object once this bug is fixed. (The
     //   event-dispatch-on-registration pattern caused some of these unit tests to fail.)
@@ -272,6 +272,8 @@
         when(mAlternateBouncerToGoneTransitionViewModel.getScrimAlpha())
                 .thenReturn(emptyFlow());
 
+        when(mShadeModeInteractor.isDualShade()).thenReturn(false);
+
         mScrimController = new ScrimController(
                 mLightBarController,
                 mDozeParameters,
@@ -290,6 +292,7 @@
                 mAlternateBouncerToGoneTransitionViewModel,
                 mKeyguardTransitionInteractor,
                 mKeyguardInteractor,
+                mShadeModeInteractor,
                 mKosmos.getTestDispatcher(),
                 mLinearLargeScreenShadeInterpolator,
                 new BlurConfig(0.0f, 0.0f));
@@ -356,8 +359,8 @@
 
     @Test
     @EnableSceneContainer
-    @DisableFlags(DualShade.FLAG_NAME)
     public void transitionToShadeLocked_sceneContainer_dualShadeOff() {
+        when(mShadeModeInteractor.isDualShade()).thenReturn(false);
         mScrimController.transitionTo(SHADE_LOCKED);
         mScrimController.setQsPosition(1f, 0);
         finishAnimationsImmediately();
@@ -376,8 +379,8 @@
 
     @Test
     @EnableSceneContainer
-    @EnableFlags(DualShade.FLAG_NAME)
     public void transitionToShadeLocked_sceneContainer_dualShadeOn() {
+        when(mShadeModeInteractor.isDualShade()).thenReturn(true);
         mScrimController.transitionTo(SHADE_LOCKED);
         mScrimController.setQsPosition(1f, 0);
         finishAnimationsImmediately();
@@ -956,8 +959,8 @@
 
     @Test
     @EnableSceneContainer
-    @DisableFlags(DualShade.FLAG_NAME)
     public void transitionToUnlocked_sceneContainer_dualShadeOff() {
+        when(mShadeModeInteractor.isDualShade()).thenReturn(false);
         mScrimController.setRawPanelExpansionFraction(0f);
         mScrimController.transitionTo(ScrimState.UNLOCKED);
         finishAnimationsImmediately();
@@ -985,8 +988,8 @@
 
     @Test
     @EnableSceneContainer
-    @EnableFlags(DualShade.FLAG_NAME)
     public void transitionToUnlocked_sceneContainer_dualShadeOn() {
+        when(mShadeModeInteractor.isDualShade()).thenReturn(true);
         mScrimController.setRawPanelExpansionFraction(0f);
         mScrimController.transitionTo(ScrimState.UNLOCKED);
         finishAnimationsImmediately();
@@ -1256,6 +1259,7 @@
                 mAlternateBouncerToGoneTransitionViewModel,
                 mKeyguardTransitionInteractor,
                 mKeyguardInteractor,
+                mShadeModeInteractor,
                 mKosmos.getTestDispatcher(),
                 mLinearLargeScreenShadeInterpolator,
                 new BlurConfig(0.0f, 0.0f));
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 8beed01..f4c0e36 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
@@ -29,7 +29,6 @@
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.runBlocking
@@ -39,7 +38,6 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
 @RunWith(AndroidJUnit4::class)
 class AirplaneModeViewModelImplTest : SysuiTestCase() {
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 4a2f6f2..df74404 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
@@ -25,12 +25,10 @@
 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() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryImplTest.kt
index 7d101be..d074fc2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryImplTest.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.createTestConfig
 import com.android.systemui.util.mockito.whenever
 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
@@ -45,7 +44,6 @@
 import org.mockito.MockitoSession
 import org.mockito.quality.Strictness
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class CarrierConfigRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
index 36f5236..d055905 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
@@ -50,7 +50,6 @@
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.launchIn
@@ -70,7 +69,6 @@
  * switches over when the value of `demoMode` changes
  */
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MobileRepositorySwitcherTest : SysuiTestCase() {
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 fd23655..02ad90c 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
@@ -50,7 +50,6 @@
 import com.google.common.truth.Truth.assertThat
 import java.io.PrintWriter
 import java.io.StringWriter
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
@@ -69,7 +68,6 @@
  * properly switches over when the value of `isCarrierMerged` changes.
  */
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FullMobileConnectionRepositoryTest : SysuiTestCase() {
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 3a25ecb..df5c6e9 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
@@ -98,7 +98,6 @@
 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.flow.MutableStateFlow
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
@@ -115,7 +114,6 @@
 import org.mockito.kotlin.argumentCaptor
 
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MobileConnectionRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt
index 0d82c79..ec260fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt
@@ -49,7 +49,6 @@
 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.StateFlow
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
@@ -92,7 +91,6 @@
  * 5. Assert that B has the state sent in step #2
  */
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 class MobileConnectionTelephonySmokeTests : SysuiTestCase() {
     private lateinit var underTest: MobileConnectionRepositoryImpl
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
index 6c60f55..d1d6e27 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
@@ -79,7 +79,6 @@
 import com.android.wifitrackerlib.WifiPickerTracker
 import com.google.common.truth.Truth.assertThat
 import java.util.UUID
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
@@ -101,7 +100,6 @@
 import org.mockito.kotlin.whenever
 
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 // This is required because our [SubscriptionManager.OnSubscriptionsChangedListener] uses a looper
 // to run the callback and this makes the looper place nicely with TestScope etc.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt
index 84846a1..ce99e59 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt
@@ -44,7 +44,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
@@ -57,7 +56,6 @@
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 @RunWithLooper(setAsMainLooper = true)
-@OptIn(ExperimentalCoroutinesApi::class)
 class ModernStatusBarMobileViewTest : SysuiTestCase() {
     private val kosmos = testKosmos()
 
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 599729d..6a8b783 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
@@ -53,7 +53,6 @@
 import java.util.Optional
 import java.util.function.Consumer
 import kotlin.test.Test
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -71,7 +70,6 @@
 import org.mockito.kotlin.doThrow
 
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DeviceBasedSatelliteRepositoryImplTest : SysuiTestCase() {
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 88f262b..8a0159c 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
@@ -47,7 +47,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.tuner.TunerService
 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
@@ -60,7 +59,6 @@
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
-@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ConnectivityRepositoryImplTest : SysuiTestCase() {
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 3007eab..8d05ea1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.volume;
 
+import java.util.List;
 import static android.media.AudioManager.RINGER_MODE_NORMAL;
 import static android.media.AudioManager.RINGER_MODE_SILENT;
 import static android.media.AudioManager.RINGER_MODE_VIBRATE;
@@ -93,7 +94,6 @@
 import com.android.systemui.volume.ui.navigation.VolumeNavigator;
 
 import com.google.android.msdl.domain.MSDLPlayer;
-import com.google.common.collect.ImmutableList;
 
 import dagger.Lazy;
 
@@ -163,7 +163,7 @@
             new CsdWarningDialog.Factory() {
                 @Override
                 public CsdWarningDialog create(int warningType, Runnable onCleanup,
-                        Optional<ImmutableList<CsdWarningAction>> actionIntents) {
+                        Optional<List<CsdWarningAction>> actionIntents) {
                     return mCsdWarningDialog;
                 }
             };
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 5d88f72..bf10dc6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -26,8 +26,6 @@
 import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
 import static android.service.notification.NotificationListenerService.REASON_PACKAGE_BANNED;
 
-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;
@@ -175,6 +173,7 @@
 import com.android.wm.shell.bubbles.BubbleEntry;
 import com.android.wm.shell.bubbles.BubbleLogger;
 import com.android.wm.shell.bubbles.BubbleOverflow;
+import com.android.wm.shell.bubbles.BubbleResizabilityChecker;
 import com.android.wm.shell.bubbles.BubbleStackView;
 import com.android.wm.shell.bubbles.BubbleTaskView;
 import com.android.wm.shell.bubbles.BubbleViewInfoTask;
@@ -182,7 +181,6 @@
 import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.bubbles.StackEducationView;
 import com.android.wm.shell.bubbles.bar.BubbleBarLayerView;
-import com.android.wm.shell.bubbles.properties.BubbleProperties;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayImeController;
 import com.android.wm.shell.common.DisplayInsetsController;
@@ -297,7 +295,7 @@
     private BubbleEntry mBubbleEntryUser11;
     private BubbleEntry mBubbleEntry2User11;
 
-    private Intent mAppBubbleIntent;
+    private Intent mNotesBubbleIntent;
 
     @Mock
     private ShellInit mShellInit;
@@ -354,7 +352,7 @@
     @Mock
     private NotifPipelineFlags mNotifPipelineFlags;
     @Mock
-    private Icon mAppBubbleIcon;
+    private Icon mNotesBubbleIcon;
     @Mock
     private Display mDefaultDisplay;
     @Mock
@@ -380,8 +378,6 @@
 
     private UserHandle mUser0;
 
-    private FakeBubbleProperties mBubbleProperties;
-
     @Parameters(name = "{0}")
     public static List<FlagsParameterization> getParams() {
         return SceneContainerFlagParameterizationKt.parameterizeSceneContainerFlag();
@@ -457,8 +453,8 @@
         mNotificationShadeWindowController.fetchWindowRootView();
         mNotificationShadeWindowController.attach();
 
-        mAppBubbleIntent = new Intent(mContext, BubblesTestActivity.class);
-        mAppBubbleIntent.setPackage(mContext.getPackageName());
+        mNotesBubbleIntent = new Intent(mContext, BubblesTestActivity.class);
+        mNotesBubbleIntent.setPackage(mContext.getPackageName());
 
         mZenModeConfig.suppressedVisualEffects = 0;
         when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
@@ -522,7 +518,6 @@
         mTaskViewRepository = new TaskViewRepository();
         mTaskViewTransitions = new TaskViewTransitions(mTransitions, mTaskViewRepository,
                 mShellTaskOrganizer, mSyncQueue);
-        mBubbleProperties = new FakeBubbleProperties();
         mBubbleController = new TestableBubbleController(
                 mContext,
                 mShellInit,
@@ -551,7 +546,7 @@
                 mTransitions,
                 mock(SyncTransactionQueue.class),
                 mock(IWindowManager.class),
-                mBubbleProperties);
+                new BubbleResizabilityChecker());
         mBubbleController.setExpandListener(mBubbleExpandListener);
         spyOn(mBubbleController);
 
@@ -1478,8 +1473,8 @@
     }
 
     @Test
-    public void testShowManageMenuChangesSysuiState_appBubble() {
-        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
+    public void testShowManageMenuChangesSysuiState_notesBubble() {
+        mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, mUser0, mNotesBubbleIcon);
         assertTrue(mBubbleController.hasBubbles());
 
         // Expand the stack
@@ -1979,79 +1974,80 @@
     }
 
     @Test
-    public void testShowOrHideAppBubble_addsAndExpand() {
+    public void testShowOrHideNotesBubble_addsAndExpand() {
         assertThat(mBubbleController.isStackExpanded()).isFalse();
 
-        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
+        mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, mUser0, mNotesBubbleIcon);
 
         verify(mBubbleController).inflateAndAdd(any(Bubble.class), /* suppressFlyout= */ eq(true),
                 /* showInShade= */ eq(false));
         assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(
-                Bubble.getAppBubbleKeyForApp(mContext.getPackageName(), mUser0));
+                Bubble.getNoteBubbleKeyForApp(mContext.getPackageName(), mUser0));
         assertThat(mBubbleController.isStackExpanded()).isTrue();
     }
 
     @Test
-    public void testShowOrHideAppBubble_expandIfCollapsed() {
-        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
+    public void testShowOrHideNotesBubble_expandIfCollapsed() {
+        mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, mUser0, mNotesBubbleIcon);
         mBubbleController.updateBubble(mBubbleEntry);
         mBubbleController.collapseStack();
         assertThat(mBubbleController.isStackExpanded()).isFalse();
 
         // Calling this while collapsed will expand the app bubble
-        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
+        mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, mUser0, mNotesBubbleIcon);
 
         assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(
-                Bubble.getAppBubbleKeyForApp(mContext.getPackageName(), mUser0));
+                Bubble.getNoteBubbleKeyForApp(mContext.getPackageName(), mUser0));
         assertThat(mBubbleController.isStackExpanded()).isTrue();
         assertThat(mBubbleData.getBubbles().size()).isEqualTo(2);
     }
 
     @Test
-    public void testShowOrHideAppBubble_collapseIfSelected() {
-        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
+    public void testShowOrHideNotesBubble_collapseIfSelected() {
+        mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, mUser0, mNotesBubbleIcon);
         assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(
-                Bubble.getAppBubbleKeyForApp(mContext.getPackageName(), mUser0));
+                Bubble.getNoteBubbleKeyForApp(mContext.getPackageName(), mUser0));
         assertThat(mBubbleController.isStackExpanded()).isTrue();
 
         // Calling this while the app bubble is expanded should collapse the stack
-        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
+        mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, mUser0, mNotesBubbleIcon);
 
         assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(
-                Bubble.getAppBubbleKeyForApp(mContext.getPackageName(), mUser0));
+                Bubble.getNoteBubbleKeyForApp(mContext.getPackageName(), mUser0));
         assertThat(mBubbleController.isStackExpanded()).isFalse();
         assertThat(mBubbleData.getBubbles().size()).isEqualTo(1);
         assertThat(mBubbleData.getBubbles().get(0).getUser()).isEqualTo(mUser0);
     }
 
     @Test
-    public void testShowOrHideAppBubbleWithNonPrimaryUser_bubbleCollapsedWithExpectedUser() {
+    public void testShowOrHideNotesBubbleWithNonPrimaryUser_bubbleCollapsedWithExpectedUser() {
         UserHandle user10 = createUserHandle(/* userId = */ 10);
-        String appBubbleKey = Bubble.getAppBubbleKeyForApp(mContext.getPackageName(), user10);
-        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, user10, mAppBubbleIcon);
-        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(appBubbleKey);
+        String notesKey = Bubble.getNoteBubbleKeyForApp(mContext.getPackageName(), user10);
+        mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, user10, mNotesBubbleIcon);
+        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(notesKey);
         assertThat(mBubbleController.isStackExpanded()).isTrue();
         assertThat(mBubbleData.getBubbles().size()).isEqualTo(1);
         assertThat(mBubbleData.getBubbles().get(0).getUser()).isEqualTo(user10);
 
         // Calling this while the app bubble is expanded should collapse the stack
-        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, user10, mAppBubbleIcon);
+        mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, user10, mNotesBubbleIcon);
 
-        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(appBubbleKey);
+        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(notesKey);
         assertThat(mBubbleController.isStackExpanded()).isFalse();
         assertThat(mBubbleData.getBubbles().size()).isEqualTo(1);
         assertThat(mBubbleData.getBubbles().get(0).getUser()).isEqualTo(user10);
     }
 
     @Test
-    public void testShowOrHideAppBubbleOnUser10AndThenUser0_user0BubbleExpanded() {
+    public void testShowOrHideNotesBubbleOnUser10AndThenUser0_user0BubbleExpanded() {
         UserHandle user10 = createUserHandle(/* userId = */ 10);
-        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, user10, mAppBubbleIcon);
+        mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, user10, mNotesBubbleIcon);
 
-        String appBubbleUser0Key = Bubble.getAppBubbleKeyForApp(mContext.getPackageName(), mUser0);
-        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
+        String notesBubbleUser0Key = Bubble.getNoteBubbleKeyForApp(mContext.getPackageName(),
+                mUser0);
+        mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, mUser0, mNotesBubbleIcon);
 
-        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(appBubbleUser0Key);
+        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(notesBubbleUser0Key);
         assertThat(mBubbleController.isStackExpanded()).isTrue();
         assertThat(mBubbleData.getBubbles()).hasSize(2);
         assertThat(mBubbleData.getBubbles().get(0).getUser()).isEqualTo(mUser0);
@@ -2059,63 +2055,64 @@
     }
 
     @Test
-    public void testShowOrHideAppBubble_selectIfNotSelected() {
-        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
+    public void testShowOrHideNotesBubble_selectIfNotSelected() {
+        mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, mUser0, mNotesBubbleIcon);
         mBubbleController.updateBubble(mBubbleEntry);
         mBubbleController.expandStackAndSelectBubble(mBubbleEntry);
         assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(mBubbleEntry.getKey());
         assertThat(mBubbleController.isStackExpanded()).isTrue();
 
-        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
+        mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, mUser0, mNotesBubbleIcon);
         assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(
-                Bubble.getAppBubbleKeyForApp(mContext.getPackageName(), mUser0));
+                Bubble.getNoteBubbleKeyForApp(mContext.getPackageName(), mUser0));
         assertThat(mBubbleController.isStackExpanded()).isTrue();
         assertThat(mBubbleData.getBubbles().size()).isEqualTo(2);
     }
 
     @Test
-    public void testShowOrHideAppBubble_addsFromOverflow() {
-        String appBubbleKey = Bubble.getAppBubbleKeyForApp(mAppBubbleIntent.getPackage(), mUser0);
-        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
-
+    public void testShowOrHideNotesBubble_addsFromOverflow() {
+        String noteBubbleKey = Bubble.getNoteBubbleKeyForApp(mNotesBubbleIntent.getPackage(),
+                mUser0);
+        mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, mUser0, mNotesBubbleIcon);
         // 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();
+        mBubbleController.dismissBubble(noteBubbleKey, Bubbles.DISMISS_USER_GESTURE);
+        assertThat(mBubbleData.getOverflowBubbleWithKey(noteBubbleKey)).isNotNull();
 
         // Calling this while collapsed will re-add and expand the app bubble
-        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
-        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(appBubbleKey);
+        mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, mUser0, mNotesBubbleIcon);
+        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(noteBubbleKey);
         assertThat(mBubbleController.isStackExpanded()).isTrue();
         assertThat(mBubbleData.getBubbles().size()).isEqualTo(1);
-        assertThat(mBubbleData.getOverflowBubbleWithKey(appBubbleKey)).isNull();
+        assertThat(mBubbleData.getOverflowBubbleWithKey(noteBubbleKey)).isNull();
     }
 
     @Test
-    public void testShowOrHideAppBubble_updateExistedBubbleInOverflow_updateIntentInBubble() {
-        String appBubbleKey = Bubble.getAppBubbleKeyForApp(mAppBubbleIntent.getPackage(), mUser0);
-        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
+    public void testShowOrHideNotesBubble_updateExistedBubbleInOverflow_updateIntentInBubble() {
+        String noteBubbleKey = Bubble.getNoteBubbleKeyForApp(mNotesBubbleIntent.getPackage(),
+                mUser0);
+        mBubbleController.showOrHideNotesBubble(mNotesBubbleIntent, mUser0, mNotesBubbleIcon);
         // 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();
+        mBubbleController.dismissBubble(noteBubbleKey, Bubbles.DISMISS_USER_GESTURE);
+        assertThat(mBubbleData.getOverflowBubbleWithKey(noteBubbleKey)).isNotNull();
 
         // Modify the intent to include new extras.
-        Intent newAppBubbleIntent = new Intent(mContext, BubblesTestActivity.class)
+        Intent newIntent = 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);
+        mBubbleController.showOrHideNotesBubble(newIntent, mUser0, mNotesBubbleIcon);
+        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(noteBubbleKey);
         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();
+        assertThat(mBubbleData.getBubbles().get(0).getIntent()
+                .getStringExtra("hello")).isEqualTo("world");
+        assertThat(mBubbleData.getOverflowBubbleWithKey(noteBubbleKey)).isNull();
     }
 
     @Test
@@ -2143,9 +2140,9 @@
         assertFalse("FLAG_NO_DISMISS Notifs should be non-dismissable", bubble.isDismissable());
     }
 
+    @DisableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void registerBubbleBarListener_barDisabled_largeScreen_shouldBeIgnored() {
-        mBubbleProperties.mIsBubbleBarEnabled = false;
         mPositioner.setIsLargeScreen(true);
         mEntryListener.onEntryAdded(mRow);
         mBubbleController.updateBubble(mBubbleEntry);
@@ -2161,9 +2158,9 @@
         assertThat(mBubbleController.getStackView().getBubbleCount()).isEqualTo(1);
     }
 
+    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void registerBubbleBarListener_barEnabled_smallScreen_shouldBeIgnored() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(false);
         mEntryListener.onEntryAdded(mRow);
         mBubbleController.updateBubble(mBubbleEntry);
@@ -2179,9 +2176,9 @@
         assertThat(mBubbleController.getStackView().getBubbleCount()).isEqualTo(1);
     }
 
+    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void registerBubbleBarListener_switchToBarAndBackToStack() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
         mEntryListener.onEntryAdded(mRow);
         mBubbleController.updateBubble(mBubbleEntry);
@@ -2211,9 +2208,9 @@
         assertBubbleIsInflatedForStack(mBubbleData.getOverflow());
     }
 
+    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void registerBubbleBarListener_switchToBarWhileExpanded() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
 
         mEntryListener.onEntryAdded(mRow);
@@ -2238,9 +2235,9 @@
         assertThat(layerView.isExpanded()).isTrue();
     }
 
+    @DisableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void switchBetweenBarAndStack_noBubbles_shouldBeIgnored() {
-        mBubbleProperties.mIsBubbleBarEnabled = false;
         mPositioner.setIsLargeScreen(true);
         assertFalse(mBubbleController.hasBubbles());
 
@@ -2256,9 +2253,9 @@
         assertNoBubbleContainerViews();
     }
 
+    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void bubbleBarBubbleExpandedAndCollapsed() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
         mEntryListener.onEntryAdded(mRow);
         mBubbleController.updateBubble(mBubbleEntry);
@@ -2277,7 +2274,6 @@
     @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void dragBubbleBarBubble_selectedBubble_expandedViewCollapsesDuringDrag() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
         mBubbleController.registerBubbleStateListener(bubbleStateListener);
@@ -2306,7 +2302,6 @@
     @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void dragBubbleBarBubble_unselectedBubble_expandedViewCollapsesDuringDrag() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
         mBubbleController.registerBubbleStateListener(bubbleStateListener);
@@ -2335,7 +2330,6 @@
     @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void dismissBubbleBarBubble_selected_selectsAndExpandsNext() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
         mBubbleController.registerBubbleStateListener(bubbleStateListener);
@@ -2359,7 +2353,6 @@
     @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void dismissBubbleBarBubble_unselected_selectionDoesNotChange() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
         mBubbleController.registerBubbleStateListener(bubbleStateListener);
@@ -2407,9 +2400,9 @@
         verify(mBubbleController).onSensitiveNotificationProtectionStateChanged(false);
     }
 
+    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void setBubbleBarLocation_listenerNotified() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
 
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
@@ -2421,9 +2414,9 @@
                 BubbleBarLocation.LEFT);
     }
 
+    @DisableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void setBubbleBarLocation_barDisabled_shouldBeIgnored() {
-        mBubbleProperties.mIsBubbleBarEnabled = false;
         mPositioner.setIsLargeScreen(true);
 
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
@@ -2496,7 +2489,6 @@
     @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void testEventLogging_bubbleBar_addBubble() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
         mBubbleController.registerBubbleStateListener(bubbleStateListener);
@@ -2510,7 +2502,6 @@
     @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void testEventLogging_bubbleBar_updateBubble() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
         mBubbleController.registerBubbleStateListener(bubbleStateListener);
@@ -2527,7 +2518,6 @@
     @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void testEventLogging_bubbleBar_dragSelectedBubbleToDismiss() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
         mBubbleController.registerBubbleStateListener(bubbleStateListener);
@@ -2554,7 +2544,6 @@
     @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void testEventLogging_bubbleBar_dragOtherBubbleToDismiss() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
         mBubbleController.registerBubbleStateListener(bubbleStateListener);
@@ -2579,7 +2568,6 @@
     @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void testEventLogging_bubbleBar_dragBarToDismiss() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
 
         // Not a user gesture, should not log an event
@@ -2594,7 +2582,6 @@
     @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void testEventLogging_bubbleBar_expandAndCollapse() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
         mBubbleController.registerBubbleStateListener(bubbleStateListener);
@@ -2614,7 +2601,6 @@
     @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void testEventLogging_bubbleBar_autoExpandingBubble() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
         mBubbleController.registerBubbleStateListener(bubbleStateListener);
@@ -2630,7 +2616,6 @@
     @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void testEventLogging_bubbleBar_switchBubble() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
         mBubbleController.registerBubbleStateListener(bubbleStateListener);
@@ -2656,7 +2641,6 @@
     @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void testEventLogging_bubbleBar_openOverflow() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
         mBubbleController.registerBubbleStateListener(bubbleStateListener);
@@ -2672,7 +2656,6 @@
     @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
     @Test
     public void testEventLogging_bubbleBar_fromOverflowToBar() {
-        mBubbleProperties.mIsBubbleBarEnabled = true;
         mPositioner.setIsLargeScreen(true);
         FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
         mBubbleController.registerBubbleStateListener(bubbleStateListener);
@@ -2902,16 +2885,4 @@
         @Override
         public void onItemDraggedOutsideBubbleBarDropZone() {}
     }
-
-    private static class FakeBubbleProperties implements BubbleProperties {
-        boolean mIsBubbleBarEnabled = false;
-
-        @Override
-        public boolean isBubbleBarEnabled() {
-            return mIsBubbleBarEnabled;
-        }
-
-        @Override
-        public void refresh() {}
-    }
 }
diff --git a/packages/SystemUI/tests/utils/src/android/view/WindowManagerKosmos.kt b/packages/SystemUI/tests/utils/src/android/view/WindowManagerKosmos.kt
index 025f556..80254d5 100644
--- a/packages/SystemUI/tests/utils/src/android/view/WindowManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/android/view/WindowManagerKosmos.kt
@@ -24,4 +24,6 @@
 
 val Kosmos.mockWindowManager: WindowManager by Kosmos.Fixture { mock(WindowManager::class.java) }
 
+val Kosmos.mockIWindowManager: IWindowManager by Kosmos.Fixture { mock(IWindowManager::class.java) }
+
 var Kosmos.windowManager: WindowManager by Kosmos.Fixture { mockWindowManager }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt
index 35e85bb..b6f8ec6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt
@@ -19,6 +19,7 @@
 import com.android.systemui.brightness.domain.interactor.brightnessPolicyEnforcementInteractor
 import com.android.systemui.brightness.domain.interactor.screenBrightnessInteractor
 import com.android.systemui.classifier.domain.interactor.falsingInteractor
+import com.android.systemui.graphics.imageLoader
 import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.settings.brightness.domain.interactor.brightnessMirrorShowingInteractor
@@ -36,6 +37,7 @@
                     supportsMirroring = allowsMirroring,
                     falsingInteractor = falsingInteractor,
                     brightnessWarningToast = brightnessWarningToast,
+                    imageLoader = imageLoader,
                 )
             }
         }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt
index b3c1411..3f35bb9 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt
@@ -17,8 +17,7 @@
 /** Fake implementation of [CommunalSceneRepository]. */
 class FakeCommunalSceneRepository(
     private val applicationScope: CoroutineScope,
-    override val currentScene: MutableStateFlow<SceneKey> =
-        MutableStateFlow(CommunalScenes.Default),
+    override val currentScene: MutableStateFlow<SceneKey> = MutableStateFlow(CommunalScenes.Default),
 ) : CommunalSceneRepository {
 
     override fun changeScene(toScene: SceneKey, transitionKey: TransitionKey?) =
@@ -31,6 +30,10 @@
         }
     }
 
+    override suspend fun showHubFromPowerButton() {
+        snapToScene(CommunalScenes.Communal)
+    }
+
     private val defaultTransitionState = ObservableTransitionState.Idle(CommunalScenes.Default)
     private val _transitionState = MutableStateFlow<Flow<ObservableTransitionState>?>(null)
     override val transitionState: StateFlow<ObservableTransitionState> =
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModelKosmos.kt
index 1c84133..f737772 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalUserActionsViewModelKosmos.kt
@@ -20,10 +20,12 @@
 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.domain.interactor.shadeModeInteractor
 
 val Kosmos.communalUserActionsViewModel by Fixture {
     CommunalUserActionsViewModel(
         deviceUnlockedInteractor = deviceUnlockedInteractor,
         shadeInteractor = shadeInteractor,
+        shadeModeInteractor = shadeModeInteractor,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt
index 71746b5..2e59788 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt
@@ -20,6 +20,7 @@
 import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
 
 val Kosmos.dreamUserActionsViewModel by
     Kosmos.Fixture {
@@ -27,5 +28,6 @@
             communalInteractor = communalInteractor,
             deviceUnlockedInteractor = deviceUnlockedInteractor,
             shadeInteractor = shadeInteractor,
+            shadeModeInteractor = shadeModeInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/quickaffordance/LocalUserSelectionManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/quickaffordance/LocalUserSelectionManagerKosmos.kt
index 328338b..21d1a76 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/quickaffordance/LocalUserSelectionManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/quickaffordance/LocalUserSelectionManagerKosmos.kt
@@ -18,7 +18,6 @@
 
 import android.content.applicationContext
 import com.android.systemui.broadcast.broadcastDispatcher
-import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.settings.userFileManager
 import com.android.systemui.settings.userTracker
@@ -29,7 +28,6 @@
             context = applicationContext,
             userFileManager = userFileManager,
             userTracker = userTracker,
-            communalSettingsInteractor = communalSettingsInteractor,
             broadcastDispatcher = broadcastDispatcher,
         )
     }
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 8ea80081..1952f26 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
@@ -114,6 +114,7 @@
     override val keyguardAlpha: StateFlow<Float> = _keyguardAlpha
 
     override val panelAlpha: MutableStateFlow<Float> = MutableStateFlow(1f)
+    override val zoomOut: MutableStateFlow<Float> = MutableStateFlow(0f)
 
     override val lastRootViewTapPosition: MutableStateFlow<Point?> = MutableStateFlow(null)
 
@@ -272,6 +273,10 @@
         panelAlpha.value = alpha
     }
 
+    override fun setZoomOut(zoomOutFromShadeRadius: Float) {
+        zoomOut.value = zoomOutFromShadeRadius
+    }
+
     fun setIsEncryptedOrLockdown(value: Boolean) {
         _isEncryptedOrLockdown.value = value
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt
index ef9bd82..5793695 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt
@@ -62,6 +62,7 @@
             defaultSettingsPopupMenuSection = mock(),
             defaultStatusBarSection = mock(),
             defaultNotificationStackScrollLayoutSection = mock(),
+            aodPromotedNotificationSection = mock(),
             aodNotificationIconsSection = mock(),
             aodBurnInSection = mock(),
             clockSection = keyguardClockSection,
@@ -69,7 +70,6 @@
             keyguardSliceViewSection = mock(),
             udfpsAccessibilityOverlaySection = mock(),
             accessibilityActionsSection = mock(),
-            aodPromotedNotificationSection = mock(),
         )
     }
 
@@ -84,6 +84,7 @@
             defaultStatusBarSection = mock(),
             splitShadeNotificationStackScrollLayoutSection = mock(),
             splitShadeGuidelines = mock(),
+            aodPromotedNotificationSection = mock(),
             aodNotificationIconsSection = mock(),
             aodBurnInSection = mock(),
             clockSection = keyguardClockSection,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorKosmos.kt
index ba64ed7..22e76f6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorKosmos.kt
@@ -22,7 +22,6 @@
 import com.android.internal.widget.lockPatternUtils
 import com.android.keyguard.logging.KeyguardQuickAffordancesLogger
 import com.android.systemui.animation.dialogTransitionAnimator
-import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
 import com.android.systemui.dock.dockManager
 import com.android.systemui.flags.featureFlagsClassic
 import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
@@ -54,7 +53,6 @@
         devicePolicyManager = devicePolicyManager,
         dockManager = dockManager,
         biometricSettingsRepository = biometricSettingsRepository,
-        communalSettingsInteractor = communalSettingsInteractor,
         accessibilityManager = mock<AccessibilityManager>(),
         backgroundDispatcher = testDispatcher,
         appContext = applicationContext,
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 f47b2df..78d44d4 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
@@ -20,8 +20,8 @@
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardBlueprintInteractor
 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.shade.domain.interactor.shadeInteractor
 import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor
 
@@ -34,7 +34,7 @@
             touchHandling = keyguardTouchHandlingViewModel,
             shadeInteractor = shadeInteractor,
             unfoldTransitionInteractor = unfoldTransitionInteractor,
-            occlusionInteractor = sceneContainerOcclusionInteractor,
             deviceEntryInteractor = deviceEntryInteractor,
+            transitionInteractor = keyguardTransitionInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelKosmos.kt
index 2311c0a..ec83157 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelKosmos.kt
@@ -22,12 +22,14 @@
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
 import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
 
 val Kosmos.lockscreenUserActionsViewModel by Fixture {
     LockscreenUserActionsViewModel(
         deviceEntryInteractor = deviceEntryInteractor,
         communalInteractor = communalInteractor,
         shadeInteractor = shadeInteractor,
+        shadeModeInteractor = shadeModeInteractor,
         occlusionInteractor = sceneContainerOcclusionInteractor,
     )
 }
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 35e90f0..446e106 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
@@ -178,7 +178,9 @@
     val scrimStartable by lazy { kosmos.scrimStartable }
     val sceneContainerOcclusionInteractor by lazy { kosmos.sceneContainerOcclusionInteractor }
     val msdlPlayer by lazy { kosmos.fakeMSDLPlayer }
+
     val shadeModeInteractor by lazy { kosmos.shadeModeInteractor }
+
     val bouncerHapticHelper by lazy { kosmos.bouncerHapticPlayer }
 
     val glanceableHubToLockscreenTransitionViewModel by lazy {
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 2e6d8ed..4f024d7 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
@@ -19,7 +19,6 @@
 import com.android.internal.logging.uiEventLogger
 import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
-import com.android.systemui.jank.interactionJankMonitor
 import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
@@ -37,7 +36,6 @@
     Kosmos.Fixture {
         StatusBarStateControllerImpl(
             uiEventLogger,
-            { interactionJankMonitor },
             mock(),
             { keyguardInteractor },
             { keyguardTransitionInteractor },
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/process/ProcessKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/process/ProcessKosmos.kt
index 79167f8..4d1e0a8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/process/ProcessKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/process/ProcessKosmos.kt
@@ -16,6 +16,9 @@
 
 package com.android.systemui.process
 
-import com.android.systemui.kosmos.Kosmos
+import android.app.ActivityManager
 
-val Kosmos.processWrapper: ProcessWrapperFake by Kosmos.Fixture { ProcessWrapperFake() }
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.mockito.mock
+
+val Kosmos.processWrapper: ProcessWrapperFake by Kosmos.Fixture { ProcessWrapperFake(mock<ActivityManager>()) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/process/ProcessWrapperFake.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/process/ProcessWrapperFake.kt
index dee3644..152cc30 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/process/ProcessWrapperFake.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/process/ProcessWrapperFake.kt
@@ -16,9 +16,10 @@
 
 package com.android.systemui.process
 
+import android.app.ActivityManager
 import android.os.UserHandle
 
-class ProcessWrapperFake : ProcessWrapper() {
+class ProcessWrapperFake(activityManager: ActivityManager) : ProcessWrapper(activityManager) {
 
     var systemUser: Boolean = false
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeTileDetailsContent.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeTileDetailsContent.kt
new file mode 100644
index 0000000..84a7364
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeTileDetailsContent.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF 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
+
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
+
+@Composable
+fun FakeTileDetailsContent() {
+    Text(
+        text = "Fake details content",
+        textAlign = TextAlign.Center,
+        fontWeight = FontWeight.ExtraBold,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeTileDetailsViewModel.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeTileDetailsViewModel.kt
index 555f019..4f8d5a1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeTileDetailsViewModel.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeTileDetailsViewModel.kt
@@ -16,24 +16,11 @@
 
 package com.android.systemui.qs
 
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.text.style.TextAlign
 import com.android.systemui.plugins.qs.TileDetailsViewModel
 
 class FakeTileDetailsViewModel(var tileSpec: String?) : TileDetailsViewModel() {
     private var _clickOnSettingsButton = 0
 
-    @Composable
-    override fun GetContentView() {
-        Text(
-            text = "Fake details content",
-            textAlign = TextAlign.Center,
-            fontWeight = FontWeight.ExtraBold,
-        )
-    }
-
     override fun clickOnSettingsButton() {
         _clickOnSettingsButton++
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
index 65e580c..583a9de 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
@@ -33,6 +33,7 @@
 import com.android.systemui.qs.panels.domain.interactor.tileSquishinessInteractor
 import com.android.systemui.qs.panels.ui.viewmodel.inFirstPageViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.mediaInRowInLandscapeViewModelFactory
+import com.android.systemui.qs.panels.ui.viewmodel.quickQuickSettingsViewModelFactory
 import com.android.systemui.qs.ui.viewmodel.quickSettingsContainerViewModelFactory
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.shade.largeScreenHeaderHelper
@@ -48,6 +49,7 @@
             ): QSFragmentComposeViewModel {
                 return QSFragmentComposeViewModel(
                     quickSettingsContainerViewModelFactory,
+                    quickQuickSettingsViewModelFactory,
                     mainResources,
                     footerActionsViewModelFactory,
                     footerActionsController,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/QSColumnsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/QSColumnsInteractorKosmos.kt
index 47615f5..161f72a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/QSColumnsInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/QSColumnsInteractorKosmos.kt
@@ -19,9 +19,13 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.qs.panels.data.repository.qsColumnsRepository
-import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
 
 val Kosmos.qsColumnsInteractor by
     Kosmos.Fixture {
-        QSColumnsInteractor(applicationCoroutineScope, qsColumnsRepository, shadeInteractor)
+        QSColumnsInteractor(
+            scope = applicationCoroutineScope,
+            repo = qsColumnsRepository,
+            shadeModeInteractor = shadeModeInteractor,
+        )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt
index 13cbddf..3f07d05 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.qs.tiles.impl.modes.domain.interactor
 
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.mainCoroutineContext
 import com.android.systemui.qs.tiles.base.actions.qsTileIntentUserInputHandler
 import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
 import com.android.systemui.statusbar.policy.ui.dialog.modesDialogDelegate
@@ -26,6 +27,7 @@
 val Kosmos.modesTileUserActionInteractor: ModesTileUserActionInteractor by
     Kosmos.Fixture {
         ModesTileUserActionInteractor(
+            mainCoroutineContext,
             qsTileIntentUserInputHandler,
             Provider { modesDialogDelegate }.get(),
             zenModeInteractor,
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
index f8fa5db..3fc73cb 100644
--- 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
@@ -20,9 +20,9 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.qs.panels.ui.viewmodel.detailsViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.quickQuickSettingsViewModelFactory
 import com.android.systemui.qs.panels.ui.viewmodel.tileGridViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.toolbar.toolbarViewModelFactory
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
 import com.android.systemui.shade.ui.viewmodel.shadeHeaderViewModelFactory
 
 val Kosmos.quickSettingsContainerViewModelFactory by
@@ -33,13 +33,13 @@
             ): QuickSettingsContainerViewModel {
                 return QuickSettingsContainerViewModel(
                     brightnessSliderViewModelFactory,
-                    quickQuickSettingsViewModelFactory,
                     shadeHeaderViewModelFactory,
                     supportsBrightnessMirroring,
                     tileGridViewModel,
                     editModeViewModel,
                     detailsViewModel,
                     toolbarViewModelFactory,
+                    shadeModeInteractor,
                 )
             }
         }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelKosmos.kt
index 4f3b8f3..108a20a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelKosmos.kt
@@ -19,7 +19,6 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.shade.domain.interactor.shadeInteractor
-import com.android.systemui.shade.ui.viewmodel.shadeHeaderViewModelFactory
 import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
 
 val Kosmos.quickSettingsShadeOverlayContentViewModel: QuickSettingsShadeOverlayContentViewModel by
@@ -28,7 +27,5 @@
             shadeInteractor = shadeInteractor,
             sceneInteractor = sceneInteractor,
             notificationStackAppearanceInteractor = notificationStackAppearanceInteractor,
-            shadeHeaderViewModelFactory = shadeHeaderViewModelFactory,
-            quickSettingsContainerViewModelFactory = quickSettingsContainerViewModelFactory,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt
index 609f97d..ce298bb 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneKosmos.kt
@@ -4,6 +4,7 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.systemui.classifier.domain.interactor.falsingInteractor
 import com.android.systemui.haptics.msdl.msdlPlayer
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.keyguard.ui.viewmodel.lightRevealScrimViewModel
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
@@ -14,11 +15,12 @@
 import com.android.systemui.scene.shared.model.SceneContainerConfig
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.FakeOverlay
-import com.android.systemui.scene.ui.composable.SceneContainerTransitions
+import com.android.systemui.scene.ui.composable.ConstantSceneContainerTransitionsBuilder
 import com.android.systemui.scene.ui.viewmodel.SceneContainerHapticsViewModel
 import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
 import com.android.systemui.scene.ui.viewmodel.splitEdgeDetector
 import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
 import com.android.systemui.statusbar.domain.interactor.remoteInputInteractor
 import com.android.systemui.wallpapers.ui.viewmodel.wallpaperViewModel
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -48,6 +50,8 @@
 
 val Kosmos.overlays by Fixture { fakeOverlays }
 
+val Kosmos.sceneTransitionsBuilder by Fixture { ConstantSceneContainerTransitionsBuilder() }
+
 var Kosmos.sceneContainerConfig by Fixture {
     val navigationDistances =
         mapOf(
@@ -63,9 +67,9 @@
     SceneContainerConfig(
         sceneKeys = sceneKeys,
         initialSceneKey = initialSceneKey,
-        transitions = SceneContainerTransitions,
         overlayKeys = overlayKeys,
         navigationDistances = navigationDistances,
+        transitionsBuilder = sceneTransitionsBuilder,
     )
 }
 
@@ -91,7 +95,7 @@
                 sceneInteractor = sceneInteractor,
                 falsingInteractor = falsingInteractor,
                 powerInteractor = powerInteractor,
-                shadeInteractor = shadeInteractor,
+                shadeModeInteractor = shadeModeInteractor,
                 remoteInputInteractor = remoteInputInteractor,
                 splitEdgeDetector = splitEdgeDetector,
                 logger = sceneLogger,
@@ -100,6 +104,7 @@
                 motionEventHandlerReceiver = motionEventHandlerReceiver,
                 lightRevealScrim = lightRevealScrimViewModel,
                 wallpaperViewModel = wallpaperViewModel,
+                keyguardInteractor = keyguardInteractor,
             )
     }
 }
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
index 65bfafb..7a9b052 100644
--- 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
@@ -33,6 +33,7 @@
 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.trustInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.kosmos.testScope
@@ -91,5 +92,6 @@
         activityTransitionAnimator = activityTransitionAnimator,
         shadeModeInteractor = shadeModeInteractor,
         tableLogBuffer = logcatTableLogBuffer(this, "sceneFrameworkTableLogBuffer"),
+        trustInteractor = trustInteractor,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorKosmos.kt
index 5dc0333..9eff63c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorKosmos.kt
@@ -24,6 +24,7 @@
     Kosmos.Fixture {
         ShadeBackActionInteractorImpl(
             shadeInteractor = shadeInteractor,
+            shadeModeInteractor = shadeModeInteractor,
             sceneInteractor = sceneInteractor,
             deviceEntryInteractor = deviceEntryInteractor,
         )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractorKosmos.kt
index 2ba9c80..614b419 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractorKosmos.kt
@@ -36,6 +36,8 @@
     )
 }
 
+val Kosmos.shadeMode by Fixture { shadeModeInteractor.shadeMode }
+
 // TODO(b/391578667): Make this user-aware once supported by FakeSecureSettingsRepository.
 /**
  * Enables the Dual Shade setting, and (optionally) sets the shade layout to be wide (`true`) or
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelKosmos.kt
index 7eb9f34..cfc2075 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelKosmos.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.shade.ui.viewmodel
 
 import android.content.applicationContext
+import com.android.systemui.battery.BatteryMeterViewController
 import com.android.systemui.broadcast.broadcastDispatcher
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.plugins.activityStarter
@@ -24,8 +25,13 @@
 import com.android.systemui.shade.domain.interactor.privacyChipInteractor
 import com.android.systemui.shade.domain.interactor.shadeHeaderClockInteractor
 import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
+import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerStatusBarViewBinder
+import com.android.systemui.statusbar.phone.ui.StatusBarIconController
+import com.android.systemui.statusbar.phone.ui.TintedIconManager
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.mobileIconsInteractor
 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.mobileIconsViewModel
+import org.mockito.kotlin.mock
 
 val Kosmos.shadeHeaderViewModel: ShadeHeaderViewModel by
     Kosmos.Fixture {
@@ -34,10 +40,16 @@
             activityStarter = activityStarter,
             sceneInteractor = sceneInteractor,
             shadeInteractor = shadeInteractor,
+            shadeModeInteractor = shadeModeInteractor,
             mobileIconsInteractor = mobileIconsInteractor,
             mobileIconsViewModel = mobileIconsViewModel,
             privacyChipInteractor = privacyChipInteractor,
             clockInteractor = shadeHeaderClockInteractor,
+            tintedIconManagerFactory = mock<TintedIconManager.Factory>(),
+            batteryMeterViewControllerFactory = mock<BatteryMeterViewController.Factory>(),
+            statusBarIconController = mock<StatusBarIconController>(),
+            notificationIconContainerStatusBarViewBinder =
+                mock<NotificationIconContainerStatusBarViewBinder>(),
             broadcastDispatcher = broadcastDispatcher,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelKosmos.kt
index 694bb6e..db4b979 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelKosmos.kt
@@ -25,7 +25,7 @@
 import com.android.systemui.qs.ui.adapter.qsSceneAdapter
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModelFactory
-import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
 import com.android.systemui.statusbar.disableflags.domain.interactor.disableFlagsInteractor
 import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor
 
@@ -35,7 +35,7 @@
         qsSceneAdapter = qsSceneAdapter,
         brightnessMirrorViewModelFactory = brightnessMirrorViewModelFactory,
         mediaCarouselInteractor = mediaCarouselInteractor,
-        shadeInteractor = shadeInteractor,
+        shadeModeInteractor = shadeModeInteractor,
         disableFlagsInteractor = disableFlagsInteractor,
         footerActionsViewModelFactory = footerActionsViewModelFactory,
         footerActionsController = footerActionsController,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelKosmos.kt
index 0aeea4e..2635593 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelKosmos.kt
@@ -20,12 +20,12 @@
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.qs.ui.adapter.qsSceneAdapter
 import com.android.systemui.scene.domain.interactor.sceneBackInteractor
-import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
 
 val Kosmos.shadeUserActionsViewModel: ShadeUserActionsViewModel by Fixture {
     ShadeUserActionsViewModel(
         qsSceneAdapter = qsSceneAdapter,
-        shadeInteractor = shadeInteractor,
+        shadeModeInteractor = shadeModeInteractor,
         sceneBackInteractor = sceneBackInteractor,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelKosmos.kt
index 1e304d9..ab61a3e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelKosmos.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.chips.call.ui.viewmodel
 
+import android.content.applicationContext
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.plugins.activityStarter
@@ -26,6 +27,7 @@
 val Kosmos.callChipViewModel: CallChipViewModel by
     Kosmos.Fixture {
         CallChipViewModel(
+            applicationContext,
             scope = applicationCoroutineScope,
             interactor = callChipInteractor,
             systemClock = fakeSystemClock,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt
index d0c80c7..878c2de 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelKosmos.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.chips.notification.ui.viewmodel
 
+import android.content.applicationContext
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
@@ -24,6 +25,7 @@
 val Kosmos.notifChipsViewModel: NotifChipsViewModel by
     Kosmos.Fixture {
         NotifChipsViewModel(
+            applicationContext,
             applicationCoroutineScope,
             statusBarNotificationChipsInteractor,
             headsUpNotificationInteractor,
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 ee34aa6..212049a 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
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.chips.ui.viewmodel
 
+import com.android.systemui.biometrics.domain.interactor.displayStateInteractor
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.statusbar.chips.call.ui.viewmodel.callChipViewModel
@@ -34,6 +36,8 @@
             castToOtherDeviceChipViewModel = castToOtherDeviceChipViewModel,
             callChipViewModel = callChipViewModel,
             notifChipsViewModel = notifChipsViewModel,
+            displayStateInteractor = displayStateInteractor,
+            configurationInteractor = configurationInteractor,
             logger = statusBarChipsLogger,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt
index 8c37bd7..bdcab5f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarOrchestratorKosmos.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.core
 
 import android.content.testableContext
+import android.view.mockIWindowManager
 import com.android.systemui.bouncer.domain.interactor.primaryBouncerInteractor
 import com.android.systemui.display.data.repository.displayRepository
 import com.android.systemui.display.data.repository.displayScopeRepository
@@ -84,5 +85,6 @@
             multiDisplayAutoHideControllerStore,
             privacyDotWindowControllerStore,
             lightBarControllerStore,
+            mockIWindowManager,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt
index c6ae15d..63085e1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt
@@ -43,6 +43,7 @@
     instanceId: Int? = null,
     isGroupSummary: Boolean = false,
     packageName: String = "pkg",
+    appName: String = "appName",
     contentIntent: PendingIntent? = null,
     bucket: Int = BUCKET_UNKNOWN,
     callType: CallType = CallType.None,
@@ -64,6 +65,7 @@
         statusBarChipIconView = statusBarChipIcon,
         uid = uid,
         packageName = packageName,
+        appName = appName,
         contentIntent = contentIntent,
         instanceId = instanceId,
         isGroupSummary = isGroupSummary,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractorKosmos.kt
index f7acae9..0acf98f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractorKosmos.kt
@@ -16,11 +16,16 @@
 
 package com.android.systemui.statusbar.notification.domain.interactor
 
+import android.content.applicationContext
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.statusbar.notification.collection.provider.sectionStyleProvider
 import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
 
 val Kosmos.renderNotificationListInteractor by
     Kosmos.Fixture {
-        RenderNotificationListInteractor(activeNotificationListRepository, sectionStyleProvider)
+        RenderNotificationListInteractor(
+            activeNotificationListRepository,
+            sectionStyleProvider,
+            applicationContext,
+        )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorKosmos.kt
index 2772d36..87704cc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorKosmos.kt
@@ -19,7 +19,7 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
 import com.android.systemui.statusbar.notification.stack.data.repository.notificationPlaceholderRepository
 import com.android.systemui.statusbar.notification.stack.data.repository.notificationViewHeightRepository
 
@@ -28,6 +28,6 @@
         viewHeightRepository = notificationViewHeightRepository,
         placeholderRepository = notificationPlaceholderRepository,
         sceneInteractor = sceneInteractor,
-        shadeInteractor = shadeInteractor,
+        shadeModeInteractor = shadeModeInteractor,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationStatsLoggerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationStatsLoggerKosmos.kt
index de52155..f91c2f6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationStatsLoggerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationStatsLoggerKosmos.kt
@@ -26,7 +26,7 @@
 
 val Kosmos.notificationStatsLogger by Fixture {
     NotificationStatsLoggerImpl(
-        applicationScope = testScope,
+        applicationScope = testScope.backgroundScope,
         bgDispatcher = testDispatcher,
         statusBarService = statusBarService,
         notificationListenerService = notificationListenerService,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModelKosmos.kt
index 7244d46..167b11d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModelKosmos.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
 import com.android.systemui.statusbar.domain.interactor.remoteInputInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
 
@@ -30,6 +31,7 @@
         dumpManager = dumpManager,
         stackAppearanceInteractor = notificationStackAppearanceInteractor,
         shadeInteractor = shadeInteractor,
+        shadeModeInteractor = shadeModeInteractor,
         remoteInputInteractor = remoteInputInteractor,
         sceneInteractor = sceneInteractor,
         keyguardInteractor = { keyguardInteractor },
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 e5cf0a9..0847774 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
@@ -22,6 +22,7 @@
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
 import com.android.systemui.statusbar.domain.interactor.remoteInputInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
@@ -31,6 +32,7 @@
         interactor = notificationStackAppearanceInteractor,
         sceneInteractor = sceneInteractor,
         shadeInteractor = shadeInteractor,
+        shadeModeInteractor = shadeModeInteractor,
         headsUpNotificationInteractor = headsUpNotificationInteractor,
         remoteInputInteractor = remoteInputInteractor,
         featureFlags = featureFlagsClassic,
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 45c56ae0..7a2b7c2 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
@@ -54,6 +54,7 @@
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
 import com.android.systemui.shade.largeScreenHeaderHelper
 import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
@@ -71,6 +72,7 @@
         keyguardInteractor = keyguardInteractor,
         keyguardTransitionInteractor = keyguardTransitionInteractor,
         shadeInteractor = shadeInteractor,
+        shadeModeInteractor = shadeModeInteractor,
         notificationStackAppearanceInteractor = notificationStackAppearanceInteractor,
         alternateBouncerToGoneTransitionViewModel = alternateBouncerToGoneTransitionViewModel,
         alternateBouncerToPrimaryBouncerTransitionViewModel =
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt
index f4e74fe..923b36d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt
@@ -26,5 +26,14 @@
     notificationIcon: StatusBarIconView? = null,
     intent: PendingIntent? = null,
     notificationKey: String = "test",
+    appName: String = "",
     promotedContent: PromotedNotificationContentModel? = null,
-) = OngoingCallModel.InCall(startTimeMs, notificationIcon, intent, notificationKey, promotedContent)
+) =
+    OngoingCallModel.InCall(
+        startTimeMs,
+        notificationIcon,
+        intent,
+        notificationKey,
+        appName,
+        promotedContent,
+    )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
index 1626904..bc29dba 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
@@ -20,7 +20,8 @@
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.backgroundScope
+import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.log.table.tableLogBufferFactory
 import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
@@ -59,6 +60,7 @@
             statusBarPopupChipsViewModel,
             systemStatusEventAnimationInteractor,
             multiDisplayStatusBarContentInsetsViewModelStore,
-            applicationCoroutineScope,
+            backgroundScope,
+            testDispatcher,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModuleKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModuleKosmos.kt
index 556c34d..0c814c5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModuleKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModuleKosmos.kt
@@ -16,16 +16,13 @@
 
 package com.android.systemui.volume.panel.component.mediaoutput
 
-import android.content.applicationContext
 import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.volume.panel.component.mediaoutput.domain.MediaOutputAvailabilityCriteria
 import com.android.systemui.volume.panel.component.mediaoutput.ui.composable.MediaOutputComponent
 import com.android.systemui.volume.panel.component.mediaoutput.ui.viewmodel.mediaOutputViewModel
+import com.android.systemui.volume.panel.domain.ComponentAvailabilityCriteria
+import com.android.systemui.volume.panel.domain.availableCriteria
 
 var Kosmos.mediaOutputComponent: MediaOutputComponent by
     Kosmos.Fixture { MediaOutputComponent(mediaOutputViewModel) }
-var Kosmos.mediaOutputAvailabilityCriteria by
-    Kosmos.Fixture {
-        MediaOutputAvailabilityCriteria(applicationContext, testScope.backgroundScope)
-    }
+var Kosmos.mediaOutputAvailabilityCriteria: ComponentAvailabilityCriteria by
+    Kosmos.Fixture { availableCriteria }
diff --git a/packages/WallpaperBackup/AndroidManifest.xml b/packages/WallpaperBackup/AndroidManifest.xml
index 3ce97cd..669ea71 100644
--- a/packages/WallpaperBackup/AndroidManifest.xml
+++ b/packages/WallpaperBackup/AndroidManifest.xml
@@ -34,6 +34,7 @@
                  android:allowBackup="true"
                  android:backupInForeground="true"
                  android:backupAgent=".WallpaperBackupAgent"
+                 android:restoreAnyVersion="true"
                  android:fullBackupOnly="true" >
     </application>
 </manifest>
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
index 3cb6c5a..7af03ed 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
@@ -44,6 +44,7 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.res.Resources;
+import android.icu.util.ULocale;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Build.VERSION_CODES;
@@ -81,6 +82,7 @@
 import java.io.PrintStream;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Random;
@@ -228,6 +230,9 @@
         RuntimeInit.redirectLogStreams();
 
         dumpCommandLineArgs();
+        dumpEnvironment();
+        dumpJavaProperties();
+        dumpOtherInfo();
 
         // We haven't initialized liblog yet, so directly write to System.out here.
         RavenwoodCommonUtils.log(TAG, "globalInitInner()");
@@ -564,4 +569,34 @@
             Log.v(TAG, "  " + arg);
         }
     }
+
+    private static void dumpJavaProperties() {
+        Log.v(TAG, "JVM properties:");
+        dumpMap(System.getProperties());
+    }
+
+    private static void dumpEnvironment() {
+        Log.v(TAG, "Environment:");
+        dumpMap(System.getenv());
+    }
+
+    private static void dumpMap(Map<?, ?> map) {
+        for (var key : map.keySet().stream().sorted().toList()) {
+            Log.v(TAG, "  " + key + "=" + map.get(key));
+        }
+    }
+
+    private static void dumpOtherInfo() {
+        Log.v(TAG, "Other key information:");
+        var jloc = Locale.getDefault();
+        Log.v(TAG, "  java.util.Locale=" + jloc + " / " + jloc.toLanguageTag());
+        var uloc = ULocale.getDefault();
+        Log.v(TAG, "  android.icu.util.ULocale=" + uloc + " / " + uloc.toLanguageTag());
+
+        var jtz = java.util.TimeZone.getDefault();
+        Log.v(TAG, "  java.util.TimeZone=" + jtz.getDisplayName() + " / " + jtz);
+
+        var itz = android.icu.util.TimeZone.getDefault();
+        Log.v(TAG, "  android.icu.util.TimeZone="  + itz.getDisplayName() + " / " + itz);
+    }
 }
diff --git a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
index 383e75b..e202d0e 100644
--- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
@@ -151,6 +151,10 @@
 android.os.Message
 android.os.MessageQueue
 android.os.MessageQueue_ravenwood
+android.os.PerfettoTrace
+android.os.PerfettoTrace$Category
+android.os.PerfettoTrackEventExtra
+android.os.PerfettoTrackEventExtra$NoOpBuilder
 android.os.PackageTagsList
 android.os.Parcel
 android.os.ParcelFileDescriptor
diff --git a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java
index 1bc9c78..8e44867 100644
--- a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java
+++ b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java
@@ -81,6 +81,7 @@
     @VisibleForTesting AutoclickSettingsObserver mAutoclickSettingsObserver;
     @VisibleForTesting AutoclickIndicatorScheduler mAutoclickIndicatorScheduler;
     @VisibleForTesting AutoclickIndicatorView mAutoclickIndicatorView;
+    @VisibleForTesting AutoclickTypePanel mAutoclickTypePanel;
     private WindowManager mWindowManager;
 
     public AutoclickController(Context context, int userId, AccessibilityTraceManager trace) {
@@ -123,6 +124,9 @@
         mAutoclickIndicatorView = new AutoclickIndicatorView(mContext);
 
         mWindowManager = mContext.getSystemService(WindowManager.class);
+        mAutoclickTypePanel = new AutoclickTypePanel(mContext, mWindowManager);
+
+        mAutoclickTypePanel.show();
         mWindowManager.addView(mAutoclickIndicatorView, mAutoclickIndicatorView.getLayoutParams());
     }
 
@@ -167,6 +171,7 @@
             mAutoclickIndicatorScheduler.cancel();
             mAutoclickIndicatorScheduler = null;
             mWindowManager.removeView(mAutoclickIndicatorView);
+            mAutoclickTypePanel.hide();
         }
     }
 
@@ -310,7 +315,7 @@
                     if (mAutoclickIndicatorScheduler != null) {
                         mAutoclickIndicatorScheduler.updateCursorAreaSize(size);
                     }
-                    mClickScheduler.updateMovementSlope(size);
+                    mClickScheduler.updateMovementSlop(size);
                 }
 
                 if (mAutoclickIgnoreMinorCursorMovementSettingUri.equals(uri)) {
@@ -400,9 +405,9 @@
          * to be discarded as noise. Anchor is the position of the last MOVE event that was not
          * considered noise.
          */
-        private static final double DEFAULT_MOVEMENT_SLOPE = 20f;
+        private static final double DEFAULT_MOVEMENT_SLOP = 20f;
 
-        private double mMovementSlope = DEFAULT_MOVEMENT_SLOPE;
+        private double mMovementSlop = DEFAULT_MOVEMENT_SLOP;
 
         /** Whether the minor cursor movement should be ignored. */
         private boolean mIgnoreMinorCursorMovement = AUTOCLICK_IGNORE_MINOR_CURSOR_MOVEMENT_DEFAULT;
@@ -500,6 +505,11 @@
             mMetaState = state;
         }
 
+        @VisibleForTesting
+        int getMetaStateForTesting() {
+            return mMetaState;
+        }
+
         /**
          * Updates delay that should be used when scheduling clicks. The delay will be used only for
          * clicks scheduled after this point (pending click tasks are not affected).
@@ -589,19 +599,19 @@
             float deltaX = mAnchorCoords.x - event.getX(pointerIndex);
             float deltaY = mAnchorCoords.y - event.getY(pointerIndex);
             double delta = Math.hypot(deltaX, deltaY);
-            double slope =
+            double slop =
                     ((Flags.enableAutoclickIndicator() && mIgnoreMinorCursorMovement)
-                            ? mMovementSlope
-                            : DEFAULT_MOVEMENT_SLOPE);
-            return delta > slope;
+                            ? mMovementSlop
+                            : DEFAULT_MOVEMENT_SLOP);
+            return delta > slop;
         }
 
         public void setIgnoreMinorCursorMovement(boolean ignoreMinorCursorMovement) {
             mIgnoreMinorCursorMovement = ignoreMinorCursorMovement;
         }
 
-        private void updateMovementSlope(double slope) {
-            mMovementSlope = slope;
+        private void updateMovementSlop(double slop) {
+            mMovementSlop = slop;
         }
 
         /**
diff --git a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java
new file mode 100644
index 0000000..1ba5745
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.autoclick;
+
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowInsets;
+import android.view.WindowManager;
+
+import androidx.annotation.NonNull;
+
+import com.android.internal.R;
+
+public class AutoclickTypePanel {
+
+    private final String TAG = AutoclickTypePanel.class.getSimpleName();
+
+    private final Context mContext;
+
+    private final View mContentView;
+
+    private final WindowManager mWindowManager;
+
+    public AutoclickTypePanel(Context context, WindowManager windowManager) {
+        mContext = context;
+        mWindowManager = windowManager;
+
+        mContentView = LayoutInflater.from(context).inflate(
+                R.layout.accessibility_autoclick_type_panel, null);
+    }
+
+    public void show() {
+        mWindowManager.addView(mContentView, getLayoutParams());
+    }
+
+    public void hide() {
+        mWindowManager.removeView(mContentView);
+    }
+
+    /**
+     * Retrieves the layout params for AutoclickIndicatorView, used when it's added to the Window
+     * Manager.
+     */
+    @NonNull
+    private WindowManager.LayoutParams getLayoutParams() {
+        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
+        layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+        layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+        layoutParams.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
+        layoutParams.setFitInsetsTypes(WindowInsets.Type.statusBars());
+        layoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+        layoutParams.format = PixelFormat.TRANSLUCENT;
+        layoutParams.setTitle(AutoclickTypePanel.class.getSimpleName());
+        layoutParams.accessibilityTitle =
+                mContext.getString(R.string.accessibility_autoclick_type_settings_panel_title);
+        layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
+        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
+        // TODO(b/388847771): Compute position based on user interaction.
+        layoutParams.x = 15;
+        layoutParams.y = 90;
+        layoutParams.gravity = Gravity.END | Gravity.BOTTOM;
+
+        return layoutParams;
+    }
+}
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 521f676..414db37 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -695,8 +695,10 @@
         }
 
         private void checkCallerCanSkipRoleGrant() {
+            final Context context =
+                    getContext().createContextAsUser(Binder.getCallingUserHandle(), 0);
             final KeyguardManager keyguardManager =
-                    getContext().getSystemService(KeyguardManager.class);
+                    context.getSystemService(KeyguardManager.class);
             if (keyguardManager != null && keyguardManager.isKeyguardSecure()) {
                 throw new SecurityException("Skipping CDM role grant requires insecure keyguard.");
             }
diff --git a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
index df47c98..89c9d69 100644
--- a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
+++ b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
@@ -27,10 +27,6 @@
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
-import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 
 import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
 import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
@@ -74,6 +70,7 @@
 import android.util.Slog;
 import android.view.IWindowManager;
 import android.window.ScreenCapture;
+import android.window.ScreenCapture.ScreenshotHardwareBuffer;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
@@ -333,10 +330,10 @@
                 isManagedProfileVisible = true;
             }
         }
+        final String csPackage = Objects.requireNonNull(launchIntent.getPackage());
+        final int csUid = mPackageManager.getPackageUid(csPackage, /* flags */ 0L, userId);
         if (isAssistDataAllowed) {
             try {
-                final String csPackage = Objects.requireNonNull(launchIntent.getPackage());
-                final int csUid = mPackageManager.getPackageUid(csPackage, 0, 0);
                 mAssistDataRequester.requestAssistData(
                         activityTokens,
                         /* fetchData */ true,
@@ -350,17 +347,8 @@
                 Log.e(TAG, "Could not request assist data", e);
             }
         }
-        final ScreenCapture.ScreenshotHardwareBuffer shb;
-        if (mWmInternal != null) {
-            shb = mWmInternal.takeAssistScreenshot(Set.of(
-                    TYPE_STATUS_BAR,
-                    TYPE_NAVIGATION_BAR,
-                    TYPE_NAVIGATION_BAR_PANEL,
-                    TYPE_POINTER));
-        } else {
-            if (DEBUG) Log.w(TAG, "Can't capture contextual screenshot: mWmInternal is null");
-            shb = null;
-        }
+        final ScreenshotHardwareBuffer shb = mWmInternal.takeContextualSearchScreenshot(
+                (Flags.contextualSearchWindowLayer() ? csUid : -1));
         final Bitmap bm = shb != null ? shb.asBitmap() : null;
         // Now that everything is fetched, putting it in the launchIntent.
         if (bm != null) {
@@ -509,15 +497,17 @@
                 bundle.putParcelable(ContextualSearchManager.EXTRA_TOKEN, mToken);
                 // We get take the screenshot with the system server's identity because the system
                 // server has READ_FRAME_BUFFER permission to get the screenshot.
+                final int callingUid = Binder.getCallingUid();
                 Binder.withCleanCallingIdentity(() -> {
-                    if (mWmInternal != null) {
+                    final ScreenshotHardwareBuffer shb =
+                            mWmInternal.takeContextualSearchScreenshot(
+                               (Flags.contextualSearchWindowLayer() ? callingUid : -1));
+                    final Bitmap bm = shb != null ? shb.asBitmap() : null;
+                    if (bm != null) {
                         bundle.putParcelable(ContextualSearchManager.EXTRA_SCREENSHOT,
-                                mWmInternal.takeAssistScreenshot(Set.of(
-                                        TYPE_STATUS_BAR,
-                                        TYPE_NAVIGATION_BAR,
-                                        TYPE_NAVIGATION_BAR_PANEL,
-                                        TYPE_POINTER))
-                                .asBitmap().asShared());
+                                bm.asShared());
+                        bundle.putBoolean(ContextualSearchManager.EXTRA_FLAG_SECURE_FOUND,
+                                shb.containsSecureLayers());
                     }
                     try {
                         callback.onResult(
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 420dcfe..9b0caf5 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -227,6 +227,7 @@
         "com.android.sysprop.watchdog",
         "securebox",
         "apache-commons-math",
+        "apache-commons-compress",
         "battery_saver_flag_lib",
         "notification_flags_lib",
         "power_hint_flags_lib",
diff --git a/services/core/java/com/android/server/BootReceiver.java b/services/core/java/com/android/server/BootReceiver.java
index 7a5b866..cf0d7e7 100644
--- a/services/core/java/com/android/server/BootReceiver.java
+++ b/services/core/java/com/android/server/BootReceiver.java
@@ -53,6 +53,7 @@
 import com.android.server.am.DropboxRateLimiter;
 import com.android.server.os.TombstoneProtos.Tombstone;
 
+import libcore.io.IoUtils;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -154,6 +155,10 @@
 
     @Override
     public void onReceive(final Context context, Intent intent) {
+        if (!Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
+            return;
+        }
+
         // Log boot events in the background to avoid blocking the main thread with I/O
         new Thread() {
             @Override
@@ -219,6 +224,8 @@
                 } catch (Exception e) {
                     Slog.wtf(TAG, "Error watching for trace events", e);
                     return 0;  // Unregister the handler.
+                } finally {
+                    IoUtils.closeQuietly(fd);
                 }
                 return OnFileDescriptorEventListener.EVENT_INPUT;
             }
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index ef769cf..6858e29 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -9,7 +9,6 @@
 
 # Zram writeback
 per-file ZramWriteback.java = minchan@google.com, rajekumar@google.com
-per-file ZramMaintenance.java = kawasin@google.com
 
 # ServiceWatcher
 per-file ServiceWatcher.java = sooniln@google.com
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 19e7e06..49ab8ec 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -156,6 +156,7 @@
 import com.android.internal.util.Preconditions;
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
+import com.android.server.memory.ZramMaintenance;
 import com.android.server.pm.Installer;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.storage.AppFuseBridge;
@@ -947,7 +948,6 @@
         refreshZramSettings();
 
         if (mmdEnabled()) {
-            // TODO: b/375432472 - Start zram maintenance only when zram is enabled.
             ZramMaintenance.startZramMaintenance(mContext);
         } else {
             // Schedule zram writeback unless zram is disabled by persist.sys.zram_enabled
diff --git a/services/core/java/com/android/server/TradeInModeService.java b/services/core/java/com/android/server/TradeInModeService.java
index a696673..1a9e02c 100644
--- a/services/core/java/com/android/server/TradeInModeService.java
+++ b/services/core/java/com/android/server/TradeInModeService.java
@@ -41,12 +41,15 @@
 import java.io.FileWriter;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 
 
 public final class TradeInModeService extends SystemService {
     private static final String TAG = "TradeInModeService";
 
     private static final String TIM_PROP = "persist.adb.tradeinmode";
+    private static final String TIM_TEST_PROP = "persist.adb.test_tradeinmode";
 
     private static final int TIM_STATE_UNSET = 0;
 
@@ -108,6 +111,10 @@
                 // setup completion observer.
                 if (isDeviceSetup()) {
                     stopTradeInMode();
+                } else if (isDebuggable() && !isForceEnabledForTesting()) {
+                    // The device was made debuggable after entering TIM. This
+                    // can happen while flashing. For convenience, leave test mode.
+                    leaveTestMode();
                 } else {
                     watchForSetupCompletion();
                     watchForNetworkChange();
@@ -171,12 +178,7 @@
                 Slog.e(TAG, "Cannot enter evaluation mode, FRP lock is present.");
                 return false;
             }
-
-            try (FileWriter fw = new FileWriter(WIPE_INDICATOR_FILE,
-                                                StandardCharsets.US_ASCII)) {
-                fw.write("0");
-            } catch (IOException e) {
-                Slog.e(TAG, "Failed to write " + WIPE_INDICATOR_FILE, e);
+            if (!scheduleTradeInModeWipe()) {
                 return false;
             }
 
@@ -189,7 +191,7 @@
             }
 
             SystemProperties.set(TIM_PROP, Integer.toString(TIM_STATE_EVALUATION_MODE));
-            SystemProperties.set("ctl.restart", "adbd");
+            restartAdbd();
             return true;
         }
 
@@ -200,6 +202,55 @@
                                         "Cannot test for trade-in evaluation mode allowed");
             return !isFrpActive();
         }
+
+        @Override
+        @RequiresPermission(android.Manifest.permission.ENTER_TRADE_IN_MODE)
+        public void scheduleWipeForTesting() {
+            enforceTestingPermissions();
+
+            scheduleTradeInModeWipe();
+        }
+
+        @Override
+        @RequiresPermission(android.Manifest.permission.ENTER_TRADE_IN_MODE)
+        public void startTesting() {
+            enforceTestingPermissions();
+
+            enterTestMode();
+        }
+
+        @Override
+        @RequiresPermission(android.Manifest.permission.ENTER_TRADE_IN_MODE)
+        public void stopTesting() {
+            enforceTestingPermissions();
+
+            if (!isForceEnabledForTesting()) {
+                throw new IllegalStateException("testing must have been started");
+            }
+
+            final long callingId = Binder.clearCallingIdentity();
+            try {
+                leaveTestMode();
+            } finally {
+                Binder.restoreCallingIdentity(callingId);
+            }
+        }
+
+        @Override
+        @RequiresPermission(android.Manifest.permission.ENTER_TRADE_IN_MODE)
+        public boolean isTesting() {
+            enforceTestingPermissions();
+
+            return isForceEnabledForTesting();
+        }
+
+        private void enforceTestingPermissions() {
+            mContext.enforceCallingOrSelfPermission("android.permission.ENTER_TRADE_IN_MODE",
+                                        "Caller must have ENTER_TRADE_IN_MODE permission");
+            if (!isDebuggable()) {
+                throw new SecurityException("ro.debuggable must be set to 1");
+            }
+        }
     }
 
     private void startTradeInMode() {
@@ -207,8 +258,7 @@
 
         SystemProperties.set(TIM_PROP, Integer.toString(TIM_STATE_FOYER));
 
-        final ContentResolver cr = mContext.getContentResolver();
-        Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 1);
+        setAdbEnabled(true);
 
         watchForSetupCompletion();
         watchForNetworkChange();
@@ -223,8 +273,51 @@
         removeNetworkWatch();
         removeAccountsWatch();
 
+        if (isForceEnabledForTesting()) {
+            // If testing in a debug build, we need to re-enable ADB.
+            restartAdbd();
+        } else {
+            // Otherwise, ADB must not be enabled.
+            setAdbEnabled(false);
+        }
+    }
+
+    private void enterTestMode() {
+        SystemProperties.set(TIM_TEST_PROP, "1");
+    }
+
+    private void leaveTestMode() {
+        if (getTradeInModeState() == TIM_STATE_FOYER) {
+            stopTradeInMode();
+        }
+
+        SystemProperties.set(TIM_TEST_PROP, "");
+        SystemProperties.set(TIM_PROP, "");
+        try {
+            Files.deleteIfExists(Paths.get(WIPE_INDICATOR_FILE));
+        } catch (IOException e) {
+            Slog.e(TAG, "Failed to remove wipe indicator", e);
+        }
+    }
+
+    private boolean scheduleTradeInModeWipe() {
+        try (FileWriter fw = new FileWriter(WIPE_INDICATOR_FILE,
+                                            StandardCharsets.US_ASCII)) {
+            fw.write("0");
+        } catch (IOException e) {
+            Slog.e(TAG, "Failed to write " + WIPE_INDICATOR_FILE, e);
+            return false;
+        }
+        return true;
+    }
+
+    private void restartAdbd() {
+        SystemProperties.set("ctl.restart", "adbd");
+    }
+
+    private void setAdbEnabled(boolean enabled) {
         final ContentResolver cr = mContext.getContentResolver();
-        Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 0);
+        Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, enabled ? 1 : 0);
     }
 
     private int getTradeInModeState() {
@@ -236,7 +329,7 @@
     }
 
     private boolean isForceEnabledForTesting() {
-        return SystemProperties.getInt("persist.adb.test_tradeinmode", 0) == 1;
+        return isDebuggable() && SystemProperties.getInt(TIM_TEST_PROP, 0) == 1;
     }
 
     private boolean isAdbEnabled() {
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 896c9b8..c65981b 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -16,11 +16,13 @@
 
 package com.android.server;
 
-import static android.app.Flags.modesApi;
 import static android.app.Flags.enableCurrentModeTypeBinderCache;
 import static android.app.Flags.enableNightModeBinderCache;
+import static android.app.Flags.modesApi;
 import static android.app.UiModeManager.ContrastUtils.CONTRAST_DEFAULT_VALUE;
 import static android.app.UiModeManager.DEFAULT_PRIORITY;
+import static android.app.UiModeManager.FORCE_INVERT_TYPE_DARK;
+import static android.app.UiModeManager.FORCE_INVERT_TYPE_OFF;
 import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_OFF;
 import static android.app.UiModeManager.MODE_NIGHT_AUTO;
 import static android.app.UiModeManager.MODE_NIGHT_CUSTOM;
@@ -33,6 +35,7 @@
 import static android.app.UiModeManager.PROJECTION_TYPE_NONE;
 import static android.os.UserHandle.USER_SYSTEM;
 import static android.os.UserHandle.getCallingUserId;
+import static android.provider.Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED;
 import static android.provider.Settings.Secure.CONTRAST_LEVEL;
 import static android.util.TimeUtils.isTimeBetween;
 
@@ -45,6 +48,7 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
+import android.app.ActivityThread;
 import android.app.AlarmManager;
 import android.app.IOnProjectionStateChangedListener;
 import android.app.IUiModeManager;
@@ -56,6 +60,7 @@
 import android.app.StatusBarManager;
 import android.app.UiModeManager;
 import android.app.UiModeManager.AttentionModeThemeOverlayType;
+import android.app.UiModeManager.ForceInvertType;
 import android.app.UiModeManager.NightModeCustomReturnType;
 import android.app.UiModeManager.NightModeCustomType;
 import android.content.BroadcastReceiver;
@@ -93,6 +98,7 @@
 import android.util.ArraySet;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseIntArray;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
@@ -256,6 +262,9 @@
     @GuardedBy("mLock")
     private final SparseArray<Float> mContrasts = new SparseArray<>();
 
+    @GuardedBy("mLock")
+    private final SparseIntArray mForceInvertStates = new SparseIntArray();
+
     public UiModeManagerService(Context context) {
         this(context, /* setupWizardComplete= */ false, /* tm= */ null, new Injector());
     }
@@ -407,9 +416,33 @@
         @Override
         public void onChange(boolean selfChange, Uri uri) {
             updateSystemProperties();
+            updateForceInvertStates();
         }
     };
 
+    private final ContentObserver mForceInvertStateObserver = new ContentObserver(mHandler) {
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            updateForceInvertStates();
+        }
+    };
+
+    private void updateForceInvertStates() {
+        if (!android.view.accessibility.Flags.forceInvertColor()) {
+            return;
+        }
+
+        synchronized (mLock) {
+            if (updateForceInvertStateLocked()) {
+                int forceInvertState = getForceInvertStateLocked();
+                mUiModeManagerCallbacks.get(mCurrentUser, new RemoteCallbackList<>())
+                        .broadcast(ignoreRemoteException(
+                                callback ->
+                                        callback.notifyForceInvertStateChanged(forceInvertState)));
+            }
+        }
+    }
+
     private final ContentObserver mContrastObserver = new ContentObserver(mHandler) {
         @Override
         public void onChange(boolean selfChange, Uri uri) {
@@ -485,6 +518,12 @@
                 context.getContentResolver()
                         .registerContentObserver(Secure.getUriFor(Secure.UI_NIGHT_MODE),
                                 false, mDarkThemeObserver, 0);
+                if (android.view.accessibility.Flags.forceInvertColor()) {
+                    context.getContentResolver()
+                            .registerContentObserver(
+                                    Secure.getUriFor(ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED),
+                                    false, mForceInvertStateObserver, UserHandle.USER_ALL);
+                }
                 context.getContentResolver().registerContentObserver(
                         Secure.getUriFor(Secure.CONTRAST_LEVEL), false,
                         mContrastObserver, UserHandle.USER_ALL);
@@ -919,7 +958,7 @@
 
         @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DAY_NIGHT_MODE)
         @Override
-        public  @NightModeCustomReturnType int getNightModeCustomType() {
+        public @NightModeCustomReturnType int getNightModeCustomType() {
             getNightModeCustomType_enforcePermission();
             synchronized (mLock) {
                 return mNightModeCustomType;
@@ -1275,6 +1314,14 @@
                 return getContrastLocked();
             }
         }
+
+        @Override
+        @ForceInvertType
+        public int getForceInvertState() {
+            synchronized (mLock) {
+                return getForceInvertStateLocked();
+            }
+        }
     };
 
     private void enforceProjectionTypePermissions(@UiModeManager.ProjectionType int p) {
@@ -1358,6 +1405,76 @@
     }
 
     /**
+     * Return the force invert for the current user. If not cached, fetch it from the settings.
+     */
+    @GuardedBy("mLock")
+    @ForceInvertType
+    private int getForceInvertStateLocked() {
+        if (mForceInvertStates.indexOfKey(mCurrentUser) < 0) {
+            updateForceInvertStateLocked();
+        }
+        return mForceInvertStates.get(mCurrentUser);
+    }
+
+    /**
+     * Read the force invert setting for the current user and update {@link #mForceInvertStates}
+     * if the contrast changed. Returns true if {@link #mForceInvertStates} was updated.
+     */
+    @GuardedBy("mLock")
+    private boolean updateForceInvertStateLocked() {
+        int forceInvertState = getForceInvertStateInternal();
+        if (mForceInvertStates.get(mCurrentUser) != forceInvertState) {
+            mForceInvertStates.put(mCurrentUser, forceInvertState);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the current state of force invert, which modifies the display colors to
+     * enhance visibility based on the system's dark theme settings and app-specific configurations.
+     *
+     * <p>This method is for informational purposes only. The application does not need to
+     * implement any special handling for force invert; the system applies it automatically.
+     * If you want to prevent force invert from affecting your app, ensure you have defined
+     * both light and dark themes. Force invert is not applied to apps that already adapt
+     * to the user's system theme preference.</p>
+     *
+     * @return The current force invert state, represented by a {@code ForceDarkType} constant.
+     *
+     * @hide
+     */
+    private int getForceInvertStateInternal() {
+        if (!android.view.accessibility.Flags.forceInvertColor()) {
+            return FORCE_INVERT_TYPE_OFF;
+        }
+
+        if (!isSystemInDarkTheme()) {
+            return FORCE_INVERT_TYPE_OFF;
+        }
+
+        if (!isForceInvert()) {
+            return FORCE_INVERT_TYPE_OFF;
+        }
+
+        return FORCE_INVERT_TYPE_DARK;
+    }
+
+    private boolean isSystemInDarkTheme() {
+        Context sysUiContext = ActivityThread.currentActivityThread().getSystemUiContext();
+        int sysUiNightMode = sysUiContext.getResources().getConfiguration().uiMode
+                & Configuration.UI_MODE_NIGHT_MASK;
+        return sysUiNightMode == Configuration.UI_MODE_NIGHT_YES;
+    }
+
+    private boolean isForceInvert() {
+        return Settings.Secure.getIntForUser(
+                getContext().getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED,
+                /* def= */ 0, mCurrentUser) == 1;
+    }
+
+    /**
      * Return the contrast for the current user. If not cached, fetch it from the settings.
      */
     @GuardedBy("mLock")
@@ -1967,6 +2084,14 @@
         sendConfigurationAndStartDreamOrDockAppLocked(category);
     }
 
+    private boolean shouldStartDockApp(Context context, Intent homeIntent) {
+        if (mWatch && !mSetupWizardComplete) {
+            // Do not ever start dock app when setup is not complete on a watch.
+            return false;
+        }
+        return Sandman.shouldStartDockApp(context, homeIntent);
+    }
+
     private void sendConfigurationAndStartDreamOrDockAppLocked(String category) {
         // Update the configuration but don't send it yet.
         mHoldingConfiguration = false;
@@ -1983,7 +2108,7 @@
             // activity manager take care of both the start and config
             // change.
             Intent homeIntent = buildHomeIntent(category);
-            if (Sandman.shouldStartDockApp(getContext(), homeIntent)) {
+            if (shouldStartDockApp(getContext(), homeIntent)) {
                 try {
                     int result = ActivityTaskManager.getService().startActivityWithConfig(
                             null, getContext().getBasePackageName(),
diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java
index 626fa70..7e68239 100644
--- a/services/core/java/com/android/server/VpnManagerService.java
+++ b/services/core/java/com/android/server/VpnManagerService.java
@@ -19,6 +19,7 @@
 import static android.Manifest.permission.NETWORK_STACK;
 
 import static com.android.net.module.util.PermissionUtils.enforceAnyPermissionOf;
+import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPermission;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -1020,6 +1021,8 @@
     @Override
     @Nullable
     public byte[] getFromVpnProfileStore(@NonNull String name) {
+        // TODO(b/307903113): Replace NETWORK_STACK permission and adopt proper permission
+        enforceNetworkStackPermission(mContext);
         return mVpnProfileStore.get(name);
     }
 
@@ -1037,6 +1040,8 @@
      */
     @Override
     public boolean putIntoVpnProfileStore(@NonNull String name, @NonNull byte[] blob) {
+        // TODO(b/307903113): Replace NETWORK_STACK permission and adopt proper permission
+        enforceNetworkStackPermission(mContext);
         return mVpnProfileStore.put(name, blob);
     }
 
@@ -1052,6 +1057,8 @@
      */
     @Override
     public boolean removeFromVpnProfileStore(@NonNull String name) {
+        // TODO(b/307903113): Replace NETWORK_STACK permission and adopt proper permission
+        enforceNetworkStackPermission(mContext);
         return mVpnProfileStore.remove(name);
     }
 
@@ -1069,6 +1076,8 @@
     @Override
     @NonNull
     public String[] listFromVpnProfileStore(@NonNull String prefix) {
+        // TODO(b/307903113): Replace NETWORK_STACK permission and adopt proper permission
+        enforceNetworkStackPermission(mContext);
         return mVpnProfileStore.list(prefix);
     }
 
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 8e520dc..96b30d4 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -191,6 +191,9 @@
             "android.hardware.sensors.ISensors/",
             "android.hardware.vibrator.IVibrator/",
             "android.hardware.vibrator.IVibratorManager/",
+            "android.hardware.wifi.hostapd.IHostapd/",
+            "android.hardware.wifi.IWifi/",
+            "android.hardware.wifi.supplicant.ISupplicant/",
             "android.system.suspend.ISystemSuspend/",
     };
 
diff --git a/services/core/java/com/android/server/ZramMaintenance.java b/services/core/java/com/android/server/ZramMaintenance.java
deleted file mode 100644
index cdb4812..0000000
--- a/services/core/java/com/android/server/ZramMaintenance.java
+++ /dev/null
@@ -1,118 +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.server;
-
-import android.app.job.JobInfo;
-import android.app.job.JobParameters;
-import android.app.job.JobScheduler;
-import android.app.job.JobService;
-import android.content.ComponentName;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.IMmd;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.util.Slog;
-
-import java.time.Duration;
-
-/**
- * Schedules zram maintenance (e.g. zram writeback, zram recompression).
- *
- * <p>ZramMaintenance notifies mmd the good timing to execute zram maintenance based on:
- *
- * <ul>
- * <li>Enough interval has passed.
- * <li>The system is idle.
- * <li>The battery is not low.
- * </ul>
- */
-public class ZramMaintenance extends JobService {
-    private static final String TAG = ZramMaintenance.class.getName();
-    // Job id must be unique across all clients of the same uid. ZramMaintenance uses the bug number
-    // as the job id.
-    private static final int JOB_ID = 375432472;
-    private static final ComponentName sZramMaintenance =
-            new ComponentName("android", ZramMaintenance.class.getName());
-
-    private static final String FIRST_DELAY_SECONDS_PROP =
-            "mm.zram.maintenance.first_delay_seconds";
-    // The default is 1 hour.
-    private static final long DEFAULT_FIRST_DELAY_SECONDS = 3600;
-    private static final String PERIODIC_DELAY_SECONDS_PROP =
-            "mm.zram.maintenance.periodic_delay_seconds";
-    // The default is 1 hour.
-    private static final long DEFAULT_PERIODIC_DELAY_SECONDS = 3600;
-    private static final String REQUIRE_DEVICE_IDLE_PROP =
-            "mm.zram.maintenance.require_device_idle";
-    private static final boolean DEFAULT_REQUIRE_DEVICE_IDLE =
-            true;
-    private static final String REQUIRE_BATTERY_NOT_LOW_PROP =
-            "mm.zram.maintenance.require_battry_not_low";
-    private static final boolean DEFAULT_REQUIRE_BATTERY_NOT_LOW =
-            true;
-
-    @Override
-    public boolean onStartJob(JobParameters params) {
-        IBinder binder = ServiceManager.getService("mmd");
-        if (binder != null) {
-            IMmd mmd = IMmd.Stub.asInterface(binder);
-            try {
-                mmd.doZramMaintenance();
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Failed to doZramMaintenance", e);
-            }
-        } else {
-            Slog.w(TAG, "binder not found");
-        }
-        Duration delay = Duration.ofSeconds(SystemProperties.getLong(PERIODIC_DELAY_SECONDS_PROP,
-                DEFAULT_PERIODIC_DELAY_SECONDS));
-        scheduleZramMaintenance(this, delay);
-        return true;
-    }
-
-    @Override
-    public boolean onStopJob(JobParameters params) {
-        return false;
-    }
-
-    /**
-     * Starts periodical zram maintenance.
-     */
-    public static void startZramMaintenance(Context context) {
-        Duration delay = Duration.ofSeconds(
-                SystemProperties.getLong(FIRST_DELAY_SECONDS_PROP, DEFAULT_FIRST_DELAY_SECONDS));
-        scheduleZramMaintenance(context, delay);
-    }
-
-    private static void scheduleZramMaintenance(Context context, Duration delay) {
-        JobScheduler js = context.getSystemService(JobScheduler.class);
-
-        if (js != null) {
-            js.schedule(new JobInfo.Builder(JOB_ID, sZramMaintenance)
-                    .setMinimumLatency(delay.toMillis())
-                    .setRequiresDeviceIdle(
-                            SystemProperties.getBoolean(REQUIRE_DEVICE_IDLE_PROP,
-                                    DEFAULT_REQUIRE_DEVICE_IDLE))
-                    .setRequiresBatteryNotLow(
-                            SystemProperties.getBoolean(REQUIRE_BATTERY_NOT_LOW_PROP,
-                                    DEFAULT_REQUIRE_BATTERY_NOT_LOW))
-                    .build());
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index cbebc90..c237897 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -4279,7 +4279,6 @@
     }
 
     int runClearBadProcess(PrintWriter pw) throws RemoteException {
-        final String processName = getNextArgRequired();
         int userId = UserHandle.USER_CURRENT;
         String opt;
         while ((opt = getNextOption()) != null) {
@@ -4290,6 +4289,7 @@
                 return -1;
             }
         }
+        final String processName = getNextArgRequired();
         if (userId == UserHandle.USER_CURRENT) {
             userId = mInternal.getCurrentUserId();
         }
diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java
index 374abe0..0bc816e 100644
--- a/services/core/java/com/android/server/am/AppBatteryTracker.java
+++ b/services/core/java/com/android/server/am/AppBatteryTracker.java
@@ -818,8 +818,10 @@
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix);
         pw.println("APP BATTERY STATE TRACKER:");
-        // Force an update.
-        updateBatteryUsageStatsIfNecessary(mInjector.currentTimeMillis(), true);
+        if (mInjector.getActivityManagerInternal().isBooted()) {
+            // Force an update.
+            updateBatteryUsageStatsIfNecessary(mInjector.currentTimeMillis(), true);
+        }
         // Force a check.
         scheduleBgBatteryUsageStatsCheck();
         // Wait for its completion (as it runs in handler thread for the sake of thread safe)
@@ -878,8 +880,10 @@
 
     @Override
     void dumpAsProto(ProtoOutputStream proto, int uid) {
-        // Force an update.
-        updateBatteryUsageStatsIfNecessary(mInjector.currentTimeMillis(), true);
+        if (mInjector.getActivityManagerInternal().isBooted()) {
+            // Force an update.
+            updateBatteryUsageStatsIfNecessary(mInjector.currentTimeMillis(), true);
+        }
         synchronized (mLock) {
             final SparseArray<ImmutableBatteryUsage> uidConsumers = mUidBatteryUsageInWindow;
             if (uid != android.os.Process.INVALID_UID) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 644077a..c8b0a57 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -526,6 +526,8 @@
     }
 
     public void systemServicesReady() {
+        mStats.setBatteryHistoryCompressionEnabled(
+                Flags.extendedBatteryHistoryCompressionEnabled());
         mStats.saveBatteryUsageStatsOnReset(mBatteryUsageStatsProvider, mPowerStatsStore,
                 isBatteryUsageStatsAccumulationSupported());
         mStats.resetBatteryHistoryOnNewSession(
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 5184a2c..c633830 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -186,8 +186,10 @@
         "core_libraries",
         "crumpet",
         "dck_framework",
+        "desktop_connectivity",
         "desktop_hwsec",
         "desktop_stats",
+        "desktop_wifi",
         "devoptions_settings",
         "game",
         "gpu",
@@ -218,6 +220,7 @@
         "pixel_continuity",
         "pixel_display",
         "pixel_perf",
+        "pixel_sensai",
         "pixel_sensors",
         "pixel_state_server",
         "pixel_system_sw_video",
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 27e9e44..e0fbaf4 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -31,6 +31,7 @@
 import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
 import static android.app.ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE;
 import static android.app.ActivityManagerInternal.ALLOW_PROFILES_OR_NON_FULL;
+import static android.app.KeyguardManager.LOCK_ON_USER_SWITCH_CALLBACK;
 import static android.os.PowerWhitelistManager.REASON_BOOT_COMPLETED;
 import static android.os.PowerWhitelistManager.REASON_LOCKED_BOOT_COMPLETED;
 import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
@@ -3904,10 +3905,6 @@
             return mService.mWindowManager;
         }
 
-        ActivityTaskManagerInternal getActivityTaskManagerInternal() {
-            return mService.mAtmInternal;
-        }
-
         void activityManagerOnUserStopped(@UserIdInt int userId) {
             LocalServices.getService(ActivityTaskManagerInternal.class).onUserStopped(userId);
         }
@@ -4122,40 +4119,25 @@
         }
 
         void lockDeviceNowAndWaitForKeyguardShown() {
-            if (getWindowManager().isKeyguardLocked()) {
-                Slogf.w(TAG, "Not locking the device since the keyguard is already locked");
-                return;
-            }
-
             final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
             t.traceBegin("lockDeviceNowAndWaitForKeyguardShown");
 
             final CountDownLatch latch = new CountDownLatch(1);
-            ActivityTaskManagerInternal.ScreenObserver screenObserver =
-                    new ActivityTaskManagerInternal.ScreenObserver() {
-                        @Override
-                        public void onAwakeStateChanged(boolean isAwake) {
-
-                        }
-
-                        @Override
-                        public void onKeyguardStateChanged(boolean isShowing) {
-                            if (isShowing) {
-                                latch.countDown();
-                            }
-                        }
-                    };
-
-            getActivityTaskManagerInternal().registerScreenObserver(screenObserver);
-            getWindowManager().lockDeviceNow();
+            Bundle bundle = new Bundle();
+            bundle.putBinder(LOCK_ON_USER_SWITCH_CALLBACK, new IRemoteCallback.Stub() {
+                public void sendResult(Bundle data) {
+                    latch.countDown();
+                }
+            });
+            getWindowManager().lockNow(bundle);
             try {
                 if (!latch.await(20, TimeUnit.SECONDS)) {
-                    throw new RuntimeException("Keyguard is not shown in 20 seconds");
+                    throw new RuntimeException("User controller expected a callback while waiting "
+                            + "to show the keyguard. Timed out after 20 seconds.");
                 }
             } catch (InterruptedException e) {
                 throw new RuntimeException(e);
             } finally {
-                getActivityTaskManagerInternal().unregisterScreenObserver(screenObserver);
                 t.traceEnd();
             }
         }
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index e8a2226..32c4e9b 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -551,6 +551,11 @@
     @VisibleForTesting
     final Constants mConstants;
 
+    /**
+     * Some processes in the user may still be running when trying to drop the user's state
+     */
+    private static final long REMOVE_USER_DELAY = 5000L;
+
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
     final class UidState {
         public final int uid;
@@ -6820,14 +6825,17 @@
     @Override
     public void removeUser(int userHandle) throws RemoteException {
         checkSystemUid("removeUser");
-        synchronized (AppOpsService.this) {
-            final int tokenCount = mOpUserRestrictions.size();
-            for (int i = tokenCount - 1; i >= 0; i--) {
-                ClientUserRestrictionState opRestrictions = mOpUserRestrictions.valueAt(i);
-                opRestrictions.removeUser(userHandle);
+        mHandler.postDelayed(() -> {
+            Slog.i(TAG, "Removing user " + userHandle + " from AppOpsService");
+            synchronized (AppOpsService.this) {
+                final int tokenCount = mOpUserRestrictions.size();
+                for (int i = tokenCount - 1; i >= 0; i--) {
+                    ClientUserRestrictionState opRestrictions = mOpUserRestrictions.valueAt(i);
+                    opRestrictions.removeUser(userHandle);
+                }
+                removeUidsForUserLocked(userHandle);
             }
-            removeUidsForUserLocked(userHandle);
-        }
+        }, REMOVE_USER_DELAY);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/audio/AudioManagerShellCommand.java b/services/core/java/com/android/server/audio/AudioManagerShellCommand.java
index fece7a8..ae961b5 100644
--- a/services/core/java/com/android/server/audio/AudioManagerShellCommand.java
+++ b/services/core/java/com/android/server/audio/AudioManagerShellCommand.java
@@ -83,6 +83,8 @@
                 return setGroupVolume();
             case "adj-group-volume":
                 return adjGroupVolume();
+            case "set-hardening":
+                return setEnableHardening();
         }
         return 0;
     }
@@ -130,6 +132,8 @@
         pw.println("    Sets the volume for GROUP_ID to VOLUME_INDEX");
         pw.println("  adj-group-volume GROUP_ID <RAISE|LOWER|MUTE|UNMUTE>");
         pw.println("    Adjusts the group volume for GROUP_ID given the specified direction");
+        pw.println("  set-enable-hardening <1|0>");
+        pw.println("    Enables full audio hardening enforcement, disabling any exemptions");
     }
 
     private int setSurroundFormatEnabled() {
@@ -405,6 +409,20 @@
         return 0;
     }
 
+    private int setEnableHardening() {
+        final Context context = mService.mContext;
+        final AudioManager am = context.getSystemService(AudioManager.class);
+        final boolean shouldEnable = !(readIntArg() == 0);
+        getOutPrintWriter().println(
+                "calling AudioManager.setEnableHardening(" + shouldEnable + ")");
+        try {
+            am.setEnableHardening(shouldEnable);
+        } catch (Exception e) {
+            getOutPrintWriter().println("Exception: " + e);
+        }
+        return 0;
+    }
+
     private int readIntArg() throws IllegalArgumentException {
         final String argText = getNextArg();
 
diff --git a/services/core/java/com/android/server/audio/AudioPolicyFacade.java b/services/core/java/com/android/server/audio/AudioPolicyFacade.java
index f652b33..6c0b81f 100644
--- a/services/core/java/com/android/server/audio/AudioPolicyFacade.java
+++ b/services/core/java/com/android/server/audio/AudioPolicyFacade.java
@@ -26,4 +26,5 @@
     public boolean isHotwordStreamSupported(boolean lookbackAudio);
     public INativePermissionController getPermissionController();
     public void registerOnStartTask(Runnable r);
+    public void setEnableHardening(boolean shouldEnable);
 }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index f283009..02e0d9f 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -781,7 +781,8 @@
     private int mRingerModeExternal = -1;  // reported ringer mode to outside clients (AudioManager)
 
     /** @see System#MODE_RINGER_STREAMS_AFFECTED */
-    private int mRingerModeAffectedStreams = 0;
+    @VisibleForTesting
+    protected int mRingerModeAffectedStreams = 0;
 
     private int mZenModeAffectedStreams = 0;
 
@@ -1191,6 +1192,11 @@
     private @AttributeSystemUsage int[] mSupportedSystemUsages =
             new int[]{AudioAttributes.USAGE_CALL_ASSISTANT};
 
+    // Tracks the API/shell override of hardening enforcement used for debugging
+    // When this is set to true, enforcement is on regardless of flag state and any specific
+    // exemptions in place for compat purposes.
+    private final AtomicBoolean mShouldEnableAllHardening = new AtomicBoolean(false);
+
     // Defines the format for the connection "address" for ALSA devices
     public static String makeAlsaAddressString(int card, int device) {
         return "card=" + card + ";device=" + device;
@@ -1334,6 +1340,10 @@
         mAudioVolumeGroupHelper = audioVolumeGroupHelper;
         mSettings = settings;
         mAudioPolicy = audioPolicy;
+        mAudioPolicy.registerOnStartTask(() -> {
+            mAudioPolicy.setEnableHardening(mShouldEnableAllHardening.get());
+        });
+
         mPlatformType = AudioSystem.getPlatformType(context);
 
         mBroadcastHandlerThread = new HandlerThread("AudioService Broadcast");
@@ -6315,17 +6325,15 @@
                     }
                 }
                 sRingerAndZenModeMutedStreams &= ~(1 << streamType);
-                sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent(
-                        sRingerAndZenModeMutedStreams, "muteRingerModeStreams"));
                 vss.mute(false, "muteRingerModeStreams");
             } else {
                 // mute
                 sRingerAndZenModeMutedStreams |= (1 << streamType);
-                sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent(
-                        sRingerAndZenModeMutedStreams, "muteRingerModeStreams"));
                 vss.mute(true, "muteRingerModeStreams");
             }
         }
+        sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent(
+                sRingerAndZenModeMutedStreams, "muteRingerModeStreams"));
     }
 
     private boolean isAlarm(int streamType) {
@@ -10045,12 +10053,14 @@
                             new AudioServiceEvents.StreamMuteEvent(mStreamType, state, src));
                     // check to see if unmuting should not have happened due to ringer muted streams
                     if (!state && isStreamMutedByRingerOrZenMode(mStreamType)) {
-                        Log.e(TAG, "Unmuting stream " + mStreamType
+                        Slog.e(TAG, "Attempt to unmute stream " + mStreamType
                                 + " despite ringer-zen muted stream 0x"
                                 + Integer.toHexString(AudioService.sRingerAndZenModeMutedStreams),
                                 new Exception()); // this will put a stack trace in the logs
                         sMuteLogger.enqueue(new AudioServiceEvents.StreamUnmuteErrorEvent(
                                 mStreamType, AudioService.sRingerAndZenModeMutedStreams));
+                        // do not change mute state
+                        return false;
                     }
                     mIsMuted = state;
                     if (apply) {
@@ -15019,6 +15029,16 @@
         return true;
     }
 
+    /**
+     * @see AudioManager#setEnableHardening(boolean)
+     */
+    @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
+    public void setEnableHardening(boolean shouldEnable) {
+        super.setEnableHardening_enforcePermission();
+        mShouldEnableAllHardening.set(shouldEnable);
+        mAudioPolicy.setEnableHardening(shouldEnable);
+    }
+
     //======================
     // Audioserver state dispatch
     //======================
diff --git a/services/core/java/com/android/server/audio/DefaultAudioPolicyFacade.java b/services/core/java/com/android/server/audio/DefaultAudioPolicyFacade.java
index 09701e4..c41f41e 100644
--- a/services/core/java/com/android/server/audio/DefaultAudioPolicyFacade.java
+++ b/services/core/java/com/android/server/audio/DefaultAudioPolicyFacade.java
@@ -80,4 +80,14 @@
     public void registerOnStartTask(Runnable task) {
         mServiceHolder.registerOnStartTask(unused -> task.run());
     }
+
+    @Override
+    public void setEnableHardening(boolean shouldEnable) {
+        IAudioPolicyService ap = mServiceHolder.waitForService();
+        try {
+            ap.setEnableHardening(shouldEnable);
+        } catch (RemoteException e) {
+            mServiceHolder.attemptClear(ap.asBinder());
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/biometrics/PreAuthInfo.java b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
index c739118..6fab7e6 100644
--- a/services/core/java/com/android/server/biometrics/PreAuthInfo.java
+++ b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
@@ -164,6 +164,7 @@
                 Slog.d(TAG, "Package: " + opPackageName
                         + " Sensor ID: " + sensor.id
                         + " Modality: " + sensor.modality
+                        + " User id: " + effectiveUserId
                         + " Status: " + status);
 
                 // A sensor with privacy enabled will still be eligible to
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 49b451a..e83efc5 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -107,6 +107,7 @@
 import android.hardware.display.DisplayManagerInternal.DisplayGroupListener;
 import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
 import android.hardware.display.DisplayTopology;
+import android.hardware.display.DisplayTopologyGraph;
 import android.hardware.display.DisplayViewport;
 import android.hardware.display.DisplayedContentSample;
 import android.hardware.display.DisplayedContentSamplingAttributes;
@@ -292,6 +293,7 @@
     private final DisplayModeDirector mDisplayModeDirector;
     private final ExternalDisplayPolicy mExternalDisplayPolicy;
     private WindowManagerInternal mWindowManagerInternal;
+    @Nullable
     private InputManagerInternal mInputManagerInternal;
     private ActivityManagerInternal mActivityManagerInternal;
     private final UidImportanceListener mUidImportanceListener = new UidImportanceListener();
@@ -680,8 +682,15 @@
         mExternalDisplayPolicy = new ExternalDisplayPolicy(new ExternalDisplayPolicyInjector());
         if (mFlags.isDisplayTopologyEnabled()) {
             final var backupManager = new BackupManager(mContext);
+            Consumer<Pair<DisplayTopology, DisplayTopologyGraph>> topologyChangedCallback =
+                    update -> {
+                        if (mInputManagerInternal != null) {
+                            mInputManagerInternal.setDisplayTopology(update.second);
+                        }
+                        deliverTopologyUpdate(update.first);
+                    };
             mDisplayTopologyCoordinator = new DisplayTopologyCoordinator(
-                    this::isExtendedDisplayEnabled, this::deliverTopologyUpdate,
+                    this::isExtendedDisplayEnabled, topologyChangedCallback,
                     new HandlerExecutor(mHandler), mSyncRoot, backupManager::dataChanged);
         } else {
             mDisplayTopologyCoordinator = null;
diff --git a/services/core/java/com/android/server/display/DisplayTopologyCoordinator.java b/services/core/java/com/android/server/display/DisplayTopologyCoordinator.java
index c73ab32..2618cf4 100644
--- a/services/core/java/com/android/server/display/DisplayTopologyCoordinator.java
+++ b/services/core/java/com/android/server/display/DisplayTopologyCoordinator.java
@@ -19,8 +19,11 @@
 import static android.hardware.display.DisplayTopology.pxToDp;
 
 import android.hardware.display.DisplayTopology;
+import android.hardware.display.DisplayTopologyGraph;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseIntArray;
 import android.view.Display;
 import android.view.DisplayInfo;
 
@@ -53,6 +56,12 @@
 
     @GuardedBy("mSyncRoot")
     private DisplayTopology mTopology;
+
+    // Map from logical display ID to logical display density. Should always be consistent with
+    // mTopology.
+    @GuardedBy("mSyncRoot")
+    private final SparseIntArray mDensities = new SparseIntArray();
+
     @GuardedBy("mSyncRoot")
     private final Map<String, Integer> mUniqueIdToDisplayIdMapping = new HashMap<>();
 
@@ -69,13 +78,13 @@
      * Should be invoked from the corresponding executor.
      * A copy of the topology should be sent that will not be modified by the system.
      */
-    private final Consumer<DisplayTopology> mOnTopologyChangedCallback;
+    private final Consumer<Pair<DisplayTopology, DisplayTopologyGraph>> mOnTopologyChangedCallback;
     private final Executor mTopologyChangeExecutor;
     private final DisplayManagerService.SyncRoot mSyncRoot;
     private final Runnable mTopologySavedCallback;
 
     DisplayTopologyCoordinator(BooleanSupplier isExtendedDisplayEnabled,
-            Consumer<DisplayTopology> onTopologyChangedCallback,
+            Consumer<Pair<DisplayTopology, DisplayTopologyGraph>> onTopologyChangedCallback,
             Executor topologyChangeExecutor, DisplayManagerService.SyncRoot syncRoot,
             Runnable topologySavedCallback) {
         this(new Injector(), isExtendedDisplayEnabled, onTopologyChangedCallback,
@@ -84,7 +93,7 @@
 
     @VisibleForTesting
     DisplayTopologyCoordinator(Injector injector, BooleanSupplier isExtendedDisplayEnabled,
-            Consumer<DisplayTopology> onTopologyChangedCallback,
+            Consumer<Pair<DisplayTopology, DisplayTopologyGraph>> onTopologyChangedCallback,
             Executor topologyChangeExecutor, DisplayManagerService.SyncRoot syncRoot,
             Runnable topologySavedCallback) {
         mTopology = injector.getTopology();
@@ -107,7 +116,7 @@
         }
         synchronized (mSyncRoot) {
             addDisplayIdMappingLocked(info);
-
+            mDensities.put(info.displayId, info.logicalDensityDpi);
             mTopology.addDisplay(info.displayId, getWidth(info), getHeight(info));
             restoreTopologyLocked();
             sendTopologyUpdateLocked();
@@ -119,7 +128,13 @@
      * @param info The new display info
      */
     void onDisplayChanged(DisplayInfo info) {
+        if (!isDisplayAllowedInTopology(info)) {
+            return;
+        }
         synchronized (mSyncRoot) {
+            if (mDensities.indexOfKey(info.displayId) >= 0) {
+                mDensities.put(info.displayId, info.logicalDensityDpi);
+            }
             if (mTopology.updateDisplay(info.displayId, getWidth(info), getHeight(info))) {
                 sendTopologyUpdateLocked();
             }
@@ -132,6 +147,7 @@
      */
     void onDisplayRemoved(int displayId) {
         synchronized (mSyncRoot) {
+            mDensities.delete(displayId);
             if (mTopology.removeDisplay(displayId)) {
                 removeDisplayIdMappingLocked(displayId);
                 restoreTopologyLocked();
@@ -234,8 +250,29 @@
     }
 
     private boolean isDisplayAllowedInTopology(DisplayInfo info) {
-        return mIsExtendedDisplayEnabled.getAsBoolean()
-                && info.displayGroupId == Display.DEFAULT_DISPLAY_GROUP;
+        if (info.type != Display.TYPE_INTERNAL && info.type != Display.TYPE_EXTERNAL
+                && info.type != Display.TYPE_OVERLAY) {
+            Slog.d(TAG, "Display " + info.displayId + " not allowed in topology because "
+                    + "type is not INTERNAL, EXTERNAL or OVERLAY");
+            return false;
+        }
+        if (info.type == Display.TYPE_INTERNAL && info.displayId != Display.DEFAULT_DISPLAY) {
+            Slog.d(TAG, "Display " + info.displayId + " not allowed in topology because "
+                    + "it is a non-default internal display");
+            return false;
+        }
+        if ((info.type == Display.TYPE_EXTERNAL || info.type == Display.TYPE_OVERLAY)
+                && !mIsExtendedDisplayEnabled.getAsBoolean()) {
+            Slog.d(TAG, "Display " + info.displayId + " not allowed in topology because "
+                    + "type is EXTERNAL or OVERLAY and !mIsExtendedDisplayEnabled");
+            return false;
+        }
+        if (info.displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
+            Slog.d(TAG, "Display " + info.displayId + " not allowed in topology because "
+                    + "it is not in the default display group");
+            return false;
+        }
+        return true;
     }
 
     /**
@@ -256,7 +293,9 @@
     @GuardedBy("mSyncRoot")
     private void sendTopologyUpdateLocked() {
         DisplayTopology copy = mTopology.copy();
-        mTopologyChangeExecutor.execute(() -> mOnTopologyChangedCallback.accept(copy));
+        SparseIntArray densities = mDensities.clone();
+        mTopologyChangeExecutor.execute(() -> mOnTopologyChangedCallback.accept(
+                new Pair<>(copy, copy.getGraph(densities))));
     }
 
     @VisibleForTesting
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 52e6490..87eacc9 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -132,6 +132,12 @@
     private static final int NOT_SET = -1;
 
     /**
+     * Min and Max values for percentage of RBC setting.
+     */
+    private static final int PERCENTAGE_MIN = 0;
+    private static final int PERCENTAGE_MAX = 100;
+
+    /**
      * Evaluator used to animate color matrix transitions.
      */
     private static final ColorMatrixEvaluator COLOR_MATRIX_EVALUATOR = new ColorMatrixEvaluator();
@@ -696,15 +702,25 @@
         if (mCurrentUser == UserHandle.USER_NULL) {
             return;
         }
-        int strength = Secure.getIntForUser(getContext().getContentResolver(),
+
+        int percentage = Secure.getIntForUser(getContext().getContentResolver(),
                 Secure.REDUCE_BRIGHT_COLORS_LEVEL, NOT_SET, mCurrentUser);
-        if (strength == NOT_SET) {
-            strength = getContext().getResources().getInteger(
+        final int deviceRange;
+
+        if (percentage == NOT_SET) {
+            deviceRange = getContext().getResources().getInteger(
                     R.integer.config_reduceBrightColorsStrengthDefault);
+        } else {
+            final int deviceMin = getContext().getResources().getInteger(
+                    R.integer.config_reduceBrightColorsStrengthMin);
+            final int deviceMax = getContext().getResources().getInteger(
+                    R.integer.config_reduceBrightColorsStrengthMax);
+            deviceRange = (int) MathUtils.constrainedMap(
+                    deviceMin, deviceMax, PERCENTAGE_MIN, PERCENTAGE_MAX, percentage);
         }
-        mReduceBrightColorsTintController.setMatrix(strength);
+        mReduceBrightColorsTintController.setMatrix(deviceRange);
         if (mReduceBrightColorsListener != null) {
-            mReduceBrightColorsListener.onReduceBrightColorsStrengthChanged(strength);
+            mReduceBrightColorsListener.onReduceBrightColorsStrengthChanged(deviceRange);
         }
     }
 
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 373287d..a1e8f08 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -61,7 +61,7 @@
 
     private final FlagState mDisplayTopology = new FlagState(
             Flags.FLAG_DISPLAY_TOPOLOGY,
-            Flags::displayTopology);
+            DesktopExperienceFlags.DISPLAY_TOPOLOGY::isTrue);
 
     private final FlagState mConnectedDisplayErrorHandlingFlagState = new FlagState(
             Flags.FLAG_ENABLE_CONNECTED_DISPLAY_ERROR_HANDLING,
@@ -267,7 +267,7 @@
 
     private final FlagState mBaseDensityForExternalDisplays = new FlagState(
             Flags.FLAG_BASE_DENSITY_FOR_EXTERNAL_DISPLAYS,
-            Flags::baseDensityForExternalDisplays
+            DesktopExperienceFlags.BASE_DENSITY_FOR_EXTERNAL_DISPLAYS::isTrue
     );
 
     private final FlagState mFramerateOverrideTriggersRrCallbacks = new FlagState(
diff --git a/services/core/java/com/android/server/input/KeyGestureController.java b/services/core/java/com/android/server/input/KeyGestureController.java
index fb5ce5b..41f58ae 100644
--- a/services/core/java/com/android/server/input/KeyGestureController.java
+++ b/services/core/java/com/android/server/input/KeyGestureController.java
@@ -809,7 +809,7 @@
                     if (firstDown) {
                         handleKeyGesture(deviceId, new int[]{KeyEvent.KEYCODE_FULLSCREEN},
                                 /* modifierState = */0,
-                                KeyGestureEvent.KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW,
+                                KeyGestureEvent.KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION,
                                 KeyGestureEvent.ACTION_GESTURE_COMPLETE, displayId, focusedToken,
                                 /* flags = */0, /* appLaunchData = */null);
                     }
diff --git a/services/core/java/com/android/server/inputmethod/ImeProtoLogGroup.java b/services/core/java/com/android/server/inputmethod/ImeProtoLogGroup.java
new file mode 100644
index 0000000..f9a56ef
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/ImeProtoLogGroup.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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 com.android.internal.protolog.common.IProtoLogGroup;
+
+import java.util.UUID;
+
+public enum ImeProtoLogGroup implements IProtoLogGroup {
+    // TODO(b/393561240): add info/warn/error log level and replace in IMMS
+    IMMS_DEBUG(Consts.ENABLE_DEBUG, false, false,
+            InputMethodManagerService.TAG);
+
+    private final boolean mEnabled;
+    private volatile boolean mLogToProto;
+    private volatile boolean mLogToLogcat;
+    private final String mTag;
+
+    ImeProtoLogGroup(boolean enabled, boolean logToProto, boolean logToLogcat, String tag) {
+        this.mEnabled = enabled;
+        this.mLogToProto = logToProto;
+        this.mLogToLogcat = logToLogcat;
+        this.mTag = tag;
+    }
+
+
+    @Override
+    public boolean isEnabled() {
+        return mEnabled;
+    }
+
+    @Override
+    public boolean isLogToProto() {
+        return mLogToProto;
+    }
+
+    @Override
+    public boolean isLogToLogcat() {
+        return mLogToLogcat;
+    }
+
+    @Override
+    public String getTag() {
+        return mTag;
+    }
+
+    @Override
+    public int getId() {
+        return Consts.START_ID + ordinal();
+    }
+
+    @Override
+    public void setLogToProto(boolean logToProto) {
+        mLogToProto = logToProto;
+    }
+
+    @Override
+    public void setLogToLogcat(boolean logToLogcat) {
+        mLogToLogcat = logToLogcat;
+    }
+
+    private static class Consts {
+        private static final boolean ENABLE_DEBUG = true;
+        private static final int START_ID = (int) (
+                UUID.nameUUIDFromBytes(ImeProtoLogGroup.class.getName().getBytes())
+                        .getMostSignificantBits() % Integer.MAX_VALUE);
+    }
+}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 7b81fc9..484b470 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -47,6 +47,7 @@
 import static android.view.inputmethod.ConnectionlessHandwritingCallback.CONNECTIONLESS_HANDWRITING_ERROR_OTHER;
 import static android.view.inputmethod.ConnectionlessHandwritingCallback.CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED;
 
+import static com.android.server.inputmethod.ImeProtoLogGroup.IMMS_DEBUG;
 import static com.android.server.inputmethod.ImeVisibilityStateComputer.ImeTargetWindowState;
 import static com.android.server.inputmethod.ImeVisibilityStateComputer.ImeVisibilityResult;
 import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_HIDE_IME;
@@ -176,6 +177,7 @@
 import com.android.internal.inputmethod.StartInputReason;
 import com.android.internal.inputmethod.UnbindReason;
 import com.android.internal.os.TransferPipe;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.DumpUtils;
@@ -720,9 +722,7 @@
      */
     @WorkerThread
     void onActionLocaleChanged(@NonNull LocaleList prevLocales, @NonNull LocaleList newLocales) {
-        if (DEBUG) {
-            Slog.d(TAG, "onActionLocaleChanged prev=" + prevLocales + " new=" + newLocales);
-        }
+        ProtoLog.v(IMMS_DEBUG, "onActionLocaleChanged prev=%s new=%s", prevLocales, newLocales);
         synchronized (ImfLock.class) {
             if (!mSystemReady) {
                 return;
@@ -1251,6 +1251,8 @@
 
             mShowOngoingImeSwitcherForPhones = false;
 
+            ProtoLog.init(ImeProtoLogGroup.values());
+
             mCurrentImeUserId = mActivityManagerInternal.getCurrentUserId();
             final IntFunction<InputMethodBindingController>
                     bindingControllerFactory = userId -> new InputMethodBindingController(userId,
@@ -1328,9 +1330,7 @@
             return;
         }
         final InputMethodInfo defIm = suitableImes.get(0);
-        if (DEBUG) {
-            Slog.i(TAG, "Default found, using " + defIm.getId());
-        }
+        ProtoLog.v(IMMS_DEBUG, "Default found, using %s", defIm.getId());
         setSelectedInputMethodAndSubtypeLocked(defIm, NOT_A_SUBTYPE_INDEX, false, userId);
     }
 
@@ -1347,10 +1347,8 @@
     private void switchUserOnHandlerLocked(@UserIdInt int newUserId,
             IInputMethodClientInvoker clientToBeReset) {
         final int prevUserId = mCurrentImeUserId;
-        if (DEBUG) {
-            Slog.d(TAG, "Switching user stage 1/3. newUserId=" + newUserId
-                    + " prevUserId=" + prevUserId);
-        }
+        ProtoLog.v(IMMS_DEBUG, "Switching user stage 1/3. newUserId=%s prevUserId=%s", newUserId,
+                prevUserId);
 
         // Clean up stuff for mCurrentImeUserId, which soon becomes the previous user.
 
@@ -1375,10 +1373,8 @@
         final String defaultImiId = SecureSettingsWrapper.getString(
                 Settings.Secure.DEFAULT_INPUT_METHOD, null, newUserId);
 
-        if (DEBUG) {
-            Slog.d(TAG, "Switching user stage 2/3. newUserId=" + newUserId
-                    + " defaultImiId=" + defaultImiId);
-        }
+        ProtoLog.v(IMMS_DEBUG, "Switching user stage 2/3. newUserId=%s defaultImiId=%s", newUserId,
+                defaultImiId);
 
         // For secondary users, the list of enabled IMEs may not have been updated since the
         // callbacks to PackageMonitor are ignored for the secondary user. Here, defaultImiId may
@@ -1414,10 +1410,8 @@
                     newSettings.getEnabledInputMethodList());
         }
 
-        if (DEBUG) {
-            Slog.d(TAG, "Switching user stage 3/3. newUserId=" + newUserId
-                    + " selectedIme=" + newSettings.getSelectedInputMethod());
-        }
+        ProtoLog.v(IMMS_DEBUG, "Switching user stage 3/3. newUserId=%s selectedIme=%s", newUserId,
+                newSettings.getSelectedInputMethod());
 
         if (mIsInteractive && clientToBeReset != null) {
             final ClientState cs = mClientController.getClient(clientToBeReset.asBinder());
@@ -1466,9 +1460,7 @@
         waitForUserInitialization();
 
         synchronized (ImfLock.class) {
-            if (DEBUG) {
-                Slog.d(TAG, "--- systemReady");
-            }
+            ProtoLog.v(IMMS_DEBUG, "--- systemReady");
             if (!mSystemReady) {
                 mSystemReady = true;
                 final int currentImeUserId = mCurrentImeUserId;
@@ -1844,10 +1836,8 @@
     void unbindCurrentClientLocked(@UnbindReason int unbindClientReason, @UserIdInt int userId) {
         final var userData = getUserData(userId);
         if (userData.mCurClient != null) {
-            if (DEBUG) {
-                Slog.v(TAG, "unbindCurrentInputLocked: client="
-                        + userData.mCurClient.mClient.asBinder());
-            }
+            ProtoLog.v(IMMS_DEBUG, "unbindCurrentInputLocked: client=%s",
+                    userData.mCurClient.mClient.asBinder());
             final var bindingController = userData.mBindingController;
             if (userData.mBoundToMethod) {
                 userData.mBoundToMethod = false;
@@ -1970,7 +1960,7 @@
             }
         } else {
             if (isShowRequestedForCurrentWindow(userId)) {
-                if (DEBUG) Slog.v(TAG, "Attach new input asks to show input");
+                ProtoLog.v(IMMS_DEBUG, "Attach new input asks to show input");
                 // Re-use current statsToken, if it exists.
                 final var statsToken = userData.mCurStatsToken != null ? userData.mCurStatsToken
                     : createStatsTokenForFocusedClient(true /* show */,
@@ -2130,9 +2120,7 @@
         // If configured, we want to avoid starting up the IME if it is not supposed to be showing
         if (shouldPreventImeStartupLocked(selectedMethodId, startInputFlags,
                 unverifiedTargetSdkVersion, userId)) {
-            if (DEBUG) {
-                Slog.d(TAG, "Avoiding IME startup and unbinding current input method.");
-            }
+            ProtoLog.v(IMMS_DEBUG, "Avoiding IME startup and unbinding current input method.");
             bindingController.invalidateAutofillSession();
             bindingController.unbindCurrentMethod();
             return InputBindResult.NO_EDITOR;
@@ -2215,9 +2203,8 @@
                 return currentMethodId;
             }
             final String defaultDeviceMethodId = settings.getSelectedDefaultDeviceInputMethod();
-            if (DEBUG) {
-                Slog.v(TAG, "Restoring default device input method: " + defaultDeviceMethodId);
-            }
+            ProtoLog.v(IMMS_DEBUG, "Restoring default device input method: %s",
+                    defaultDeviceMethodId);
             settings.putSelectedDefaultDeviceInputMethod(null);
             return defaultDeviceMethodId;
         }
@@ -2226,24 +2213,21 @@
         if (Objects.equals(deviceMethodId, currentMethodId)) {
             return currentMethodId;
         } else if (!settings.getMethodMap().containsKey(deviceMethodId)) {
-            if (DEBUG) {
-                Slog.v(TAG, "Disabling IME on virtual device with id " + newDeviceId
-                        + " because its custom input method is not available: " + deviceMethodId);
-            }
+            ProtoLog.v(IMMS_DEBUG,
+                    "Disabling IME on virtual device with id %s because its custom input method "
+                            + "is not available: %s",
+                    newDeviceId, deviceMethodId);
             return null;
         }
 
         if (oldDeviceId == DEVICE_ID_DEFAULT) {
-            if (DEBUG) {
-                Slog.v(TAG, "Storing default device input method " + currentMethodId);
-            }
+            ProtoLog.v(IMMS_DEBUG, "Storing default device input method %s", currentMethodId);
             settings.putSelectedDefaultDeviceInputMethod(currentMethodId);
         }
-        if (DEBUG) {
-            Slog.v(TAG, "Switching current input method from " + currentMethodId
-                    + " to device-specific one " + deviceMethodId + " because the current display "
-                    + displayIdToShowIme + " belongs to device with id " + newDeviceId);
-        }
+        ProtoLog.v(IMMS_DEBUG,
+                "Switching current input method from %s to device-specific one %s because the "
+                        + "current display %s belongs to device with id %s",
+                currentMethodId, deviceMethodId, displayIdToShowIme, newDeviceId);
         return deviceMethodId;
     }
 
@@ -2387,10 +2371,8 @@
     @GuardedBy("ImfLock.class")
     void initializeImeLocked(@NonNull IInputMethodInvoker inputMethod, @NonNull IBinder token,
             @NonNull InputMethodBindingController bindingController) {
-        if (DEBUG) {
-            Slog.v(TAG, "Sending attach of token: " + token + " for display: "
-                    + bindingController.getCurTokenDisplayId());
-        }
+        ProtoLog.v(IMMS_DEBUG, "Sending attach of token: %s for display: %s", token,
+                bindingController.getCurTokenDisplayId());
         final int userId = bindingController.getUserId();
         final var userData = getUserData(userId);
         inputMethod.initializeInternal(token,
@@ -2500,7 +2482,7 @@
     @GuardedBy("ImfLock.class")
     void requestClientSessionLocked(ClientState cs, @UserIdInt int userId) {
         if (!cs.mSessionRequested) {
-            if (DEBUG) Slog.v(TAG, "Creating new session for client " + cs);
+            ProtoLog.v(IMMS_DEBUG, "Creating new session for client %s", cs);
             final InputChannel serverChannel;
             final InputChannel clientChannel;
             {
@@ -2541,7 +2523,7 @@
     @GuardedBy("ImfLock.class")
     void requestClientSessionForAccessibilityLocked(ClientState cs) {
         if (!cs.mSessionRequestedForAccessibility) {
-            if (DEBUG) Slog.v(TAG, "Creating new accessibility sessions for client " + cs);
+            ProtoLog.v(IMMS_DEBUG, "Creating new accessibility sessions for client %s", cs);
             cs.mSessionRequestedForAccessibility = true;
             ArraySet<Integer> ignoreSet = new ArraySet<>();
             for (int i = 0; i < cs.mAccessibilitySessions.size(); i++) {
@@ -2656,10 +2638,10 @@
             return;
         }
         if (iconId == 0) {
-            if (DEBUG) Slog.d(TAG, "hide the small icon for the input method");
+            ProtoLog.v(IMMS_DEBUG, "hide the small icon for the input method");
             hideStatusBarIconLocked(userId);
         } else if (packageName != null) {
-            if (DEBUG) Slog.d(TAG, "show a small icon for the input method");
+            ProtoLog.v(IMMS_DEBUG, "show a small icon for the input method");
             final PackageManager userAwarePackageManager =
                     getPackageManagerForUser(mContext, userId);
             ApplicationInfo applicationInfo = null;
@@ -2887,12 +2869,9 @@
             return;
         }
         final int curTokenDisplayId = bindingController.getCurTokenDisplayId();
-        if (DEBUG) {
-            Slog.d(TAG, "IME window vis: " + vis
-                    + " active: " + (vis & InputMethodService.IME_ACTIVE)
-                    + " visible: " + (vis & InputMethodService.IME_VISIBLE)
-                    + " displayId: " + curTokenDisplayId);
-        }
+        ProtoLog.v(IMMS_DEBUG, "IME window vis: %s active: %s visible: %s displayId: %s", vis,
+                (vis & InputMethodService.IME_ACTIVE), (vis & InputMethodService.IME_VISIBLE),
+                curTokenDisplayId);
         final IBinder focusedWindowToken = userData.mImeBindingState != null
                 ? userData.mImeBindingState.mFocusedWindow : null;
         final Boolean windowPerceptible = focusedWindowToken != null
@@ -2960,10 +2939,8 @@
                 }
                 if (ai != null && ai.enabledSetting
                         == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
-                    if (DEBUG) {
-                        Slog.d(TAG, "Update state(" + imm.getId()
-                                + "): DISABLED_UNTIL_USED -> DEFAULT");
-                    }
+                    ProtoLog.v(IMMS_DEBUG, "Update state(%s): DISABLED_UNTIL_USED -> DEFAULT",
+                            imm.getId());
                     userAwarePackageManager.setApplicationEnabledSetting(imm.getPackageName(),
                             PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
                             PackageManager.DONT_KILL_APP);
@@ -2979,11 +2956,10 @@
             String defaultDeviceIme = SecureSettingsWrapper.getString(
                     Settings.Secure.DEFAULT_DEVICE_INPUT_METHOD, null, userId);
             if (defaultDeviceIme != null && !Objects.equals(ime, defaultDeviceIme)) {
-                if (DEBUG) {
-                    Slog.v(TAG, "Current input method " + ime + " differs from the stored default"
-                            + " device input method for user " + userId
-                            + " - restoring " + defaultDeviceIme);
-                }
+                ProtoLog.v(IMMS_DEBUG,
+                        "Current input method %s differs from the stored default device input "
+                                + "method for user %s - restoring %s",
+                        ime, userId, defaultDeviceIme);
                 SecureSettingsWrapper.putString(
                         Settings.Secure.DEFAULT_INPUT_METHOD, defaultDeviceIme, userId);
                 SecureSettingsWrapper.putString(
@@ -3179,7 +3155,7 @@
         final var userData = getUserData(userId);
         final long ident = Binder.clearCallingIdentity();
         try {
-            if (DEBUG) Slog.v(TAG, "Client requesting input be shown");
+            ProtoLog.v(IMMS_DEBUG, "Client requesting input be shown");
             if (Flags.refactorInsetsController()) {
                 final var visibilityStateComputer = userData.mVisibilityStateComputer;
                 boolean wasVisible = visibilityStateComputer.isInputShown();
@@ -3211,7 +3187,7 @@
             final int userId = resolveImeUserIdFromWindowLocked(windowToken);
             final long ident = Binder.clearCallingIdentity();
             try {
-                if (DEBUG) Slog.v(TAG, "Client requesting input be shown");
+                ProtoLog.v(IMMS_DEBUG, "Client requesting input be shown");
                 return showCurrentInputLocked(windowToken, statsToken, 0 /* flags */,
                         0 /* lastClickTooType */, null /* resultReceiver */,
                         SoftInputShowHideReason.SHOW_SOFT_INPUT, userId);
@@ -3231,7 +3207,7 @@
             final int userId = resolveImeUserIdFromWindowLocked(windowToken);
             final long ident = Binder.clearCallingIdentity();
             try {
-                if (DEBUG) Slog.v(TAG, "Client requesting input be hidden");
+                ProtoLog.v(IMMS_DEBUG, "Client requesting input be hidden");
                 return hideCurrentInputLocked(windowToken, statsToken, 0 /* flags */,
                         null /* resultReceiver */, SoftInputShowHideReason.HIDE_SOFT_INPUT,
                         userId);
@@ -3365,7 +3341,7 @@
                                         + " Ignoring startStylusHandwriting().");
                         return false;
                     }
-                    if (DEBUG) Slog.v(TAG, "Client requesting Stylus Handwriting to be started");
+                    ProtoLog.v(IMMS_DEBUG, "Client requesting Stylus Handwriting to be started");
                     final IInputMethodInvoker curMethod = bindingController.getCurMethod();
                     if (curMethod != null) {
                         curMethod.canStartStylusHandwriting(requestId.getAsInt(),
@@ -3630,7 +3606,7 @@
         final long ident = Binder.clearCallingIdentity();
         try {
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideSoftInput");
-            if (DEBUG) Slog.v(TAG, "Client requesting input be hidden");
+            ProtoLog.v(IMMS_DEBUG, "Client requesting input be hidden");
             if (Flags.refactorInsetsController()) {
                 boolean wasVisible = visibilityStateComputer.isInputShown();
                 // TODO add windowToken to interface
@@ -3830,10 +3806,9 @@
                             // because if the focus changes some time before or after, the
                             // next client receiving focus that has any interest in input will
                             // be calling through here after that change happens.
-                            if (DEBUG) {
-                                Slog.w(TAG, "Focus gain on non-focused client " + cs.mClient
-                                        + " (uid=" + cs.mUid + " pid=" + cs.mPid + ")");
-                            }
+                            ProtoLog.v(IMMS_DEBUG,
+                                    "Focus gain on non-focused client %s (uid=%s pid=%s)",
+                                    cs.mClient, cs.mUid, cs.mPid);
                             return InputBindResult.NOT_IME_TARGET_WINDOW;
                         case WindowManagerInternal.ImeClientFocusResult.INVALID_DISPLAY_ID:
                             return InputBindResult.INVALID_DISPLAY_ID;
@@ -3910,21 +3885,22 @@
             @Nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
             int unverifiedTargetSdkVersion, @NonNull InputMethodBindingController bindingController,
             @NonNull ImeOnBackInvokedDispatcher imeDispatcher, @NonNull ClientState cs) {
-        if (DEBUG) {
-            Slog.v(TAG, "startInputOrWindowGainedFocusInternalLocked: reason="
-                    + InputMethodDebug.startInputReasonToString(startInputReason)
-                    + " client=" + client.asBinder()
-                    + " inputContext=" + inputContext
-                    + " editorInfo=" + editorInfo
-                    + " startInputFlags="
-                    + InputMethodDebug.startInputFlagsToString(startInputFlags)
-                    + " softInputMode=" + InputMethodDebug.softInputModeToString(softInputMode)
-                    + " windowFlags=#" + Integer.toHexString(windowFlags)
-                    + " unverifiedTargetSdkVersion=" + unverifiedTargetSdkVersion
-                    + " bindingController=" + bindingController
-                    + " imeDispatcher=" + imeDispatcher
-                    + " cs=" + cs);
-        }
+        ProtoLog.v(IMMS_DEBUG, "startInputOrWindowGainedFocusInternalLocked: reason=%s"
+                    + " client=%s"
+                    + " inputContext=%s"
+                    + " editorInfo=%s"
+                    + " startInputFlags=%s"
+                    + " softInputMode=%s"
+                    + " windowFlags=#%s"
+                    + " unverifiedTargetSdkVersion=%s"
+                    + " bindingController=%s"
+                    + " imeDispatcher=%s"
+                    + " cs=%s",
+                InputMethodDebug.startInputReasonToString(startInputReason), client.asBinder(),
+                inputContext, editorInfo, InputMethodDebug.startInputFlagsToString(startInputFlags),
+                InputMethodDebug.softInputModeToString(softInputMode),
+                Integer.toHexString(windowFlags), unverifiedTargetSdkVersion, bindingController,
+                imeDispatcher, cs);
 
         final int userId = bindingController.getUserId();
         final var userData = getUserData(userId);
@@ -3944,12 +3920,11 @@
         visibilityStateComputer.setWindowState(windowToken, windowState);
 
         if (sameWindowFocused && isTextEditor) {
-            if (DEBUG) {
-                Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client
-                        + " editorInfo=" + editorInfo + ", token = " + windowToken
-                        + ", startInputReason="
-                        + InputMethodDebug.startInputReasonToString(startInputReason));
-            }
+            ProtoLog.v(IMMS_DEBUG,
+                    "Window already focused, ignoring focus gain of: %s editorInfo=%s, token=%s, "
+                            + "startInputReason=%s",
+                    client, editorInfo, windowToken,
+                    InputMethodDebug.startInputReasonToString(startInputReason));
             if (editorInfo != null) {
                 return startInputUncheckedLocked(cs, inputContext,
                         remoteAccessibilityInputConnection, editorInfo, startInputFlags,
@@ -4254,11 +4229,8 @@
         }
 
         if (!TextUtils.isEmpty(targetLastImiId)) {
-            if (DEBUG) {
-                Slog.d(TAG, "Switch to: " + lastImi.getId() + ", " + lastIme.second
-                        + ", from: " + bindingController.getSelectedMethodId() + ", "
-                        + subtypeIndex);
-            }
+            ProtoLog.v(IMMS_DEBUG, "Switch to: %s, %s, from: %s, %s", lastImi.getId(),
+                    lastIme.second, bindingController.getSelectedMethodId(), subtypeIndex);
             setInputMethodWithSubtypeIndexLocked(targetLastImiId, subtypeIndex, userId);
             return true;
         } else {
@@ -4557,7 +4529,7 @@
             }
             final long ident = Binder.clearCallingIdentity();
             try {
-                if (DEBUG) Slog.v(TAG, "Adding virtual stylus id for session");
+                ProtoLog.v(IMMS_DEBUG, "Adding virtual stylus id for session");
                 addStylusDeviceIdLocked(VIRTUAL_STYLUS_ID_FOR_TEST);
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -4586,7 +4558,7 @@
             }
             final long ident = Binder.clearCallingIdentity();
             try {
-                if (DEBUG) Slog.v(TAG, "Setting stylus window idle timeout");
+                ProtoLog.v(IMMS_DEBUG, "Setting stylus window idle timeout");
                 getCurMethodLocked().setStylusWindowIdleTimeoutForTest(timeout);
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -4731,9 +4703,7 @@
     @BinderThread
     @GuardedBy("ImfLock.class")
     private void notifyUserActionLocked(@NonNull UserData userData) {
-        if (DEBUG) {
-            Slog.d(TAG, "Got the notification of a user action.");
-        }
+        ProtoLog.v(IMMS_DEBUG, "Got the notification of a user action.");
         final var bindingController = userData.mBindingController;
         final InputMethodInfo imi = bindingController.getSelectedMethod();
         if (imi != null) {
@@ -4870,13 +4840,13 @@
     void setEnabledSessionLocked(SessionState session, @NonNull UserData userData) {
         if (userData.mEnabledSession != session) {
             if (userData.mEnabledSession != null && userData.mEnabledSession.mSession != null) {
-                if (DEBUG) Slog.v(TAG, "Disabling: " + userData.mEnabledSession);
+                ProtoLog.v(IMMS_DEBUG, "Disabling: " + userData.mEnabledSession);
                 userData.mEnabledSession.mMethod.setSessionEnabled(
                         userData.mEnabledSession.mSession, false);
             }
             userData.mEnabledSession = session;
             if (userData.mEnabledSession != null && userData.mEnabledSession.mSession != null) {
-                if (DEBUG) Slog.v(TAG, "Enabling: " + userData.mEnabledSession);
+                ProtoLog.v(IMMS_DEBUG, "Enabling: " + userData.mEnabledSession);
                 userData.mEnabledSession.mMethod.setSessionEnabled(
                         userData.mEnabledSession.mSession, true);
             }
@@ -4961,13 +4931,12 @@
         }
 
         if (Flags.imeSwitcherRevamp()) {
-            if (DEBUG) {
-                Slog.v(TAG, "Show IME switcher menu,"
-                        + " showAuxSubtypes=" + showAuxSubtypes
-                        + " displayId=" + displayId
-                        + " preferredInputMethodId=" + lastInputMethodId
-                        + " preferredInputMethodSubtypeIndex=" + lastInputMethodSubtypeIndex);
-            }
+            ProtoLog.v(IMMS_DEBUG, "Show IME switcher menu,"
+                            + " showAuxSubtypes=%s"
+                            + " displayId=%s"
+                            + " preferredInputMethodId=%s"
+                            + " preferredInputMethodSubtypeIndex=%s",
+                    showAuxSubtypes, displayId, lastInputMethodId, lastInputMethodSubtypeIndex);
 
             int selectedSubtypeIndex = lastInputMethodSubtypeIndex;
             if (selectedSubtypeIndex == NOT_A_SUBTYPE_INDEX) {
@@ -5206,9 +5175,7 @@
         final InputMethodInfo imi = InputMethodInfoUtils.getMostApplicableDefaultIME(
                 settings.getEnabledInputMethodList());
         if (imi != null) {
-            if (DEBUG) {
-                Slog.d(TAG, "New default IME was selected: " + imi.getId());
-            }
+            ProtoLog.v(IMMS_DEBUG, "New default IME was selected: %s", imi.getId());
             resetSelectedInputMethodAndSubtypeLocked(imi.getId(), userId);
             return true;
         }
@@ -5262,7 +5229,7 @@
                 continue;
             }
 
-            if (DEBUG) Slog.d(TAG, "Checking " + imeId);
+            ProtoLog.v(IMMS_DEBUG, "Checking %s", imeId);
 
             try {
                 final InputMethodInfo imi = new InputMethodInfo(userAwareContext, ri,
@@ -5279,11 +5246,10 @@
                             1 + imiPackageCount.getOrDefault(packageName, 0));
 
                     methodMap.put(imi.getId(), imi);
-                    if (DEBUG) {
-                        Slog.d(TAG, "Found an input method " + imi);
-                    }
-                } else if (DEBUG) {
-                    Slog.d(TAG, "Found an input method, but ignored due threshold: " + imi);
+                    ProtoLog.v(IMMS_DEBUG, "Found an input method %s", imi);
+                } else {
+                    ProtoLog.v(IMMS_DEBUG, "Found an input method, but ignored due threshold: %s",
+                            imi);
                 }
             } catch (Exception e) {
                 Slog.wtf(TAG, "Unable to load input method " + imeId, e);
@@ -5295,10 +5261,8 @@
     @GuardedBy("ImfLock.class")
     void postInputMethodSettingUpdatedLocked(boolean resetDefaultEnabledIme,
             @UserIdInt int userId) {
-        if (DEBUG) {
-            Slog.d(TAG, "--- re-buildInputMethodList reset = " + resetDefaultEnabledIme
-                    + " \n ------ caller=" + Debug.getCallers(10));
-        }
+        ProtoLog.v(IMMS_DEBUG, "--- re-buildInputMethodList reset = %s"
+                    + " \n ------ caller=%s", resetDefaultEnabledIme, Debug.getCallers(10));
         if (!mSystemReady) {
             Slog.e(TAG, "buildInputMethodListLocked is not allowed until system is ready");
             return;
@@ -5324,15 +5288,12 @@
                 }
             }
             if (!enabledImeFound) {
-                if (DEBUG) {
-                    Slog.i(TAG, "All the enabled IMEs are gone. Reset default enabled IMEs.");
-                }
+                ProtoLog.v(IMMS_DEBUG,
+                        "All the enabled IMEs are gone. Reset default enabled IMEs.");
                 resetDefaultEnabledIme = true;
                 resetSelectedInputMethodAndSubtypeLocked("", userId);
             } else if (!enabledNonAuxImeFound) {
-                if (DEBUG) {
-                    Slog.i(TAG, "All the enabled non-Aux IMEs are gone. Do partial reset.");
-                }
+                ProtoLog.v(IMMS_DEBUG, "All the enabled non-Aux IMEs are gone. Do partial reset.");
                 reenableMinimumNonAuxSystemImes = true;
             }
         }
@@ -5344,9 +5305,7 @@
             final int numImes = defaultEnabledIme.size();
             for (int i = 0; i < numImes; ++i) {
                 final InputMethodInfo imi = defaultEnabledIme.get(i);
-                if (DEBUG) {
-                    Slog.d(TAG, "--- enable ime = " + imi);
-                }
+                ProtoLog.v(IMMS_DEBUG, "--- enable ime = %s", imi);
                 setInputMethodEnabledLocked(imi.getId(), true, userId);
             }
         }
@@ -5422,10 +5381,8 @@
         final InputMethodInfo newSystemVoiceIme = InputMethodInfoUtils.chooseSystemVoiceIme(
                 settings.getMethodMap(), systemSpeechRecognizer, currentDefaultVoiceImeId);
         if (newSystemVoiceIme == null) {
-            if (DEBUG) {
-                Slog.i(TAG, "Found no valid default Voice IME. If the user is still locked,"
-                        + " this may be expected.");
-            }
+            ProtoLog.v(IMMS_DEBUG, "Found no valid default Voice IME. If the user is still locked,"
+                    + " this may be expected.");
             // Clear DEFAULT_VOICE_INPUT_METHOD when necessary.  Note that InputMethodSettings
             // does not update the actual Secure Settings until the user is unlocked.
             if (!TextUtils.isEmpty(currentDefaultVoiceImeId)) {
@@ -5438,10 +5395,8 @@
         if (TextUtils.equals(currentDefaultVoiceImeId, newSystemVoiceIme.getId())) {
             return;
         }
-        if (DEBUG) {
-            Slog.i(TAG, "Enabling the default Voice IME:" + newSystemVoiceIme
-                    + " userId:" + userId);
-        }
+        ProtoLog.v(IMMS_DEBUG, "Enabling the default Voice IME: %s userId: %s", newSystemVoiceIme,
+                userId);
         setInputMethodEnabledLocked(newSystemVoiceIme.getId(), true, userId);
         settings.putDefaultVoiceInputMethod(newSystemVoiceIme.getId());
     }
@@ -5940,10 +5895,8 @@
                 final var bindingController = userData.mBindingController;
                 // TODO(b/305829876): Implement user ID verification
                 if (userData.mCurClient != null) {
-                    if (DEBUG) {
-                        Slog.v(TAG, "unbindAccessibilityFromCurrentClientLocked: client="
-                                + userData.mCurClient.mClient.asBinder());
-                    }
+                    ProtoLog.v(IMMS_DEBUG, "unbindAccessibilityFromCurrentClientLocked: client=%s",
+                            userData.mCurClient.mClient.asBinder());
                     // A11yManagerService unbinds the disabled accessibility service. We don't need
                     // to do it here.
                     userData.mCurClient.mClient.onUnbindAccessibilityService(
diff --git a/services/core/java/com/android/server/inputmethod/LocaleUtils.java b/services/core/java/com/android/server/inputmethod/LocaleUtils.java
index dbcd21a..5484575 100644
--- a/services/core/java/com/android/server/inputmethod/LocaleUtils.java
+++ b/services/core/java/com/android/server/inputmethod/LocaleUtils.java
@@ -40,11 +40,10 @@
     /**
      * Calculates a matching score for the single desired locale.
      *
+     * @param supported the locale supported by IME subtype
+     * @param desired   the locale preferred by user
+     * @return the score based on the locale matching for the default subtype enabling
      * @see LocaleUtils#filterByLanguage(List, LocaleExtractor, LocaleList, ArrayList)
-     *
-     * @param supported The locale supported by IME subtype.
-     * @param desired The locale preferred by user.
-     * @return A score based on the locale matching for the default subtype enabling.
      */
     @IntRange(from = 1, to = 4)
     private static byte calculateMatchingSubScore(@NonNull final ULocale supported,
@@ -88,7 +87,8 @@
 
     private static final class ScoreEntry implements Comparable<ScoreEntry> {
         public int mIndex = -1;
-        @NonNull public final byte[] mScore;  // matching score of the i-th system languages.
+        @NonNull
+        public final byte[] mScore;  // matching score of the i-th system languages.
 
         ScoreEntry(@NonNull byte[] score, int index) {
             mScore = new byte[score.length];
@@ -121,10 +121,10 @@
          * {@code right} is equal, do the same comparison to the next value. Finally if all values
          * in {@code left} and {@code right} are equal, {@code left} and {@code right} is equal.</p>
          *
-         * @param left The length must be equal to {@code right}.
-         * @param right The length must be equal to {@code left}.
+         * @param left  the length must be equal to {@code right}
+         * @param right the length must be equal to {@code left}
          * @return 1 if {@code left} is larger than {@code right}. -1 if {@code left} is less than
-         * {@code right}. 0 if {@code left} and {@code right} is equal.
+         * {@code right}. 0 if {@code left} and {@code right} is equal
          */
         @IntRange(from = -1, to = 1)
         private static int compare(@NonNull byte[] left, @NonNull byte[] right) {
@@ -155,12 +155,12 @@
      * will be searched from {@code source} based on matching score. For the score design, see
      * {@link LocaleUtils#calculateMatchingSubScore(ULocale, ULocale)}</p>
      *
-     * @param sources Source items to be filtered.
-     * @param extractor Type converter from the source items to {@link Locale} object.
-     * @param preferredLocales Ordered list of locales with which the input items will be
-     * filtered.
-     * @param dest Destination into which the filtered items will be added.
-     * @param <T> Type of the data items.
+     * @param sources          source items to be filtered
+     * @param extractor        type converter from the source items to {@link Locale} object
+     * @param preferredLocales ordered list of locales with which the input items will be
+     *                         filtered
+     * @param dest             destination into which the filtered items will be added
+     * @param <T>              type of the data items
      */
     public static <T> void filterByLanguage(
             @NonNull List<T> sources,
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java
index 740c4f1..4389dd0 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java
@@ -30,6 +30,7 @@
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.Collections;
 import java.util.HashMap;
@@ -45,14 +46,14 @@
  */
 /* package */ class ContextHubEndpointManager
         implements ContextHubHalEndpointCallback.IEndpointSessionCallback {
+    /** The range of session IDs to use for endpoints */
+    public static final int SERVICE_SESSION_RANGE = 1024;
+
     private static final String TAG = "ContextHubEndpointManager";
 
     /** The hub ID of the Context Hub Service. */
     private static final long SERVICE_HUB_ID = 0x416e64726f696400L;
 
-    /** The range of session IDs to use for endpoints */
-    private static final int SERVICE_SESSION_RANGE = 1024;
-
     /** The length of the array that should be returned by HAL requestSessionIdRange */
     private static final int SERVICE_SESSION_RANGE_LENGTH = 2;
 
@@ -400,4 +401,16 @@
     private boolean isSessionIdRangeValid(int minId, int maxId) {
         return (minId <= maxId) && (minId >= 0) && (maxId >= 0);
     }
+
+    @VisibleForTesting
+    /* package */ int getNumAvailableSessions() {
+        synchronized (mSessionIdLock) {
+            return (mMaxSessionId - mMinSessionId + 1) - mReservedSessionIds.size();
+        }
+    }
+
+    @VisibleForTesting
+    /* package */ int getNumRegisteredClients() {
+        return mEndpointMap.size();
+    }
 }
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index d873075..7834e26 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -234,13 +234,25 @@
             };
 
     @GuardedBy("mLock")
-    private @UserEngagementState int mUserEngagementState = USER_DISENGAGED;
+    private @UserEngagementState int mUserEngagementState = USER_ENGAGEMENT_UNSET;
 
-    @IntDef({USER_PERMANENTLY_ENGAGED, USER_TEMPORARILY_ENGAGED, USER_DISENGAGED})
+    @IntDef({
+        USER_ENGAGEMENT_UNSET,
+        USER_PERMANENTLY_ENGAGED,
+        USER_TEMPORARILY_ENGAGED,
+        USER_DISENGAGED
+    })
     @Retention(RetentionPolicy.SOURCE)
     private @interface UserEngagementState {}
 
     /**
+     * Indicates that the {@link UserEngagementState} is not yet set.
+     *
+     * @see #updateUserEngagedStateIfNeededLocked(boolean)
+     */
+    private static final int USER_ENGAGEMENT_UNSET = -1;
+
+    /**
      * Indicates that the session is {@linkplain MediaSession#isActive() active} and in one of the
      * {@linkplain PlaybackState#isActive() active states}.
      *
@@ -1054,11 +1066,10 @@
         }
         int oldUserEngagedState = mUserEngagementState;
         int newUserEngagedState;
-        if (!isActive() || mPlaybackState == null) {
-            newUserEngagedState = USER_DISENGAGED;
-        } else if (mPlaybackState.isActive()) {
+        if (isActive() && mPlaybackState != null && mPlaybackState.isActive()) {
             newUserEngagedState = USER_PERMANENTLY_ENGAGED;
         } else if (oldUserEngagedState == USER_PERMANENTLY_ENGAGED
+                || oldUserEngagedState == USER_ENGAGEMENT_UNSET
                 || (oldUserEngagedState == USER_TEMPORARILY_ENGAGED && !isTimeoutExpired)) {
             newUserEngagedState = USER_TEMPORARILY_ENGAGED;
         } else {
@@ -1079,7 +1090,7 @@
 
         boolean wasUserEngaged = oldUserEngagedState != USER_DISENGAGED;
         boolean isNowUserEngaged = newUserEngagedState != USER_DISENGAGED;
-        if (wasUserEngaged != isNowUserEngaged) {
+        if (oldUserEngagedState == USER_ENGAGEMENT_UNSET || wasUserEngaged != isNowUserEngaged) {
             mHandler.post(
                     () ->
                             mService.onSessionUserEngagementStateChange(
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java
index 3eb38a7..b529853 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java
@@ -56,8 +56,10 @@
  */
 /* package */ class SystemMediaRoute2Provider2 extends SystemMediaRoute2Provider {
 
-    private static final String ROUTE_ID_PREFIX_SYSTEM = "SYSTEM";
-    private static final String ROUTE_ID_SYSTEM_SEPARATOR = ".";
+    private static final String UNIQUE_SYSTEM_ID_PREFIX = "SYSTEM";
+    private static final String UNIQUE_SYSTEM_ID_SEPARATOR = "-";
+    private static final boolean FORCE_GLOBAL_ROUTING_SESSION = true;
+    private static final String PACKAGE_NAME_FOR_GLOBAL_SESSION = "";
 
     private final PackageManager mPackageManager;
 
@@ -67,6 +69,10 @@
     @GuardedBy("mLock")
     private final Map<String, ProviderProxyRecord> mProxyRecords = new ArrayMap<>();
 
+    @GuardedBy("mLock")
+    private final Map<String, SystemMediaSessionRecord> mSessionOriginalIdToSessionRecord =
+            new ArrayMap<>();
+
     /**
      * Maps package names to corresponding sessions maintained by {@link MediaRoute2ProviderService
      * provider services}.
@@ -114,6 +120,9 @@
             String routeOriginalId,
             int transferReason) {
         synchronized (mLock) {
+            if (FORCE_GLOBAL_ROUTING_SESSION) {
+                clientPackageName = PACKAGE_NAME_FOR_GLOBAL_SESSION;
+            }
             var targetProviderProxyId = mOriginalRouteIdToProviderId.get(routeOriginalId);
             var targetProviderProxyRecord = mProxyRecords.get(targetProviderProxyId);
             // Holds the target route, if it's managed by a provider service. Holds null otherwise.
@@ -121,7 +130,7 @@
                     targetProviderProxyRecord != null
                             ? targetProviderProxyRecord.getRouteByOriginalId(routeOriginalId)
                             : null;
-            var existingSessionRecord = mPackageNameToSessionRecord.get(clientPackageName);
+            var existingSessionRecord = getSessionRecordByPackageName(clientPackageName);
             if (existingSessionRecord != null) {
                 var existingSession = existingSessionRecord.mSourceSessionInfo;
                 if (targetProviderProxyId != null
@@ -150,7 +159,7 @@
                     if (currentProxyRecord != null) {
                         currentProxyRecord.releaseSession(
                                 requestId, existingSession.getOriginalId());
-                        existingSessionRecord.removeSelfFromSessionMap();
+                        existingSessionRecord.removeSelfFromSessionMaps();
                     }
                 }
             }
@@ -202,7 +211,7 @@
             if (systemSession == null) {
                 return null;
             }
-            var overridingSession = mPackageNameToSessionRecord.get(packageName);
+            var overridingSession = getSessionRecordByPackageName(packageName);
             if (overridingSession != null) {
                 var builder =
                         new RoutingSessionInfo.Builder(overridingSession.mTranslatedSessionInfo)
@@ -240,6 +249,41 @@
         super.setRouteVolume(requestId, routeOriginalId, volume);
     }
 
+    @Override
+    public void setSessionVolume(long requestId, String sessionOriginalId, int volume) {
+        if (SYSTEM_SESSION_ID.equals(sessionOriginalId)) {
+            super.setSessionVolume(requestId, sessionOriginalId, volume);
+            return;
+        }
+        synchronized (mLock) {
+            var sessionRecord = getSessionRecordByOriginalId(sessionOriginalId);
+            var proxyRecord = sessionRecord != null ? sessionRecord.getProxyRecord() : null;
+            if (proxyRecord != null) {
+                proxyRecord.mProxy.setSessionVolume(
+                        requestId, sessionRecord.getServiceSessionId(), volume);
+                return;
+            }
+        }
+        notifyRequestFailed(requestId, MediaRoute2ProviderService.REASON_ROUTE_NOT_AVAILABLE);
+    }
+
+    @GuardedBy("mLock")
+    private SystemMediaSessionRecord getSessionRecordByOriginalId(String sessionOriginalId) {
+        if (FORCE_GLOBAL_ROUTING_SESSION) {
+            return getSessionRecordByPackageName(PACKAGE_NAME_FOR_GLOBAL_SESSION);
+        } else {
+            return mSessionOriginalIdToSessionRecord.get(sessionOriginalId);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private SystemMediaSessionRecord getSessionRecordByPackageName(String clientPackageName) {
+        if (FORCE_GLOBAL_ROUTING_SESSION) {
+            clientPackageName = PACKAGE_NAME_FOR_GLOBAL_SESSION;
+        }
+        return mPackageNameToSessionRecord.get(clientPackageName);
+    }
+
     /**
      * Returns the uid that corresponds to the given name and user handle, or {@link
      * Process#INVALID_UID} if a uid couldn't be found.
@@ -297,16 +341,34 @@
      */
     private void updateSessionInfo() {
         synchronized (mLock) {
-            var systemSessionInfo = mSystemSessionInfo;
-            if (systemSessionInfo == null) {
+            var globalSessionInfoRecord =
+                    getSessionRecordByPackageName(PACKAGE_NAME_FOR_GLOBAL_SESSION);
+            var globalSessionInfo =
+                    globalSessionInfoRecord != null
+                            ? globalSessionInfoRecord.mTranslatedSessionInfo
+                            : null;
+            if (globalSessionInfo == null) {
+                globalSessionInfo = mSystemSessionInfo;
+            }
+            if (globalSessionInfo == null) {
                 // The system session info hasn't been initialized yet. Do nothing.
                 return;
             }
-            var builder = new RoutingSessionInfo.Builder(systemSessionInfo);
-            mProxyRecords.values().stream()
-                    .flatMap(ProviderProxyRecord::getRoutesStream)
-                    .map(MediaRoute2Info::getOriginalId)
-                    .forEach(builder::addTransferableRoute);
+            var builder = new RoutingSessionInfo.Builder(globalSessionInfo);
+            if (globalSessionInfo == mSystemSessionInfo) {
+                // The session is the system one. So we make all the service-provided routes
+                // available for transfer. The system transferable routes are already there.
+                mProxyRecords.values().stream()
+                        .flatMap(ProviderProxyRecord::getRoutesStream)
+                        .map(MediaRoute2Info::getOriginalId)
+                        .forEach(builder::addTransferableRoute);
+            } else {
+                // The session is service-provided. So we add the system-provided routes as
+                // transferable.
+                mLastSystemProviderInfo.getRoutes().stream()
+                        .map(MediaRoute2Info::getOriginalId)
+                        .forEach(builder::addTransferableRoute);
+            }
             mSessionInfos.clear();
             mSessionInfos.add(builder.build());
             for (var sessionRecords : mPackageNameToSessionRecord.values()) {
@@ -376,16 +438,17 @@
     }
 
     /**
-     * Equivalent to {@link #asSystemRouteId}, except it takes a unique route id instead of a
-     * original id.
+     * Equivalent to {@link #asUniqueSystemId}, except it takes a unique id instead of an original
+     * id.
      */
     private static String uniqueIdAsSystemRouteId(String providerId, String uniqueRouteId) {
-        return asSystemRouteId(providerId, MediaRouter2Utils.getOriginalId(uniqueRouteId));
+        return asUniqueSystemId(providerId, MediaRouter2Utils.getOriginalId(uniqueRouteId));
     }
 
     /**
      * Returns a unique {@link MediaRoute2Info#getOriginalId() original id} for this provider to
-     * publish system media routes from {@link MediaRoute2ProviderService provider services}.
+     * publish system media routes and sessions from {@link MediaRoute2ProviderService provider
+     * services}.
      *
      * <p>This provider will publish system media routes as part of the system routing session.
      * However, said routes may also support {@link MediaRoute2Info#FLAG_ROUTING_TYPE_REMOTE remote
@@ -393,12 +456,12 @@
      * we derive a {@link MediaRoute2Info#getOriginalId original id} that is unique among all
      * original route ids used by this provider.
      */
-    private static String asSystemRouteId(String providerId, String originalRouteId) {
-        return ROUTE_ID_PREFIX_SYSTEM
-                + ROUTE_ID_SYSTEM_SEPARATOR
+    private static String asUniqueSystemId(String providerId, String originalId) {
+        return UNIQUE_SYSTEM_ID_PREFIX
+                + UNIQUE_SYSTEM_ID_SEPARATOR
                 + providerId
-                + ROUTE_ID_SYSTEM_SEPARATOR
-                + originalRouteId;
+                + UNIQUE_SYSTEM_ID_SEPARATOR
+                + originalId;
     }
 
     /**
@@ -485,7 +548,7 @@
                     continue;
                 }
                 String id =
-                        asSystemRouteId(providerInfo.getUniqueId(), sourceRoute.getOriginalId());
+                        asUniqueSystemId(providerInfo.getUniqueId(), sourceRoute.getOriginalId());
                 var newRouteBuilder = new MediaRoute2Info.Builder(id, sourceRoute);
                 if ((sourceRoute.getSupportedRoutingTypes()
                                 & MediaRoute2Info.FLAG_ROUTING_TYPE_SYSTEM_AUDIO)
@@ -534,6 +597,9 @@
                             RoutingSessionInfo translatedSession;
                             synchronized (mLock) {
                                 mSessionRecord = systemMediaSessionRecord;
+                                mSessionOriginalIdToSessionRecord.put(
+                                        systemMediaSessionRecord.mOriginalId,
+                                        systemMediaSessionRecord);
                                 mPackageNameToSessionRecord.put(
                                         mClientPackageName, systemMediaSessionRecord);
                                 mPendingSessionCreations.remove(mRequestId);
@@ -576,24 +642,38 @@
 
         private final String mProviderId;
 
-        @GuardedBy("SystemMediaRoute2Provider2.this.mLock")
-        @NonNull
-        private RoutingSessionInfo mSourceSessionInfo;
+        /**
+         * The {@link RoutingSessionInfo#getOriginalId() original id} with which this session is
+         * published.
+         *
+         * <p>Derived from the service routing session, using {@link #asUniqueSystemId}.
+         */
+        private final String mOriginalId;
+
+        // @GuardedBy("SystemMediaRoute2Provider2.this.mLock")
+        @NonNull private RoutingSessionInfo mSourceSessionInfo;
 
         /**
-         * The same as {@link #mSourceSessionInfo}, except ids are {@link #asSystemRouteId system
+         * The same as {@link #mSourceSessionInfo}, except ids are {@link #asUniqueSystemId system
          * provider ids}.
          */
-        @NonNull
-        private RoutingSessionInfo mTranslatedSessionInfo;
+        // @GuardedBy("SystemMediaRoute2Provider2.this.mLock")
+        @NonNull private RoutingSessionInfo mTranslatedSessionInfo;
 
         SystemMediaSessionRecord(
                 @NonNull String providerId, @NonNull RoutingSessionInfo sessionInfo) {
             mProviderId = providerId;
             mSourceSessionInfo = sessionInfo;
+            mOriginalId =
+                    asUniqueSystemId(sessionInfo.getProviderId(), sessionInfo.getOriginalId());
             mTranslatedSessionInfo = asSystemProviderSession(sessionInfo);
         }
 
+        // @GuardedBy("SystemMediaRoute2Provider2.this.mLock")
+        public String getServiceSessionId() {
+            return mSourceSessionInfo.getOriginalId();
+        }
+
         @Override
         public void onSessionUpdate(@NonNull RoutingSessionInfo sessionInfo) {
             RoutingSessionInfo translatedSessionInfo = asSystemProviderSession(sessionInfo);
@@ -612,31 +692,32 @@
         @Override
         public void onSessionReleased() {
             synchronized (mLock) {
-                removeSelfFromSessionMap();
+                removeSelfFromSessionMaps();
             }
             notifyGlobalSessionInfoUpdated();
         }
 
-        @GuardedBy("SystemMediaRoute2Provider2.this.mLock")
+        // @GuardedBy("SystemMediaRoute2Provider2.this.mLock")
         @Nullable
         public ProviderProxyRecord getProxyRecord() {
             ProviderProxyRecord provider = mProxyRecords.get(mProviderId);
             if (provider == null) {
                 // Unexpected condition where the proxy is no longer available while there's an
                 // ongoing session. Could happen due to a crash in the provider process.
-                removeSelfFromSessionMap();
+                removeSelfFromSessionMaps();
             }
             return provider;
         }
 
-        @GuardedBy("SystemMediaRoute2Provider2.this.mLock")
-        private void removeSelfFromSessionMap() {
+        // @GuardedBy("SystemMediaRoute2Provider2.this.mLock")
+        private void removeSelfFromSessionMaps() {
+            mSessionOriginalIdToSessionRecord.remove(mOriginalId);
             mPackageNameToSessionRecord.remove(mSourceSessionInfo.getClientPackageName());
         }
 
         private RoutingSessionInfo asSystemProviderSession(RoutingSessionInfo session) {
             var builder =
-                    new RoutingSessionInfo.Builder(session)
+                    new RoutingSessionInfo.Builder(session, mOriginalId)
                             .setProviderId(mUniqueId)
                             .setSystemSession(true)
                             .clearSelectedRoutes()
diff --git a/services/core/java/com/android/server/media/quality/MediaQualityService.java b/services/core/java/com/android/server/media/quality/MediaQualityService.java
index d00ac4d..c93f107 100644
--- a/services/core/java/com/android/server/media/quality/MediaQualityService.java
+++ b/services/core/java/com/android/server/media/quality/MediaQualityService.java
@@ -1160,6 +1160,9 @@
 
         private Bundle convertToCaps(ParameterRange range) {
             Bundle bundle = new Bundle();
+            if (range == null || range.numRange == null) {
+                return bundle;
+            }
             bundle.putObject("INT_MIN_MAX", range.numRange.getIntMinMax());
             bundle.putObject("INT_VALUES_SUPPORTED", range.numRange.getIntValuesSupported());
             bundle.putObject("DOUBLE_MIN_MAX", range.numRange.getDoubleMinMax());
@@ -1351,7 +1354,7 @@
             RemoteCallbackList<IPictureProfileCallback> {
         @Override
         public void onCallbackDied(IPictureProfileCallback callback) {
-            synchronized ("mPictureProfileLock") {    //TODO: Change to lock
+            synchronized (mPictureProfileLock) {
                 for (int i = 0; i < mUserStates.size(); i++) {
                     int userId = mUserStates.keyAt(i);
                     UserState userState = getOrCreateUserStateLocked(userId);
@@ -1365,7 +1368,7 @@
             RemoteCallbackList<ISoundProfileCallback> {
         @Override
         public void onCallbackDied(ISoundProfileCallback callback) {
-            synchronized ("mSoundProfileLock") {    //TODO: Change to lock
+            synchronized (mSoundProfileLock) {
                 for (int i = 0; i < mUserStates.size(); i++) {
                     int userId = mUserStates.keyAt(i);
                     UserState userState = getOrCreateUserStateLocked(userId);
diff --git a/services/core/java/com/android/server/media/quality/MediaQualityUtils.java b/services/core/java/com/android/server/media/quality/MediaQualityUtils.java
index 5bd4420..ba61e50 100644
--- a/services/core/java/com/android/server/media/quality/MediaQualityUtils.java
+++ b/services/core/java/com/android/server/media/quality/MediaQualityUtils.java
@@ -357,6 +357,9 @@
      */
     public static PictureParameter[] convertPersistableBundleToPictureParameterList(
             PersistableBundle params) {
+        if (params == null) {
+            return null;
+        }
         List<PictureParameter> pictureParams = new ArrayList<>();
         if (params.containsKey(PictureQuality.PARAMETER_BRIGHTNESS)) {
             pictureParams.add(PictureParameter.brightness(params.getLong(
@@ -784,6 +787,9 @@
      */
     public static SoundParameter[] convertPersistableBundleToSoundParameterList(
             PersistableBundle params) {
+        if (params == null) {
+            return null;
+        }
         //TODO: set EqualizerDetail
         List<SoundParameter> soundParams = new ArrayList<>();
         if (params.containsKey(SoundQuality.PARAMETER_BALANCE)) {
diff --git a/services/core/java/com/android/server/memory/OWNERS b/services/core/java/com/android/server/memory/OWNERS
new file mode 100644
index 0000000..dc0e898
--- /dev/null
+++ b/services/core/java/com/android/server/memory/OWNERS
@@ -0,0 +1,3 @@
+include /MEMORY_OWNERS
+
+per-file ZramMaintenance.java = kawasin@google.com
diff --git a/services/core/java/com/android/server/memory/ZramMaintenance.java b/services/core/java/com/android/server/memory/ZramMaintenance.java
new file mode 100644
index 0000000..48358d1
--- /dev/null
+++ b/services/core/java/com/android/server/memory/ZramMaintenance.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.memory;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.IBinder;
+import android.os.IMmd;
+import android.os.PersistableBundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.provider.DeviceConfig;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.time.Duration;
+
+/**
+ * Schedules zram maintenance (e.g. zram writeback, zram recompression).
+ *
+ * <p>ZramMaintenance notifies mmd the good timing to execute zram maintenance based on:
+ *
+ * <ul>
+ * <li>Enough interval has passed.
+ * <li>The system is idle.
+ * <li>The battery is not low.
+ * </ul>
+ */
+public class ZramMaintenance extends JobService {
+    private static final String TAG = ZramMaintenance.class.getName();
+    // Job id must be unique across all clients of the same uid. ZramMaintenance uses the bug number
+    // as the job id.
+    @VisibleForTesting
+    public static final int JOB_ID = 375432472;
+    private static final ComponentName sZramMaintenance =
+            new ComponentName("android", ZramMaintenance.class.getName());
+    @VisibleForTesting
+    public static final String KEY_CHECK_STATUS = "check_status";
+
+    private static final String SYSTEM_PROPERTY_PREFIX = "mm.";
+    private static final String FIRST_DELAY_SECONDS_PROP =
+            "zram.maintenance.first_delay_seconds";
+    // The default is 1 hour.
+    private static final long DEFAULT_FIRST_DELAY_SECONDS = 3600;
+    private static final String PERIODIC_DELAY_SECONDS_PROP =
+            "zram.maintenance.periodic_delay_seconds";
+    // The default is 1 hour.
+    private static final long DEFAULT_PERIODIC_DELAY_SECONDS = 3600;
+    private static final String REQUIRE_DEVICE_IDLE_PROP =
+            "zram.maintenance.require_device_idle";
+    private static final boolean DEFAULT_REQUIRE_DEVICE_IDLE =
+            true;
+    private static final String REQUIRE_BATTERY_NOT_LOW_PROP =
+            "zram.maintenance.require_battry_not_low";
+    private static final boolean DEFAULT_REQUIRE_BATTERY_NOT_LOW =
+            true;
+
+    @Override
+    public boolean onStartJob(JobParameters params) {
+        new Thread("ZramMaintenance") {
+            @Override
+            public void run() {
+                try {
+                    IBinder binder = ServiceManager.getService("mmd");
+                    IMmd mmd = IMmd.Stub.asInterface(binder);
+                    startJob(ZramMaintenance.this, params, mmd);
+                } finally {
+                    jobFinished(params, false);
+                }
+            }
+        }.start();
+        return true;
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters params) {
+        return false;
+    }
+
+    /**
+     * This is public to test ZramMaintenance logic.
+     *
+     * <p>
+     * We need to pass mmd as parameter because we can't mock "IMmd.Stub.asInterface".
+     *
+     * <p>
+     * Since IMmd.isZramMaintenanceSupported() is blocking call, this method should be executed on
+     * a worker thread.
+     */
+    @VisibleForTesting
+    public static void startJob(Context context, JobParameters params, IMmd mmd) {
+        boolean checkStatus = params.getExtras().getBoolean(KEY_CHECK_STATUS);
+        if (mmd != null) {
+            try {
+                if (checkStatus && !mmd.isZramMaintenanceSupported()) {
+                    Slog.i(TAG, "zram maintenance is not supported");
+                    return;
+                }
+                // Status check is required before the first doZramMaintenanceAsync() call once.
+                checkStatus = false;
+
+                mmd.doZramMaintenanceAsync();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Failed to binder call to mmd", e);
+            }
+        } else {
+            Slog.w(TAG, "binder not found");
+        }
+        Duration delay = Duration.ofSeconds(getLongProperty(PERIODIC_DELAY_SECONDS_PROP,
+                DEFAULT_PERIODIC_DELAY_SECONDS));
+        scheduleZramMaintenance(context, delay, checkStatus);
+    }
+
+    /**
+     * Starts periodical zram maintenance.
+     */
+    public static void startZramMaintenance(Context context) {
+        Duration delay = Duration.ofSeconds(
+                getLongProperty(FIRST_DELAY_SECONDS_PROP, DEFAULT_FIRST_DELAY_SECONDS));
+        scheduleZramMaintenance(context, delay, true);
+    }
+
+    private static void scheduleZramMaintenance(Context context, Duration delay,
+            boolean checkStatus) {
+        JobScheduler js = context.getSystemService(JobScheduler.class);
+
+        if (js != null) {
+            final PersistableBundle bundle = new PersistableBundle();
+            bundle.putBoolean(KEY_CHECK_STATUS, checkStatus);
+            js.schedule(new JobInfo.Builder(JOB_ID, sZramMaintenance)
+                    .setMinimumLatency(delay.toMillis())
+                    .setRequiresDeviceIdle(
+                            getBooleanProperty(REQUIRE_DEVICE_IDLE_PROP,
+                                    DEFAULT_REQUIRE_DEVICE_IDLE))
+                    .setRequiresBatteryNotLow(
+                            getBooleanProperty(REQUIRE_BATTERY_NOT_LOW_PROP,
+                                    DEFAULT_REQUIRE_BATTERY_NOT_LOW))
+                    .setExtras(bundle)
+                    .build());
+        }
+    }
+
+    private static long getLongProperty(String name, long defaultValue) {
+        return DeviceConfig.getLong(DeviceConfig.NAMESPACE_MM, name,
+                SystemProperties.getLong(SYSTEM_PROPERTY_PREFIX + name, defaultValue));
+    }
+
+    private static boolean getBooleanProperty(String name, boolean defaultValue) {
+        return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_MM, name,
+                SystemProperties.getBoolean(SYSTEM_PROPERTY_PREFIX + name, defaultValue));
+    }
+}
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index e47f8ae9..02f817e 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -146,18 +146,27 @@
     private static List<NotificationSectioner> NOTIFICATION_SHADE_SECTIONS =
             getNotificationShadeSections();
 
+    private static List<NotificationSectioner> NOTIFICATION_BUNDLE_SECTIONS;
+
     private static List<NotificationSectioner> getNotificationShadeSections() {
         ArrayList<NotificationSectioner> sectionsList = new ArrayList<>();
         if (android.service.notification.Flags.notificationClassification()) {
             sectionsList.addAll(List.of(
                 new NotificationSectioner("PromotionsSection", 0, (record) ->
-                    NotificationChannel.PROMOTIONS_ID.equals(record.getChannel().getId())),
+                        NotificationChannel.PROMOTIONS_ID.equals(record.getChannel().getId())
+                        && record.getImportance() < NotificationManager.IMPORTANCE_DEFAULT),
                 new NotificationSectioner("SocialSection", 0, (record) ->
-                    NotificationChannel.SOCIAL_MEDIA_ID.equals(record.getChannel().getId())),
+                        NotificationChannel.SOCIAL_MEDIA_ID.equals(record.getChannel().getId())
+                        && record.getImportance() < NotificationManager.IMPORTANCE_DEFAULT),
                 new NotificationSectioner("NewsSection", 0, (record) ->
-                    NotificationChannel.NEWS_ID.equals(record.getChannel().getId())),
+                        NotificationChannel.NEWS_ID.equals(record.getChannel().getId())
+                        && record.getImportance() < NotificationManager.IMPORTANCE_DEFAULT),
                 new NotificationSectioner("RecsSection", 0, (record) ->
-                    NotificationChannel.RECS_ID.equals(record.getChannel().getId()))));
+                        NotificationChannel.RECS_ID.equals(record.getChannel().getId())
+                        && record.getImportance() < NotificationManager.IMPORTANCE_DEFAULT)
+                ));
+
+            NOTIFICATION_BUNDLE_SECTIONS = new ArrayList<>(sectionsList);
         }
 
         if (Flags.notificationForceGroupConversations()) {
@@ -828,7 +837,7 @@
                     }
                     moveNotificationsToNewSection(record.getUserId(), pkgName,
                             List.of(new NotificationMoveOp(record, null, fullAggregateGroupKey)),
-                            REGROUP_REASON_BUNDLE);
+                            Map.of(record.getKey(), REGROUP_REASON_BUNDLE));
                     return;
                 }
             }
@@ -895,7 +904,12 @@
             return false;
         }
 
-        return NotificationChannel.SYSTEM_RESERVED_IDS.contains(record.getChannel().getId());
+        return isInBundleSection(record);
+    }
+
+    private static boolean isInBundleSection(final NotificationRecord record) {
+        final NotificationSectioner sectioner = getSection(record);
+        return (sectioner != null && NOTIFICATION_BUNDLE_SECTIONS.contains(sectioner));
     }
 
     /**
@@ -1084,10 +1098,10 @@
                                       FullyQualifiedGroupKey newGroup) { }
 
     /**
-     * Called when a notification channel is updated (channel attributes have changed),
-     * so that this helper can adjust the aggregate groups by moving children
-     * if their section has changed.
-     * see {@link #onNotificationPostedWithDelay(NotificationRecord, List, Map)}
+     * Called when a notification channel is updated (channel attributes have changed), 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
@@ -1095,19 +1109,30 @@
      */
     @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) {
+            final NotificationChannel channel, final List<NotificationRecord> notificationList,
+            ArrayMap<String, NotificationRecord> summaryByGroupKey) {
         synchronized (mAggregatedNotifications) {
+            final ArrayMap<String, Integer> regroupingReasonMap = new ArrayMap<>();
             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);
+                    regroupingReasonMap.put(r.getKey(), REGROUP_REASON_CHANNEL_UPDATE);
+                    if (notificationRegroupOnClassification()) {
+                        // Notification is unbundled and original summary found
+                        // => regroup in original group
+                        if (!isInBundleSection(r)
+                                && isOriginalGroupSummaryPresent(r, summaryByGroupKey)) {
+                            regroupingReasonMap.put(r.getKey(),
+                                    REGROUP_REASON_UNBUNDLE_ORIGINAL_GROUP);
+                        }
+                    }
                 }
             }
 
-            regroupNotifications(userId, pkgName, notificationsToCheck,
-                    REGROUP_REASON_CHANNEL_UPDATE);
+            regroupNotifications(userId, pkgName, notificationsToCheck, regroupingReasonMap);
         }
     }
 
@@ -1124,8 +1149,10 @@
         synchronized (mAggregatedNotifications) {
             ArrayMap<String, NotificationRecord> notificationsToCheck = new ArrayMap<>();
             notificationsToCheck.put(record.getKey(), record);
+            ArrayMap<String, Integer> regroupReasons = new ArrayMap<>();
+            regroupReasons.put(record.getKey(), REGROUP_REASON_BUNDLE);
             regroupNotifications(record.getUserId(), record.getSbn().getPackageName(),
-                    notificationsToCheck, REGROUP_REASON_BUNDLE);
+                    notificationsToCheck, regroupReasons);
         }
     }
 
@@ -1144,16 +1171,16 @@
             ArrayMap<String, NotificationRecord> notificationsToCheck = new ArrayMap<>();
             notificationsToCheck.put(record.getKey(), record);
             regroupNotifications(record.getUserId(), record.getSbn().getPackageName(),
-                    notificationsToCheck,
-                    originalSummaryExists ? REGROUP_REASON_UNBUNDLE_ORIGINAL_GROUP
-                        : REGROUP_REASON_UNBUNDLE);
+                    notificationsToCheck, Map.of(record.getKey(),
+                        originalSummaryExists ? REGROUP_REASON_UNBUNDLE_ORIGINAL_GROUP
+                            : REGROUP_REASON_UNBUNDLE));
         }
     }
 
     @GuardedBy("mAggregatedNotifications")
     private void regroupNotifications(int userId, String pkgName,
             ArrayMap<String, NotificationRecord> notificationsToCheck,
-            @RegroupingReason int regroupingReason) {
+            Map<String, Integer> regroupReasons) {
         // The list of notification operations required after the channel update
         final ArrayList<NotificationMoveOp> notificationsToMove = new ArrayList<>();
 
@@ -1170,15 +1197,13 @@
 
         // Handle "grouped correctly" notifications that were re-classified (bundled)
         if (notificationRegroupOnClassification()) {
-            if (regroupingReason == REGROUP_REASON_BUNDLE) {
-                notificationsToMove.addAll(
-                        getReclassifiedNotificationsMoveOps(userId, pkgName, notificationsToCheck));
-            }
+            notificationsToMove.addAll(
+                    getReclassifiedNotificationsMoveOps(userId, pkgName, notificationsToCheck));
         }
 
         // Batch move to new section
         if (!notificationsToMove.isEmpty()) {
-            moveNotificationsToNewSection(userId, pkgName, notificationsToMove, regroupingReason);
+            moveNotificationsToNewSection(userId, pkgName, notificationsToMove, regroupReasons);
         }
     }
 
@@ -1187,9 +1212,9 @@
         final ArrayList<NotificationMoveOp> notificationsToMove = new ArrayList<>();
         for (NotificationRecord record : notificationsToCheck.values()) {
             if (isChildOfValidAppGroup(record)) {
-                // Check if section changes
+                // Check if section changes to a bundle section
                 NotificationSectioner sectioner = getSection(record);
-                if (sectioner != null) {
+                if (sectioner != null && NOTIFICATION_BUNDLE_SECTIONS.contains(sectioner)) {
                     FullyQualifiedGroupKey newFullAggregateGroupKey =
                             new FullyQualifiedGroupKey(userId, pkgName, sectioner);
                     if (DEBUG) {
@@ -1204,6 +1229,24 @@
         return notificationsToMove;
     }
 
+    /**
+     *  Checks if the original group's summary exists for a notification that was regrouped
+     * @param r notification to check
+     * @param summaryByGroupKey map of the current group summaries
+     * @return true if the original group summary exists
+     */
+    public static boolean isOriginalGroupSummaryPresent(final NotificationRecord r,
+            final ArrayMap<String, NotificationRecord> summaryByGroupKey) {
+        if (r.getSbn().isAppGroup() && r.getNotification().isGroupChild()) {
+            final String oldGroupKey = GroupHelper.getFullAggregateGroupKey(
+                    r.getSbn().getPackageName(), r.getOriginalGroupKey(), r.getUserId());
+            NotificationRecord groupSummary = summaryByGroupKey.get(oldGroupKey);
+            // We only care about app-provided valid groups
+            return (groupSummary != null && !GroupHelper.isAggregatedGroup(groupSummary));
+        }
+        return false;
+    }
+
     @GuardedBy("mAggregatedNotifications")
     private List<NotificationMoveOp> getAutogroupedNotificationsMoveOps(int userId, String pkgName,
             ArrayMap<String, NotificationRecord> notificationsToCheck) {
@@ -1298,7 +1341,8 @@
 
     @GuardedBy("mAggregatedNotifications")
     private void moveNotificationsToNewSection(final int userId, final String pkgName,
-            final List<NotificationMoveOp> notificationsToMove, int regroupingReason) {
+            final List<NotificationMoveOp> notificationsToMove,
+            final Map<String, Integer> regroupReasons) {
         record GroupUpdateOp(FullyQualifiedGroupKey groupKey, NotificationRecord record,
                              boolean hasSummary) { }
         // Bundled operations to apply to groups affected by the channel update
@@ -1317,7 +1361,7 @@
                 Log.i(TAG,
                     "moveNotificationToNewSection: " + record + " " + newFullAggregateGroupKey
                             + " from: " + oldFullAggregateGroupKey + " regroupingReason: "
-                            + regroupingReason);
+                            + regroupReasons);
             }
 
             // Update/remove aggregate summary for old group
@@ -1347,7 +1391,8 @@
             // after all notifications have been handled
             if (newFullAggregateGroupKey != null) {
                 if (notificationRegroupOnClassification()
-                        && regroupingReason == REGROUP_REASON_UNBUNDLE_ORIGINAL_GROUP) {
+                    && regroupReasons.getOrDefault(record.getKey(), REGROUP_REASON_CHANNEL_UPDATE)
+                        == REGROUP_REASON_UNBUNDLE_ORIGINAL_GROUP) {
                     // Just reset override group key, original summary exists
                     // => will be grouped back to its original group
                     record.setOverrideGroupKey(null);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 6d565d2..638b2dd 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -111,7 +111,9 @@
 import static android.service.notification.Adjustment.KEY_SUMMARIZATION;
 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.FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT;
 import static android.service.notification.Flags.callstyleCallbackApi;
 import static android.service.notification.Flags.notificationClassification;
@@ -346,6 +348,7 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.messages.nano.SystemMessageProto;
+import com.android.internal.notification.NotificationChannelGroupsHelper;
 import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.SomeArgs;
@@ -491,7 +494,10 @@
     };
 
     static final Integer[] DEFAULT_ALLOWED_ADJUSTMENT_KEY_TYPES = new Integer[] {
-            TYPE_PROMOTION
+            TYPE_PROMOTION,
+            TYPE_NEWS,
+            TYPE_CONTENT_RECOMMENDATION,
+            TYPE_SOCIAL_MEDIA
     };
 
     static final String[] NON_BLOCKABLE_DEFAULT_ROLES = new String[] {
@@ -1929,27 +1935,17 @@
         if (DBG) {
             Slog.v(TAG, "unclassifyNotification: " + r);
         }
-
-        boolean hasOriginalSummary = false;
-        if (r.getSbn().isAppGroup() && r.getNotification().isGroupChild()) {
-            final String oldGroupKey = GroupHelper.getFullAggregateGroupKey(
-                    r.getSbn().getPackageName(), r.getOriginalGroupKey(), r.getUserId());
-            NotificationRecord groupSummary = mSummaryByGroupKey.get(oldGroupKey);
-            // We only care about app-provided valid groups
-            hasOriginalSummary = (groupSummary != null
-                    && !GroupHelper.isAggregatedGroup(groupSummary));
-        }
-
         // Only NotificationRecord's mChannel is updated when bundled, the Notification
         // mChannelId will always be the original channel.
         String origChannelId = r.getNotification().getChannelId();
         NotificationChannel originalChannel = mPreferencesHelper.getNotificationChannel(
                 r.getSbn().getPackageName(), r.getUid(), origChannelId, false);
         String currChannelId = r.getChannel().getId();
-        boolean isBundled = NotificationChannel.SYSTEM_RESERVED_IDS.contains(currChannelId);
-        if (originalChannel != null && !origChannelId.equals(currChannelId) && isBundled) {
+        boolean isClassified = NotificationChannel.SYSTEM_RESERVED_IDS.contains(currChannelId);
+        if (originalChannel != null && !origChannelId.equals(currChannelId) && isClassified) {
             r.updateNotificationChannel(originalChannel);
-            mGroupHelper.onNotificationUnbundled(r, hasOriginalSummary);
+            mGroupHelper.onNotificationUnbundled(r,
+                    GroupHelper.isOriginalGroupSummaryPresent(r, mSummaryByGroupKey));
         }
     }
 
@@ -2034,9 +2030,9 @@
             Slog.v(TAG, "reclassifyNotification: " + r);
         }
 
-        boolean isBundled = NotificationChannel.SYSTEM_RESERVED_IDS.contains(
+        boolean isClassified = NotificationChannel.SYSTEM_RESERVED_IDS.contains(
                 r.getChannel().getId());
-        if (r.getBundleType() != Adjustment.TYPE_OTHER && !isBundled) {
+        if (r.getBundleType() != Adjustment.TYPE_OTHER && !isClassified) {
             final Bundle classifBundle = new Bundle();
             classifBundle.putInt(KEY_TYPE, r.getBundleType());
             Adjustment adj = new Adjustment(r.getSbn().getPackageName(), r.getKey(),
@@ -3583,7 +3579,7 @@
                 synchronized (mNotificationLock) {
                     mGroupHelper.onChannelUpdated(
                             UserHandle.getUserHandleForUid(uid).getIdentifier(), pkg,
-                            updatedChannel, mNotificationList);
+                            updatedChannel, mNotificationList, mSummaryByGroupKey);
                 }
             }, DELAY_FORCE_REGROUP_TIME);
         }
@@ -4531,7 +4527,7 @@
                     if (key == null) {
                         return;
                     }
-                    mAssistants.setAdjustmentTypeSupportedState(info,  key, supported);
+                    mAssistants.setAdjustmentTypeSupportedState(info.userid,  key, supported);
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -4574,6 +4570,12 @@
         }
 
         @Override
+        public String[] getAdjustmentDeniedPackages(String key) {
+            checkCallerIsSystemOrSystemUiOrShell();
+            return mAssistants.getAdjustmentDeniedPackages(key);
+        }
+
+        @Override
         public boolean isAdjustmentSupportedForPackage(String key, String pkg) {
             checkCallerIsSystemOrSystemUiOrShell();
             return mAssistants.isAdjustmentAllowedForPackage(key, pkg);
@@ -5020,8 +5022,8 @@
         public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(
                 String pkg) {
             checkCallerIsSystemOrSameApp(pkg);
-            return mPreferencesHelper.getNotificationChannelGroups(
-                    pkg, Binder.getCallingUid(), false, false, true, true, null);
+            return mPreferencesHelper.getNotificationChannelGroups(pkg, Binder.getCallingUid(),
+                    NotificationChannelGroupsHelper.Params.forAllGroups());
         }
 
         @Override
@@ -5141,8 +5143,9 @@
         public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroupsForPackage(
                 String pkg, int uid, boolean includeDeleted) {
             enforceSystemOrSystemUI("getNotificationChannelGroupsForPackage");
-            return mPreferencesHelper.getNotificationChannelGroups(
-                    pkg, uid, includeDeleted, true, false, true, null);
+            return mPreferencesHelper.getNotificationChannelGroups(pkg, uid,
+                    new NotificationChannelGroupsHelper.Params(includeDeleted, true, false, true,
+                            null));
         }
 
         @Override
@@ -5170,8 +5173,9 @@
                 }
             }
 
-            return mPreferencesHelper.getNotificationChannelGroups(
-                    pkg, uid, false, true, false, true, recentlySentChannels);
+            return mPreferencesHelper.getNotificationChannelGroups(pkg, uid,
+                    NotificationChannelGroupsHelper.Params.onlySpecifiedOrBlockedChannels(
+                            recentlySentChannels));
         }
 
         @Override
@@ -7024,7 +7028,7 @@
             final long identity = Binder.clearCallingIdentity();
             try {
                 synchronized (mNotificationLock) {
-                    mAssistants.checkServiceTokenLocked(token);
+                    ManagedServiceInfo info = mAssistants.checkServiceTokenLocked(token);
                     int N = mEnqueuedNotifications.size();
                     for (int i = 0; i < N; i++) {
                         final NotificationRecord r = mEnqueuedNotifications.get(i);
@@ -7370,6 +7374,10 @@
                     mAssistants.setPackageOrComponentEnabled(assistant.flattenToString(),
                             userId, true, granted, userSet);
 
+                    if (android.service.notification.Flags.notificationClassification()) {
+                        mAssistants.setNasUnsupportedDefaults(userId);
+                    }
+
                     getContext().sendBroadcastAsUser(
                             new Intent(ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED)
                                     .setPackage(assistant.getPackageName())
@@ -7401,7 +7409,8 @@
                     toRemove.add(potentialKey);
                 }
                 if (notificationClassification() && potentialKey.equals(KEY_TYPE)) {
-                    mAssistants.setNasUnsupportedDefaults(r.getSbn().getNormalizedUserId());
+                    mAssistants.setAdjustmentTypeSupportedState(
+                            r.getSbn().getNormalizedUserId(), potentialKey, true);
                     if (!mAssistants.isAdjustmentKeyTypeAllowed(adjustments.getInt(KEY_TYPE))) {
                         toRemove.add(potentialKey);
                     } else if (notificationClassificationUi()
@@ -7412,6 +7421,8 @@
                 }
                 if ((nmSummarization() || nmSummarizationUi())
                         && potentialKey.equals(KEY_SUMMARIZATION)) {
+                    mAssistants.setAdjustmentTypeSupportedState(
+                            r.getSbn().getNormalizedUserId(), potentialKey, true);
                     if (!mAssistants.isAdjustmentAllowedForPackage(KEY_SUMMARIZATION,
                             r.getSbn().getPackageName())) {
                         toRemove.add(potentialKey);
@@ -12069,8 +12080,8 @@
         private static final String TAG_DENIED_KEY = "adjustment";
         private static final String ATT_DENIED_KEY = "key";
         private static final String ATT_DENIED_KEY_APPS = "denied_apps";
-        private static final String TAG_ENABLED_TYPES = "enabled_key_types";
-        private static final String ATT_NAS_UNSUPPORTED = "nas_unsupported_adjustments";
+        private static final String TAG_ENABLED_TYPES = "enabled_classification_types";
+        private static final String ATT_NAS_UNSUPPORTED = "unsupported_adjustments";
 
         private final Object mLock = new Object();
 
@@ -12290,6 +12301,16 @@
             }
         }
 
+        protected @NonNull String[] getAdjustmentDeniedPackages(@Adjustment.Keys String key) {
+            synchronized (mLock) {
+                if (notificationClassificationUi() || nmSummarization() | nmSummarizationUi()) {
+                    return mAdjustmentKeyDeniedPackages.getOrDefault(
+                            key, new ArraySet<>()).toArray(new String[0]);
+                }
+            }
+            return new String[]{};
+        }
+
         protected @NonNull boolean isAdjustmentAllowedForPackage(@Adjustment.Keys String key,
                 String pkg) {
             synchronized (mLock) {
@@ -12672,10 +12693,6 @@
                     setNotificationAssistantAccessGrantedForUserInternal(
                             currentComponent, userId, false, userSet);
                 }
-            } else {
-                if (android.service.notification.Flags.notificationClassification()) {
-                    setNasUnsupportedDefaults(userId);
-                }
             }
             super.setPackageOrComponentEnabled(pkgOrComponent, userId, isPrimary, enabled, userSet);
         }
@@ -12708,36 +12725,37 @@
             }
         }
 
-        @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
         @GuardedBy("mNotificationLock")
-        public void setAdjustmentTypeSupportedState(ManagedServiceInfo info,
+        public void setAdjustmentTypeSupportedState(@UserIdInt int userId,
                 @Adjustment.Keys String key, boolean supported) {
-            if (!android.service.notification.Flags.notificationClassification()) {
+            if (!(android.service.notification.Flags.notificationClassification()
+                    || android.app.Flags.nmSummarizationUi()
+                    || android.app.Flags.nmSummarization())) {
                 return;
             }
-            setNasUnsupportedDefaults(info.userid);
-            HashSet<String> disabledAdjustments = mNasUnsupported.get(info.userid);
+            HashSet<String> disabledAdjustments =
+                    mNasUnsupported.getOrDefault(userId, new HashSet<>());
             if (supported) {
                 disabledAdjustments.remove(key);
             } else {
                 disabledAdjustments.add(key);
             }
-            mNasUnsupported.put(info.userid, disabledAdjustments);
+            mNasUnsupported.put(userId, disabledAdjustments);
             handleSavePolicyFile();
         }
 
-        @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
         @GuardedBy("mNotificationLock")
         public @NonNull Set<String> getUnsupportedAdjustments(@UserIdInt int userId) {
-            if (!android.service.notification.Flags.notificationClassification()) {
+            if (!(android.service.notification.Flags.notificationClassification()
+                    || android.app.Flags.nmSummarizationUi()
+                    || android.app.Flags.nmSummarization())) {
                 return new HashSet<>();
             }
-            setNasUnsupportedDefaults(userId);
-            return mNasUnsupported.get(userId);
+            return mNasUnsupported.getOrDefault(userId, new HashSet<>());
         }
 
         private void setNasUnsupportedDefaults(@UserIdInt int userId) {
-            if (mNasUnsupported != null && !mNasUnsupported.containsKey(userId)) {
+            if (mNasUnsupported != null) {
                 mNasUnsupported.put(userId, new HashSet(List.of(mDefaultUnsupportedAdjustments)));
                 handleSavePolicyFile();
             }
@@ -12750,10 +12768,8 @@
                 return;
             }
             synchronized (mLock) {
-                if (mNasUnsupported.containsKey(approvedUserId)) {
-                    out.attribute(null, ATT_NAS_UNSUPPORTED,
-                            TextUtils.join(",", mNasUnsupported.get(approvedUserId)));
-                }
+                out.attribute(null, ATT_NAS_UNSUPPORTED, TextUtils.join(",",
+                        mNasUnsupported.getOrDefault(approvedUserId, new HashSet<>())));
             }
         }
 
@@ -12766,8 +12782,15 @@
             if (ManagedServices.TAG_MANAGED_SERVICES.equals(tag)) {
                 final String types = XmlUtils.readStringAttribute(parser, ATT_NAS_UNSUPPORTED);
                 synchronized (mLock) {
-                    if (!TextUtils.isEmpty(types)) {
-                        mNasUnsupported.put(approvedUserId, new HashSet(List.of(types.split(","))));
+                    if (types == null) {
+                        setNasUnsupportedDefaults(approvedUserId);
+                    } else {
+                        if (!TextUtils.isEmpty(types)) {
+                            mNasUnsupported.put(approvedUserId,
+                                    new HashSet(List.of(types.split(","))));
+                        } else {
+                            mNasUnsupported.put(approvedUserId, new HashSet());
+                        }
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 1def7ec..5a58f45 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -1681,9 +1681,13 @@
         }
 
         if (mTargetSdkVersion >= Build.VERSION_CODES.R
-                && notification.isStyle(Notification.MessagingStyle.class)
-                && (mShortcutInfo == null || isOnlyBots(mShortcutInfo.getPersons()))) {
-            return false;
+                && notification.isStyle(Notification.MessagingStyle.class)) {
+            if (mShortcutInfo == null || isOnlyBots(mShortcutInfo.getPersons())) {
+                return false;
+            }
+            if (Flags.notificationNoCustomViewConversations() && hasUndecoratedRemoteView()) {
+                return false;
+            }
         }
         if (mHasSentValidMsg && mShortcutInfo == null) {
             return false;
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 7d45cd9..46c99cd 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -92,6 +92,7 @@
 import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
 import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags;
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.notification.NotificationChannelGroupsHelper;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.XmlUtils;
@@ -1678,18 +1679,8 @@
             if (r == null || groupId == null || !r.groups.containsKey(groupId)) {
                 return null;
             }
-            NotificationChannelGroup group = r.groups.get(groupId).clone();
-            group.setChannels(new ArrayList<>());
-            int N = r.channels.size();
-            for (int i = 0; i < N; i++) {
-                final NotificationChannel nc = r.channels.valueAt(i);
-                if (includeDeleted || !nc.isDeleted()) {
-                    if (groupId.equals(nc.getGroup())) {
-                        group.addChannel(nc);
-                    }
-                }
-            }
-            return group;
+            return NotificationChannelGroupsHelper.getGroupWithChannels(groupId,
+                    r.channels.values(), r.groups, includeDeleted);
         }
     }
 
@@ -1706,51 +1697,16 @@
     }
 
     public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
-            int uid, boolean includeDeleted, boolean includeNonGrouped, boolean includeEmpty,
-            boolean includeBlocked, Set<String> activeChannelFilter) {
+            int uid, NotificationChannelGroupsHelper.Params params) {
         Objects.requireNonNull(pkg);
-        Map<String, NotificationChannelGroup> groups = new ArrayMap<>();
         synchronized (mLock) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 return ParceledListSlice.emptyList();
             }
-            NotificationChannelGroup nonGrouped = new NotificationChannelGroup(null, null);
-            int N = r.channels.size();
-            for (int i = 0; i < N; i++) {
-                final NotificationChannel nc = r.channels.valueAt(i);
-                boolean includeChannel = (includeDeleted || !nc.isDeleted())
-                        && (activeChannelFilter == null
-                                || (includeBlocked && nc.getImportance() == IMPORTANCE_NONE)
-                                || activeChannelFilter.contains(nc.getId()))
-                        && !SYSTEM_RESERVED_IDS.contains(nc.getId());
-                if (includeChannel) {
-                    if (nc.getGroup() != null) {
-                        if (r.groups.get(nc.getGroup()) != null) {
-                            NotificationChannelGroup ncg = groups.get(nc.getGroup());
-                            if (ncg == null) {
-                                ncg = r.groups.get(nc.getGroup()).clone();
-                                ncg.setChannels(new ArrayList<>());
-                                groups.put(nc.getGroup(), ncg);
-                            }
-                            ncg.addChannel(nc);
-                        }
-                    } else {
-                        nonGrouped.addChannel(nc);
-                    }
-                }
-            }
-            if (includeNonGrouped && nonGrouped.getChannels().size() > 0) {
-                groups.put(null, nonGrouped);
-            }
-            if (includeEmpty) {
-                for (NotificationChannelGroup group : r.groups.values()) {
-                    if (!groups.containsKey(group.getId())) {
-                        groups.put(group.getId(), group);
-                    }
-                }
-            }
-            return new ParceledListSlice<>(new ArrayList<>(groups.values()));
+            return new ParceledListSlice<>(
+                    NotificationChannelGroupsHelper.getGroupsWithChannels(r.channels.values(),
+                            r.groups, params));
         }
     }
 
@@ -2397,6 +2353,12 @@
                     pw.print(r.canHavePromotedNotifs);
                 }
                 pw.println();
+                if (r.delegate != null) {
+                    pw.print(prefix);
+                    pw.printf("    Delegate: %s (%s) enabled=%s", r.delegate.mPkg, r.delegate.mUid,
+                            r.delegate.mEnabled);
+                    pw.println();
+                }
                 for (NotificationChannel channel : r.channels.values()) {
                     pw.print(prefix);
                     channel.dump(pw, "    ", filter.redact);
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 8710438..d6b587b 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -251,14 +251,17 @@
 
     private final Object mLock = new Object();
 
+    @GuardedBy("mLock")
     private final AtomicFile mSettingsFile;
 
     private final PackageManagerHelperImpl mPackageManager;
 
     private final UserManagerService mUserManager;
 
+    @GuardedBy("mLock")
     private final OverlayManagerSettings mSettings;
 
+    @GuardedBy("mLock")
     private final OverlayManagerServiceImpl mImpl;
 
     private final OverlayActorEnforcer mActorEnforcer;
@@ -296,7 +299,9 @@
             UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
             umi.addUserLifecycleListener(new UserLifecycleListener());
 
-            restoreSettings();
+            // No async stuff happening in the constructor yet, so it's OK to call a ...Locked()
+            // method without a lock here.
+            restoreSettingsLocked();
 
             // Wipe all shell overlays on boot, to recover from a potentially broken device
             String shellPkgName = TextUtils.emptyIfNull(
@@ -403,6 +408,20 @@
         return userIds;
     }
 
+    /**
+     * Ensure that the caller has permission to interact with the given userId.
+     * If the calling user is not the same as the provided user, the caller needs
+     * to hold the INTERACT_ACROSS_USERS_FULL permission (or be system uid or
+     * root).
+     *
+     * @param userId the user to interact with
+     * @param message message for any SecurityException
+     */
+    static int handleIncomingUser(final int userId, @NonNull final String message) {
+        return ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+                Binder.getCallingUid(), userId, false, true, message, null);
+    }
+
     private void handlePackageAdd(String packageName, Bundle extras, int userId) {
         final boolean replacing = extras.getBoolean(Intent.EXTRA_REPLACING, false);
         if (replacing) {
@@ -902,25 +921,28 @@
                 throws RemoteException {
             try {
                 traceBegin(TRACE_TAG_RRO, "OMS#commit " + transaction);
-                try {
-                    executeAllRequests(transaction);
-                } catch (Exception e) {
-                    final long ident = Binder.clearCallingIdentity();
+                synchronized (mLock) {
                     try {
-                        restoreSettings();
-                    } finally {
-                        Binder.restoreCallingIdentity(ident);
+                        executeAllRequestsLocked(transaction);
+                    } catch (Exception e) {
+                        final long ident = Binder.clearCallingIdentity();
+                        try {
+                            restoreSettingsLocked();
+                        } finally {
+                            Binder.restoreCallingIdentity(ident);
+                        }
+                        Slog.d(TAG, "commit failed: " + e.getMessage(), e);
+                        throw new SecurityException("commit failed"
+                                + (DEBUG || Build.IS_DEBUGGABLE ? ": " + e.getMessage() : ""));
                     }
-                    Slog.d(TAG, "commit failed: " + e.getMessage(), e);
-                    throw new SecurityException("commit failed"
-                            + (DEBUG || Build.IS_DEBUGGABLE ? ": " + e.getMessage() : ""));
                 }
             } finally {
                 traceEnd(TRACE_TAG_RRO);
             }
         }
 
-        private Set<UserPackage> executeRequest(
+        @GuardedBy("mLock")
+        private Set<UserPackage> executeRequestLocked(
                 @NonNull final OverlayManagerTransaction.Request request)
                 throws OperationFailedException {
             Objects.requireNonNull(request, "Transaction contains a null request");
@@ -995,33 +1017,29 @@
             }
         }
 
-        private void executeAllRequests(@NonNull final OverlayManagerTransaction transaction)
+        @GuardedBy("mLock")
+        private void executeAllRequestsLocked(@NonNull final OverlayManagerTransaction transaction)
                 throws OperationFailedException {
             if (DEBUG) {
                 Slog.d(TAG, "commit " + transaction);
             }
-            if (transaction == null) {
-                throw new IllegalArgumentException("null transaction");
+
+            // execute the requests (as calling user)
+            Set<UserPackage> affectedPackagesToUpdate = null;
+            for (Iterator<Request> it = transaction.getRequests(); it.hasNext(); ) {
+                Request request = it.next();
+                affectedPackagesToUpdate = CollectionUtils.addAll(affectedPackagesToUpdate,
+                        executeRequestLocked(request));
             }
 
-            synchronized (mLock) {
-                // execute the requests (as calling user)
-                Set<UserPackage> affectedPackagesToUpdate = null;
-                for (Iterator<Request> it = transaction.getRequests(); it.hasNext(); ) {
-                    Request request = it.next();
-                    affectedPackagesToUpdate = CollectionUtils.addAll(affectedPackagesToUpdate,
-                            executeRequest(request));
-                }
-
-                // past the point of no return: the entire transaction has been
-                // processed successfully, we can no longer fail: continue as
-                // system_server
-                final long ident = Binder.clearCallingIdentity();
-                try {
-                    updateTargetPackagesLocked(affectedPackagesToUpdate);
-                } finally {
-                    Binder.restoreCallingIdentity(ident);
-                }
+            // past the point of no return: the entire transaction has been
+            // processed successfully, we can no longer fail: continue as
+            // system_server
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                updateTargetPackagesLocked(affectedPackagesToUpdate);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
             }
         }
 
@@ -1037,7 +1055,7 @@
         @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             final DumpState dumpState = new DumpState();
-            dumpState.setUserId(UserHandle.USER_ALL);
+            int userId = UserHandle.USER_ALL;
 
             int opti = 0;
             while (opti < args.length) {
@@ -1064,9 +1082,7 @@
                         return;
                     }
                     try {
-                        final int userId = UserHandle.parseUserArg(args[opti]);
-                        final int realUserId = handleIncomingUser(userId, "dump");
-                        dumpState.setUserId(realUserId);
+                        userId = UserHandle.parseUserArg(args[opti]);
                         opti++;
                     } catch (Exception e) {
                         pw.println("Error: " + e.getMessage());
@@ -1105,6 +1121,9 @@
             }
 
             enforceDumpPermission("dump");
+            final int realUserId = userId != UserHandle.USER_ALL
+                    ? handleIncomingUser(userId, "dump") : userId;
+            dumpState.setUserId(realUserId);
             synchronized (mLock) {
                 mImpl.dump(pw, dumpState);
                 if (dumpState.getPackageName() == null) {
@@ -1114,20 +1133,6 @@
         }
 
         /**
-         * Ensure that the caller has permission to interact with the given userId.
-         * If the calling user is not the same as the provided user, the caller needs
-         * to hold the INTERACT_ACROSS_USERS_FULL permission (or be system uid or
-         * root).
-         *
-         * @param userId the user to interact with
-         * @param message message for any SecurityException
-         */
-        private int handleIncomingUser(final int userId, @NonNull final String message) {
-            return ActivityManager.handleIncomingUser(Binder.getCallingPid(),
-                    Binder.getCallingUid(), userId, false, true, message, null);
-        }
-
-        /**
          * Enforce that the caller holds the DUMP permission (or is system or root).
          *
          * @param message used as message if SecurityException is thrown
@@ -1447,12 +1452,14 @@
         }
     }
 
+    @GuardedBy("mLock")
     private void updateTargetPackagesLocked(@Nullable UserPackage updatedTarget) {
         if (updatedTarget != null) {
             updateTargetPackagesLocked(Set.of(updatedTarget));
         }
     }
 
+    @GuardedBy("mLock")
     private void updateTargetPackagesLocked(@Nullable Set<UserPackage> updatedTargets) {
         if (CollectionUtils.isEmpty(updatedTargets)) {
             return;
@@ -1548,6 +1555,7 @@
     }
 
     @NonNull
+    @GuardedBy("mLock")
     private SparseArray<List<String>> updatePackageManagerLocked(
             @Nullable Set<UserPackage> targets) {
         if (CollectionUtils.isEmpty(targets)) {
@@ -1568,6 +1576,7 @@
      *         targetPackageNames: the target themselves and shared libraries)
      */
     @NonNull
+    @GuardedBy("mLock")
     private List<String> updatePackageManagerLocked(@NonNull Collection<String> targetPackageNames,
             final int userId) {
         try {
@@ -1623,6 +1632,7 @@
         }
     }
 
+    @GuardedBy("mLock")
     private void persistSettingsLocked() {
         if (DEBUG) {
             Slog.d(TAG, "Writing overlay settings");
@@ -1638,35 +1648,35 @@
         }
     }
 
-    private void restoreSettings() {
+    @GuardedBy("mLock")
+    private void restoreSettingsLocked() {
         try {
             traceBegin(TRACE_TAG_RRO, "OMS#restoreSettings");
-            synchronized (mLock) {
-                if (!mSettingsFile.getBaseFile().exists()) {
-                    return;
+
+            if (!mSettingsFile.getBaseFile().exists()) {
+                return;
+            }
+            try (FileInputStream stream = mSettingsFile.openRead()) {
+                mSettings.restore(stream);
+
+                // We might have data for dying users if the device was
+                // restarted before we received USER_REMOVED. Remove data for
+                // users that will not exist after the system is ready.
+
+                final List<UserInfo> liveUsers = mUserManager.getUsers(true /*excludeDying*/);
+                final int[] liveUserIds = new int[liveUsers.size()];
+                for (int i = 0; i < liveUsers.size(); i++) {
+                    liveUserIds[i] = liveUsers.get(i).getUserHandle().getIdentifier();
                 }
-                try (FileInputStream stream = mSettingsFile.openRead()) {
-                    mSettings.restore(stream);
+                Arrays.sort(liveUserIds);
 
-                    // We might have data for dying users if the device was
-                    // restarted before we received USER_REMOVED. Remove data for
-                    // users that will not exist after the system is ready.
-
-                    final List<UserInfo> liveUsers = mUserManager.getUsers(true /*excludeDying*/);
-                    final int[] liveUserIds = new int[liveUsers.size()];
-                    for (int i = 0; i < liveUsers.size(); i++) {
-                        liveUserIds[i] = liveUsers.get(i).getUserHandle().getIdentifier();
+                for (int userId : mSettings.getUsers()) {
+                    if (Arrays.binarySearch(liveUserIds, userId) < 0) {
+                        mSettings.removeUser(userId);
                     }
-                    Arrays.sort(liveUserIds);
-
-                    for (int userId : mSettings.getUsers()) {
-                        if (Arrays.binarySearch(liveUserIds, userId) < 0) {
-                            mSettings.removeUser(userId);
-                        }
-                    }
-                } catch (IOException | XmlPullParserException e) {
-                    Slog.e(TAG, "failed to restore overlay state", e);
                 }
+            } catch (IOException | XmlPullParserException e) {
+                Slog.e(TAG, "failed to restore overlay state", e);
             }
         } finally {
             traceEnd(TRACE_TAG_RRO);
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index 0e9ec4d..02c0190 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -715,20 +715,11 @@
     }
 
     void dump(@NonNull final PrintWriter pw, @NonNull DumpState dumpState) {
-        Pair<OverlayIdentifier, String> overlayIdmap = null;
-        if (dumpState.getPackageName() != null) {
-            OverlayIdentifier id = new OverlayIdentifier(dumpState.getPackageName(),
-                    dumpState.getOverlayName());
-            OverlayInfo oi = mSettings.getNullableOverlayInfo(id, USER_SYSTEM);
-            if (oi != null) {
-                overlayIdmap = new Pair<>(id, oi.baseCodePath);
-            }
-        }
-
         // settings
         mSettings.dump(pw, dumpState);
 
         // idmap data
+        final var overlayIdmap = mSettings.getIdentifierAndBaseCodePath(dumpState);
         if (dumpState.getField() == null) {
             Set<Pair<OverlayIdentifier, String>> allIdmaps = (overlayIdmap != null)
                     ? Set.of(overlayIdmap) : mSettings.getAllIdentifiersAndBaseCodePaths();
diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java
index f9758fc..e6b1c5f 100644
--- a/services/core/java/com/android/server/om/OverlayManagerSettings.java
+++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java
@@ -212,17 +212,41 @@
     }
 
     Set<String> getAllBaseCodePaths() {
+        // Overlays installed for multiple users have the same code path, avoid duplicates with Set.
         final Set<String> paths = new ArraySet<>();
         mItems.forEach(item -> paths.add(item.mBaseCodePath));
         return paths;
     }
 
     Set<Pair<OverlayIdentifier, String>> getAllIdentifiersAndBaseCodePaths() {
+        // Overlays installed for multiple users have the same code path, avoid duplicates with Set.
         final Set<Pair<OverlayIdentifier, String>> set = new ArraySet<>();
-        mItems.forEach(item -> set.add(new Pair(item.mOverlay, item.mBaseCodePath)));
+        mItems.forEach(item -> set.add(new Pair<>(item.mOverlay, item.mBaseCodePath)));
         return set;
     }
 
+    @Nullable
+    Pair<OverlayIdentifier, String> getIdentifierAndBaseCodePath(@NonNull DumpState dumpState) {
+        if (dumpState.getPackageName() == null) {
+            return null;
+        }
+        OverlayIdentifier id = new OverlayIdentifier(dumpState.getPackageName(),
+                dumpState.getOverlayName());
+        final int userId = dumpState.getUserId();
+        for (int i = 0; i < mItems.size(); i++) {
+            final var item = mItems.get(i);
+            if (userId != UserHandle.USER_ALL && userId != item.mUserId) {
+                continue;
+            }
+            if (!id.equals(item.mOverlay)) {
+                continue;
+            }
+            // Overlays installed for multiple users have the same code path, return first found.
+            return new Pair<>(id, item.mBaseCodePath);
+        }
+        return null;
+    }
+
     @NonNull
     List<OverlayInfo> removeIf(@NonNull final Predicate<OverlayInfo> predicate, final int userId) {
         return removeIf(info -> (predicate.test(info) && info.userId == userId));
diff --git a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
index b7f2112..39a6b18 100644
--- a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
+++ b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
@@ -17,6 +17,7 @@
 package com.android.server.om;
 
 import static com.android.internal.content.om.OverlayConfig.PARTITION_ORDER_FILE_PATH;
+import static com.android.server.om.OverlayManagerService.handleIncomingUser;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -145,7 +146,7 @@
         out.println("    Load a package and print the value of a given resource");
         out.println("    applying the current configuration and enabled overlays.");
         out.println("    For a more fine-grained alternative, use 'idmap2 lookup'.");
-        out.println("  fabricate [--user USER_ID] [--target-name OVERLAYABLE] --target PACKAGE");
+        out.println("  fabricate [--target-name OVERLAYABLE] --target PACKAGE");
         out.println("            --name NAME [--file FILE] ");
         out.println("            PACKAGE:TYPE/NAME ENCODED-TYPE-ID|TYPE-NAME ENCODED-VALUE");
         out.println("    Create an overlay from a single resource. Caller must be root. Example:");
@@ -160,7 +161,7 @@
         final PrintWriter out = getOutPrintWriter();
         final PrintWriter err = getErrPrintWriter();
 
-        int userId = UserHandle.USER_SYSTEM;
+        int userId = UserHandle.USER_CURRENT;
         String opt;
         while ((opt = getNextOption()) != null) {
             switch (opt) {
@@ -234,7 +235,7 @@
     private int runEnableDisable(final boolean enable) throws RemoteException {
         final PrintWriter err = getErrPrintWriter();
 
-        int userId = UserHandle.USER_SYSTEM;
+        int userId = UserHandle.USER_CURRENT;
         String opt;
         while ((opt = getNextOption()) != null) {
             switch (opt) {
@@ -269,7 +270,6 @@
             return 1;
         }
 
-        int userId = UserHandle.USER_SYSTEM;
         String targetPackage = "";
         String targetOverlayable = "";
         String name = "";
@@ -278,9 +278,6 @@
         String config = null;
         while ((opt = getNextOption()) != null) {
             switch (opt) {
-                case "--user":
-                    userId = UserHandle.parseUserArg(getNextArgRequired());
-                    break;
                 case "--target":
                     targetPackage = getNextArgRequired();
                     break;
@@ -442,7 +439,7 @@
     private int runEnableExclusive() throws RemoteException {
         final PrintWriter err = getErrPrintWriter();
 
-        int userId = UserHandle.USER_SYSTEM;
+        int userId = UserHandle.USER_CURRENT;
         boolean inCategory = false;
         String opt;
         while ((opt = getNextOption()) != null) {
@@ -469,7 +466,7 @@
     private int runSetPriority() throws RemoteException {
         final PrintWriter err = getErrPrintWriter();
 
-        int userId = UserHandle.USER_SYSTEM;
+        int userId = UserHandle.USER_CURRENT;
         String opt;
         while ((opt = getNextOption()) != null) {
             switch (opt) {
@@ -498,7 +495,7 @@
         final PrintWriter out = getOutPrintWriter();
         final PrintWriter err = getErrPrintWriter();
 
-        int userId = UserHandle.USER_SYSTEM;
+        int userId = UserHandle.USER_CURRENT;
         boolean verbose = false;
         String opt;
         while ((opt = getNextOption()) != null) {
@@ -525,15 +522,16 @@
             return 1;
         }
 
+        final int realUserId = handleIncomingUser(userId, "runLookup");
         final Resources res;
         try {
             res = mContext
-                .createContextAsUser(UserHandle.of(userId), /* flags */ 0)
+                .createContextAsUser(UserHandle.of(realUserId), /* flags */ 0)
                 .getPackageManager()
                 .getResourcesForApplication(packageToLoad);
         } catch (PackageManager.NameNotFoundException e) {
             err.println(String.format("Error: failed to get resources for package %s for user %d",
-                    packageToLoad, userId));
+                    packageToLoad, realUserId));
             return 1;
         }
         final AssetManager assets = res.getAssets();
diff --git a/services/core/java/com/android/server/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java
index c62aaeb..f88681d 100644
--- a/services/core/java/com/android/server/pm/UserManagerInternal.java
+++ b/services/core/java/com/android/server/pm/UserManagerInternal.java
@@ -23,7 +23,9 @@
 import android.content.pm.LauncherUserInfo;
 import android.content.pm.UserInfo;
 import android.content.pm.UserProperties;
+import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.multiuser.Flags;
 import android.os.Bundle;
 import android.os.UserManager;
 import android.util.DebugUtils;
@@ -351,8 +353,10 @@
             boolean excludePreCreated);
 
     /**
-     * Returns an array of ids for profiles associated with the specified user including the user
-     * itself.
+     * Returns a list of the users that are associated with the specified user, including the user
+     * itself. This includes the user, its profiles, its parent, and its parent's other profiles,
+     * as applicable.
+     *
      * <p>Note that this includes all profile types (not including Restricted profiles).
      *
      * @param userId      id of the user to return profiles for
@@ -617,4 +621,14 @@
      * if there is no such user.
      */
     public abstract @UserIdInt int getCommunalProfileId();
+
+    /**
+     * Checks whether to show a notification for sounds (e.g., alarms, timers, etc.) from
+     * background users.
+     */
+    public static boolean shouldShowNotificationForBackgroundUserSounds() {
+        return Flags.addUiForSoundsFromBackgroundUsers() && Resources.getSystem().getBoolean(
+                com.android.internal.R.bool.config_showNotificationForBackgroundUserAlarms)
+                && UserManager.supportsMultipleUsers();
+    }
 }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 8cbccf5..c7737e9 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -33,7 +33,6 @@
 import static android.os.UserManager.USER_OPERATION_ERROR_UNKNOWN;
 import static android.os.UserManager.USER_OPERATION_ERROR_USER_RESTRICTED;
 import static android.os.UserManager.USER_TYPE_PROFILE_PRIVATE;
-import static android.os.UserManager.supportsMultipleUsers;
 import static android.provider.Settings.Secure.HIDE_PRIVATESPACE_ENTRY_POINT;
 
 import static com.android.internal.app.SetScreenLockDialogActivity.EXTRA_ORIGIN_USER_ID;
@@ -60,7 +59,6 @@
 import android.annotation.SpecialUsers.CanBeALL;
 import android.annotation.SpecialUsers.CanBeCURRENT;
 import android.annotation.SpecialUsers.CanBeNULL;
-import android.annotation.SpecialUsers.CannotBeSpecialUser;
 import android.annotation.StringRes;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
@@ -131,6 +129,7 @@
 import android.os.UserManager;
 import android.os.UserManager.EnforcingUser;
 import android.os.UserManager.QuietModeFlag;
+import android.os.UserManager.UserLogoutability;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageManagerInternal;
 import android.provider.Settings;
@@ -1161,7 +1160,7 @@
 
         showHsumNotificationIfNeeded();
 
-        if (shouldShowNotificationForBackgroundUserSounds()) {
+        if (UserManagerInternal.shouldShowNotificationForBackgroundUserSounds()) {
             new BackgroundUserSoundNotifier(mContext);
         }
     }
@@ -1474,10 +1473,13 @@
        return UserHandle.USER_NULL;
    }
 
-
     @Override
     public @CanBeNULL @UserIdInt int getPreviousFullUserToEnterForeground() {
         checkQueryOrCreateUsersPermission("get previous user");
+        return getPreviousFullUserToEnterForegroundUnchecked();
+    }
+
+    private int getPreviousFullUserToEnterForegroundUnchecked() {
         int previousUser = UserHandle.USER_NULL;
         long latestEnteredTime = 0;
         final int currentUser = getCurrentUserId();
@@ -1638,7 +1640,7 @@
         final int userSize = mUsers.size();
         for (int i = 0; i < userSize; i++) {
             UserInfo profile = mUsers.valueAt(i).info;
-            if (!isProfileOf(user, profile)) {
+            if (!isSameProfileGroup(user, profile)) {
                 continue;
             }
             if (enabledOnly && !profile.isEnabled()) {
@@ -1706,22 +1708,18 @@
         return isSameProfileGroupNoChecks(userId, otherUserId);
     }
 
-    /**
-     * Returns whether users are in the same non-empty profile group.
-     * Currently, false if empty profile group, even if they are the same user, for whatever reason.
-     */
+    /** Returns whether users are in the same profile group. */
     private boolean isSameProfileGroupNoChecks(@UserIdInt int userId, int otherUserId) {
         synchronized (mUsersLock) {
             UserInfo userInfo = getUserInfoLU(userId);
-            if (userInfo == null || userInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
+            if (userInfo == null) {
                 return false;
             }
             UserInfo otherUserInfo = getUserInfoLU(otherUserId);
-            if (otherUserInfo == null
-                    || otherUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID) {
+            if (otherUserInfo == null) {
                 return false;
             }
-            return userInfo.profileGroupId == otherUserInfo.profileGroupId;
+            return isSameProfileGroup(userInfo, otherUserInfo);
         }
     }
 
@@ -1780,10 +1778,10 @@
         }
     }
 
-    private static boolean isProfileOf(UserInfo user, UserInfo profile) {
-        return user.id == profile.id ||
-                (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
-                && user.profileGroupId == profile.profileGroupId);
+    private static boolean isSameProfileGroup(@NonNull UserInfo user1, @NonNull UserInfo user2) {
+        return user1.id == user2.id ||
+                (user1.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
+                && user1.profileGroupId == user2.profileGroupId);
     }
 
     private String getAvailabilityIntentAction(boolean enableQuietMode, boolean useManagedActions) {
@@ -2921,7 +2919,8 @@
      * @return A {@link UserManager.UserSwitchabilityResult} flag indicating if the user is
      * switchable.
      */
-    public @UserManager.UserSwitchabilityResult int getUserSwitchability(int userId) {
+    @Override
+    public @UserManager.UserSwitchabilityResult int getUserSwitchability(@UserIdInt int userId) {
         if (Flags.getUserSwitchabilityPermission()) {
             if (!hasManageUsersOrPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)) {
                 throw new SecurityException(
@@ -3000,6 +2999,49 @@
     }
 
     @Override
+    public @UserLogoutability int getUserLogoutability(@UserIdInt int userId) {
+        if (!android.multiuser.Flags.logoutUserApi()) {
+            throw new UnsupportedOperationException(
+                    "aconfig flag android.multiuser.logout_user_api not enabled");
+        }
+
+        checkManageUsersPermission("getUserLogoutability");
+
+        if (userId == UserHandle.USER_SYSTEM) {
+            return UserManager.LOGOUTABILITY_STATUS_CANNOT_LOGOUT_SYSTEM_USER;
+        }
+
+        if (userId != getCurrentUserId()) {
+            // TODO(b/393656514): Decide what to do with non-current/background users.
+            // As of now, we are not going to logout a background user. A background user should
+            // simply be stopped instead.
+            return UserManager.LOGOUTABILITY_STATUS_CANNOT_SWITCH;
+        }
+
+        if (getUserSwitchability(userId) != UserManager.SWITCHABILITY_STATUS_OK) {
+            return UserManager.LOGOUTABILITY_STATUS_CANNOT_SWITCH;
+        }
+
+        if (getUserToLogoutCurrentUserTo() == UserHandle.USER_NULL) {
+            return UserManager.LOGOUTABILITY_STATUS_NO_SUITABLE_USER_TO_LOGOUT_TO;
+        }
+
+        return UserManager.LOGOUTABILITY_STATUS_OK;
+    }
+
+    /**
+     * Returns the user to switch to, when logging out current user. If in HSUM and has interactive
+     * system user, then logout would switch to the system user. Otherwise, logout would switch to
+     * the previous foreground user.
+     */
+    private @UserIdInt int getUserToLogoutCurrentUserTo() {
+        if (isHeadlessSystemUserMode() && canSwitchToHeadlessSystemUser()) {
+            return USER_SYSTEM;
+        }
+        return getPreviousFullUserToEnterForegroundUnchecked();
+    }
+
+    @Override
     public boolean isUserSwitcherEnabled(boolean showEvenIfNotActionable,
             @UserIdInt int userId) {
         if (!isUserSwitcherEnabled(userId)) {
@@ -7551,6 +7593,10 @@
                 pw.println("  (and being updated after boot)");
             }
         }
+        if (isHeadlessSystemUserMode) {
+            pw.println("  Can switch to headless system user: " + Resources.getSystem()
+                    .getBoolean(com.android.internal.R.bool.config_canSwitchToHeadlessSystemUser));
+        }
         pw.println("  User version: " + mUserVersion);
         pw.println("  Owner name: " + getOwnerName());
         if (DBG_ALLOCATION) {
@@ -8413,21 +8459,27 @@
     }
 
     /**
-     * Checks if the given user has a profile associated with it.
-     * @param userId The parent user
-     * @return
+     * Formerly: Checks if the given user has a profile associated with it.
+     * Now: Just throws. Do not use it.
+     * @param userId The parent user (passing in a profile user is not supported)
+     * @deprecated
      */
     boolean hasProfile(@UserIdInt int userId) {
-        synchronized (mUsersLock) {
-            UserInfo userInfo = getUserInfoLU(userId);
-            final int userSize = mUsers.size();
-            for (int i = 0; i < userSize; i++) {
-                UserInfo profile = mUsers.valueAt(i).info;
-                if (userId != profile.id && isProfileOf(userInfo, profile)) {
-                    return true;
+        if (!android.content.pm.Flags.removeCrossUserPermissionHack()) {
+            synchronized (mUsersLock) {
+                UserInfo userInfo = getUserInfoLU(userId);
+                final int userSize = mUsers.size();
+                for (int i = 0; i < userSize; i++) {
+                    UserInfo profile = mUsers.valueAt(i).info;
+                    if (userId != profile.id && isSameProfileGroup(userInfo, profile)) {
+                        return true;
+                    }
                 }
+                return false;
             }
-            return false;
+        } else {
+            // TODO(b/332664521): Remove this method entirely. It is no longer used.
+            throw new UnsupportedOperationException();
         }
     }
 
@@ -8499,16 +8551,6 @@
     }
 
     /**
-     * Checks whether to show a notification for sounds (e.g., alarms, timers, etc.) from
-     * background users.
-     */
-    public static boolean shouldShowNotificationForBackgroundUserSounds() {
-        return Flags.addUiForSoundsFromBackgroundUsers() && Resources.getSystem().getBoolean(
-                com.android.internal.R.bool.config_showNotificationForBackgroundUserAlarms)
-                && supportsMultipleUsers();
-    }
-
-    /**
      * Returns instance of {@link com.android.server.pm.UserJourneyLogger}.
      */
     public UserJourneyLogger getUserJourneyLogger() {
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 2bc6d53..a108248 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -309,7 +309,8 @@
      * in settings. So it is handled separately.
      */
     private static final Set<String> DEFAULT_ENABLED_FOR_MANAGED_PROFILES = Sets.newArraySet(
-            UserManager.DISALLOW_BLUETOOTH_SHARING
+            UserManager.DISALLOW_BLUETOOTH_SHARING,
+            UserManager.DISALLOW_DEBUGGING_FEATURES
     );
 
     /**
diff --git a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
index 1b7c7ad..c0441e4 100644
--- a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
@@ -155,11 +155,14 @@
 
     public static NativeLibraryHelper.Handle createNativeLibraryHandle(AndroidPackage pkg)
             throws IOException {
+        boolean pageSizeCompatDisabled = pkg.getPageSizeAppCompatFlags()
+                == ApplicationInfo.PAGE_SIZE_APP_COMPAT_FLAG_MANIFEST_OVERRIDE_DISABLED;
         return NativeLibraryHelper.Handle.create(
                 AndroidPackageUtils.getAllCodePaths(pkg),
                 pkg.isMultiArch(),
                 pkg.isExtractNativeLibrariesRequested(),
-                pkg.isDebuggable()
+                pkg.isDebuggable(),
+                pageSizeCompatDisabled
         );
     }
 
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 b905041..5c5a9c1 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -271,8 +271,9 @@
             @NonNull String permissionName, int deviceId) {
         Objects.requireNonNull(permissionName, "permission can't be null.");
         Objects.requireNonNull(packageName, "package name can't be null.");
+
         return mPermissionManagerServiceImpl.getPermissionRequestState(packageName, permissionName,
-                getPersistentDeviceId(deviceId));
+                deviceId, getPersistentDeviceId(deviceId));
     }
 
     private String getPersistentDeviceId(int deviceId) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index ca70bddc..e51ec04 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -1014,7 +1014,8 @@
     }
 
     @Override
-    public int getPermissionRequestState(String packageName, String permName, String deviceId) {
+    public int getPermissionRequestState(String packageName, String permName, int deviceId,
+            String persistentDeviceId) {
         throw new IllegalStateException("getPermissionRequestState is not supported.");
     }
 
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java
index b607832..3d295f7 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java
@@ -415,7 +415,7 @@
      *  for permission request permission flow.
      */
     int getPermissionRequestState(@NonNull String packageName, @NonNull String permName,
-            @NonNull String deviceId);
+            int deviceId, @NonNull String persistentDeviceId);
 
     /**
      * Gets the permission states for requested package, persistent device and user.
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java
index ba5e97e..f576400 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java
@@ -247,10 +247,12 @@
     }
 
     @Override
-    public int getPermissionRequestState(String packageName, String permName, String deviceId) {
+    public int getPermissionRequestState(String packageName, String permName, int deviceId,
+            String persistentDeviceId) {
         Log.i(LOG_TAG, "checkUidPermissionState(permName = " + permName + ", deviceId = "
-                + deviceId + ", packageName = " + packageName + ")");
-        return mService.getPermissionRequestState(packageName, permName, deviceId);
+                + persistentDeviceId + ", packageName = " + packageName + ")");
+        return mService.getPermissionRequestState(
+                packageName, permName, deviceId, persistentDeviceId);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java
index 008c14d..21a3570 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java
@@ -319,8 +319,10 @@
     }
 
     @Override
-    public int getPermissionRequestState(String packageName, String permName, String deviceId) {
-        return mNewImplementation.getPermissionRequestState(packageName, permName, deviceId);
+    public int getPermissionRequestState(String packageName, String permName, int deviceId,
+            String persistentDeviceId) {
+        return mNewImplementation.getPermissionRequestState(
+                packageName, permName, deviceId, persistentDeviceId);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTracingDecorator.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTracingDecorator.java
index 2a47f51..e51afb0 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTracingDecorator.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTracingDecorator.java
@@ -347,11 +347,13 @@
 
 
     @Override
-    public int getPermissionRequestState(String packageName, String permName, String deviceId) {
+    public int getPermissionRequestState(String packageName, String permName, int deviceId,
+            String persistentDeviceId) {
         Trace.traceBegin(TRACE_TAG,
                 "TaggedTracingPermissionManagerServiceImpl#checkUidPermissionState");
         try {
-            return mService.getPermissionRequestState(packageName, permName, deviceId);
+            return mService.getPermissionRequestState(
+                    packageName, permName, deviceId, persistentDeviceId);
         } finally {
             Trace.traceEnd(TRACE_TAG);
         }
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 090707d..8fae875 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -5979,10 +5979,19 @@
 
             if (uids != null) {
                 ws = new WorkSource();
-                // XXX should WorkSource have a way to set uids as an int[] instead of adding them
-                // one at a time?
-                for (int uid : uids) {
-                    ws.add(uid);
+                if (mFeatureFlags.isWakelockAttributionViaWorkchainEnabled()) {
+                    int callingUid = Binder.getCallingUid();
+                    for (int uid : uids) {
+                        WorkChain workChain = ws.createWorkChain();
+                        workChain.addNode(uid, null);
+                        workChain.addNode(callingUid, null);
+                    }
+                } else {
+                    // XXX should WorkSource have a way to set uids as an int[] instead of
+                    // adding them one at a time?
+                    for (int uid : uids) {
+                        ws.add(uid);
+                    }
                 }
             }
             updateWakeLockWorkSource(lock, ws, null);
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 42b4401..ebc50fd 100644
--- a/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
+++ b/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
@@ -63,6 +63,10 @@
     private final FlagState mMoveWscLoggingToNotifier =
             new FlagState(Flags.FLAG_MOVE_WSC_LOGGING_TO_NOTIFIER, Flags::moveWscLoggingToNotifier);
 
+    private final FlagState mWakelockAttributionViaWorkchain =
+            new FlagState(Flags.FLAG_WAKELOCK_ATTRIBUTION_VIA_WORKCHAIN,
+                    Flags::wakelockAttributionViaWorkchain);
+
     /** Returns whether early-screen-timeout-detector is enabled on not. */
     public boolean isEarlyScreenTimeoutDetectorEnabled() {
         return mEarlyScreenTimeoutDetectorFlagState.isEnabled();
@@ -110,6 +114,13 @@
     }
 
     /**
+     * @return Whether the wakelock attribution via workchain is enabled
+     */
+    public boolean isWakelockAttributionViaWorkchainEnabled() {
+        return mWakelockAttributionViaWorkchain.isEnabled();
+    }
+
+    /**
      * dumps all flagstates
      * @param pw printWriter
      */
@@ -120,6 +131,7 @@
         pw.println(" " + mPerDisplayWakeByTouch);
         pw.println(" " + mFrameworkWakelockInfo);
         pw.println(" " + mMoveWscLoggingToNotifier);
+        pw.println(" " + mWakelockAttributionViaWorkchain);
     }
 
     private static class FlagState {
diff --git a/services/core/java/com/android/server/power/feature/power_flags.aconfig b/services/core/java/com/android/server/power/feature/power_flags.aconfig
index 613daf8..fefe195 100644
--- a/services/core/java/com/android/server/power/feature/power_flags.aconfig
+++ b/services/core/java/com/android/server/power/feature/power_flags.aconfig
@@ -23,6 +23,17 @@
 }
 
 flag {
+    name: "wakelock_attribution_via_workchain"
+    namespace: "power"
+    description: "Enables the attribution of wakelocks via WorkChain for updateWakelockUids"
+    bug: "331304805"
+    is_fixed_read_only: true
+    metadata {
+      purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
     name: "improve_wakelock_latency"
     namespace: "power"
     description: "Feature flag for tracking the optimizations to improve the latency of acquiring and releasing a wakelock."
diff --git a/services/core/java/com/android/server/power/stats/BatteryHistoryDirectory.java b/services/core/java/com/android/server/power/stats/BatteryHistoryDirectory.java
new file mode 100644
index 0000000..adf308a
--- /dev/null
+++ b/services/core/java/com/android/server/power/stats/BatteryHistoryDirectory.java
@@ -0,0 +1,573 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.Trace.TRACE_TAG_SYSTEM_SERVER;
+
+import android.annotation.NonNull;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.util.ArraySet;
+import android.util.AtomicFile;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
+import com.android.internal.os.BatteryStatsHistory;
+import com.android.internal.os.BatteryStatsHistory.BatteryHistoryFragment;
+
+import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
+import org.apache.commons.compress.compressors.gzip.GzipParameters;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.zip.Deflater;
+import java.util.zip.GZIPInputStream;
+
+public class BatteryHistoryDirectory implements BatteryStatsHistory.BatteryHistoryStore {
+    public static final String TAG = "BatteryHistoryDirectory";
+    private static final boolean DEBUG = false;
+
+    private static final String FILE_SUFFIX = ".bh";
+
+    // Size of the magic number written at the start of each history file
+    private static final int FILE_FORMAT_BYTES = 4;
+    private static final byte[] FILE_FORMAT_PARCEL = {0x50, 0x52, 0x43, 0x4c}; // PRCL
+    private static final byte[] FILE_FORMAT_COMPRESSED_PARCEL = {0x47, 0x5a, 0x49, 0x50}; // GZIP
+
+    static class BatteryHistoryFile extends BatteryHistoryFragment {
+        public final AtomicFile atomicFile;
+
+        BatteryHistoryFile(File directory, long monotonicTimeMs) {
+            super(monotonicTimeMs);
+            atomicFile = new AtomicFile(new File(directory, monotonicTimeMs + FILE_SUFFIX));
+        }
+
+        @Override
+        public String toString() {
+            return atomicFile.getBaseFile().toString();
+        }
+    }
+
+    interface Compressor {
+        void compress(OutputStream stream, byte[] data) throws IOException;
+        void uncompress(byte[] data, InputStream stream) throws IOException;
+
+        default void readFully(byte[] data, InputStream stream) throws IOException {
+            int pos = 0;
+            while (pos < data.length) {
+                int count = stream.read(data, pos, data.length - pos);
+                if (count == -1) {
+                    throw new IOException("Invalid battery history file format");
+                }
+                pos += count;
+            }
+        }
+    }
+
+    static final Compressor DEFAULT_COMPRESSOR = new Compressor() {
+        @Override
+        public void compress(OutputStream stream, byte[] data) throws IOException {
+            // With the BEST_SPEED hint, we see ~4x improvement in write latency over
+            // GZIPOutputStream.
+            GzipParameters parameters = new GzipParameters();
+            parameters.setCompressionLevel(Deflater.BEST_SPEED);
+            GzipCompressorOutputStream os = new GzipCompressorOutputStream(stream, parameters);
+            os.write(data);
+            os.finish();
+            os.flush();
+        }
+
+        @Override
+        public void uncompress(byte[] data, InputStream stream) throws IOException {
+            readFully(data, new GZIPInputStream(stream));
+        }
+    };
+
+    private final File mDirectory;
+    private int mMaxHistorySize;
+    private boolean mInitialized;
+    private final List<BatteryHistoryFile> mHistoryFiles = new ArrayList<>();
+    private final ReentrantLock mLock = new ReentrantLock();
+    private final Compressor mCompressor;
+    private boolean mWaitForDirectoryLock = false;
+    private boolean mFileCompressionEnabled;
+
+    public BatteryHistoryDirectory(@NonNull File directory, int maxHistorySize) {
+        this(directory, maxHistorySize, DEFAULT_COMPRESSOR);
+    }
+
+    public BatteryHistoryDirectory(@NonNull File directory, int maxHistorySize,
+            Compressor compressor) {
+        mDirectory = directory;
+        mMaxHistorySize = maxHistorySize;
+        if (mMaxHistorySize == 0) {
+            Slog.w(TAG, "maxHistorySize should not be zero");
+        }
+        mCompressor = compressor;
+    }
+
+    public void setFileCompressionEnabled(boolean enabled) {
+        mFileCompressionEnabled = enabled;
+    }
+
+    void setMaxHistorySize(int maxHistorySize) {
+        mMaxHistorySize = maxHistorySize;
+        trim();
+    }
+
+    /**
+     * Returns the maximum storage size allocated to battery history.
+     */
+    public int getMaxHistorySize() {
+        return mMaxHistorySize;
+    }
+
+    @Override
+    public void lock() {
+        mLock.lock();
+    }
+
+    /**
+     * Turns "tryLock" into "lock" to prevent flaky unit tests.
+     * Should only be called from unit tests.
+     */
+    @VisibleForTesting
+    void makeDirectoryLockUnconditional() {
+        mWaitForDirectoryLock = true;
+    }
+
+    @Override
+    public boolean tryLock() {
+        if (mWaitForDirectoryLock) {
+            mLock.lock();
+            return true;
+        }
+        return mLock.tryLock();
+    }
+
+    @Override
+    public void writeFragment(BatteryHistoryFragment fragment,
+            @NonNull byte[] data, boolean fragmentComplete) {
+        AtomicFile file = ((BatteryHistoryFile) fragment).atomicFile;
+        FileOutputStream fos = null;
+        try {
+            final long startTimeMs = SystemClock.uptimeMillis();
+            fos = file.startWrite();
+            fos.write(FILE_FORMAT_PARCEL);
+            writeInt(fos, data.length);
+            fos.write(data);
+            fos.flush();
+            file.finishWrite(fos);
+            if (DEBUG) {
+                Slog.d(TAG, "writeHistoryFragment file:" + file.getBaseFile().getPath()
+                        + " duration ms:" + (SystemClock.uptimeMillis() - startTimeMs)
+                        + " bytes:" + data.length);
+            }
+            if (fragmentComplete) {
+                if (mFileCompressionEnabled) {
+                    BackgroundThread.getHandler().post(
+                            () -> writeHistoryFragmentCompressed(file, data));
+                }
+                BackgroundThread.getHandler().post(()-> trim());
+            }
+        } catch (IOException e) {
+            Slog.w(TAG, "Error writing battery history fragment", e);
+            file.failWrite(fos);
+        }
+    }
+
+    private void writeHistoryFragmentCompressed(AtomicFile file, byte[] data) {
+        long uncompressedSize = data.length;
+        if (uncompressedSize == 0) {
+            return;
+        }
+
+        Trace.traceBegin(TRACE_TAG_SYSTEM_SERVER, "BatteryStatsHistory.compressHistoryFile");
+        lock();
+        FileOutputStream fos = null;
+        try {
+            long startTimeNs = System.nanoTime();
+            fos = file.startWrite();
+            fos.write(FILE_FORMAT_COMPRESSED_PARCEL);
+            writeInt(fos, data.length);
+
+            mCompressor.compress(fos, data);
+            file.finishWrite(fos);
+
+            if (DEBUG) {
+                long endTimeNs = System.nanoTime();
+                long compressedSize = file.getBaseFile().length();
+                Slog.i(TAG, String.format(Locale.ENGLISH,
+                        "Compressed battery history file %s original size: %d compressed: %d "
+                                + "(%.1f%%) elapsed: %.2f ms",
+                        file.getBaseFile(), uncompressedSize, compressedSize,
+                        (uncompressedSize - compressedSize) * 100.0 / uncompressedSize,
+                        (endTimeNs - startTimeNs) / 1000000.0));
+            }
+        } catch (Exception e) {
+            Slog.w(TAG, "Error compressing battery history chunk " + file, e);
+            file.failWrite(fos);
+        } finally {
+            unlock();
+            Trace.traceEnd(TRACE_TAG_SYSTEM_SERVER);
+        }
+    }
+
+    @Override
+    public byte[] readFragment(BatteryHistoryFragment fragment) {
+        AtomicFile file = ((BatteryHistoryFile) fragment).atomicFile;
+        if (!file.exists()) {
+            deleteFragment(fragment);
+            return null;
+        }
+        final long start = SystemClock.uptimeMillis();
+        Trace.traceBegin(TRACE_TAG_SYSTEM_SERVER, "BatteryStatsHistory.read");
+        try (FileInputStream stream = file.openRead()) {
+            byte[] header = new byte[FILE_FORMAT_BYTES];
+            if (stream.read(header, 0, FILE_FORMAT_BYTES) == -1) {
+                Slog.e(TAG, "Invalid battery history file format " + file.getBaseFile());
+                deleteFragment(fragment);
+                return null;
+            }
+
+            boolean isCompressed;
+            if (Arrays.equals(header, FILE_FORMAT_COMPRESSED_PARCEL)) {
+                isCompressed = true;
+            } else if (Arrays.equals(header, FILE_FORMAT_PARCEL)) {
+                isCompressed = false;
+            } else {
+                Slog.e(TAG, "Invalid battery history file format " + file.getBaseFile());
+                deleteFragment(fragment);
+                return null;
+            }
+
+            int size = readInt(stream);
+            if (size < 0 || size > 10000000) {      // Validity check to avoid a crash
+                Slog.e(TAG, "Invalid battery history file format " + file.getBaseFile());
+                deleteFragment(fragment);
+                return null;
+            }
+
+            byte[] data = new byte[size];
+            if (isCompressed) {
+                mCompressor.uncompress(data, stream);
+            } else {
+                int pos = 0;
+                while (pos < data.length) {
+                    int count = stream.read(data, pos, data.length - pos);
+                    if (count == -1) {
+                        throw new IOException("Invalid battery history file format");
+                    }
+                    pos += count;
+                }
+            }
+            if (DEBUG) {
+                Slog.d(TAG, "readHistoryFragment:" + file.getBaseFile().getPath()
+                        + " duration ms:" + (SystemClock.uptimeMillis() - start));
+            }
+            return data;
+        } catch (Exception e) {
+            Slog.e(TAG, "Error reading file " + file.getBaseFile().getPath(), e);
+            deleteFragment(fragment);
+            return null;
+        } finally {
+            Trace.traceEnd(TRACE_TAG_SYSTEM_SERVER);
+        }
+    }
+
+    private void deleteFragment(BatteryHistoryFragment fragment) {
+        mHistoryFiles.remove(fragment);
+        ((BatteryHistoryFile) fragment).atomicFile.delete();
+    }
+
+    @Override
+    public void unlock() {
+        mLock.unlock();
+    }
+
+    @Override
+    public boolean isLocked() {
+        return mLock.isLocked();
+    }
+
+    private void ensureInitialized() {
+        if (mInitialized) {
+            return;
+        }
+
+        Trace.asyncTraceBegin(TRACE_TAG_SYSTEM_SERVER, "BatteryStatsHistory.load", 0);
+        mDirectory.mkdirs();
+        if (!mDirectory.exists()) {
+            Slog.wtf(TAG, "HistoryDir does not exist:" + mDirectory.getPath());
+        }
+
+        final List<File> toRemove = new ArrayList<>();
+        final Set<BatteryHistoryFile> dedup = new ArraySet<>();
+        mDirectory.listFiles((dir, name) -> {
+            final int b = name.lastIndexOf(FILE_SUFFIX);
+            if (b <= 0) {
+                toRemove.add(new File(dir, name));
+                return false;
+            }
+            try {
+                long monotonicTime = Long.parseLong(name.substring(0, b));
+                dedup.add(new BatteryHistoryFile(mDirectory, monotonicTime));
+            } catch (NumberFormatException e) {
+                toRemove.add(new File(dir, name));
+                return false;
+            }
+            return true;
+        });
+        if (!dedup.isEmpty()) {
+            mHistoryFiles.addAll(dedup);
+            Collections.sort(mHistoryFiles);
+        }
+        mInitialized = true;
+        if (!toRemove.isEmpty()) {
+            // Clear out legacy history files, which did not follow the X-Y.bin naming format.
+            BackgroundThread.getHandler().post(() -> {
+                lock();
+                try {
+                    for (File file : toRemove) {
+                        file.delete();
+                    }
+                } finally {
+                    unlock();
+                    Trace.asyncTraceEnd(TRACE_TAG_SYSTEM_SERVER, "BatteryStatsHistory.load", 0);
+                }
+            });
+        } else {
+            Trace.asyncTraceEnd(TRACE_TAG_SYSTEM_SERVER, "BatteryStatsHistory.load", 0);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public List<BatteryHistoryFragment> getFragments() {
+        ensureInitialized();
+        return (List<BatteryHistoryFragment>)
+                (List<? extends BatteryHistoryFragment>) mHistoryFiles;
+    }
+
+    @VisibleForTesting
+    List<String> getFileNames() {
+        ensureInitialized();
+        lock();
+        try {
+            List<String> names = new ArrayList<>();
+            for (BatteryHistoryFile historyFile : mHistoryFiles) {
+                names.add(historyFile.atomicFile.getBaseFile().getName());
+            }
+            return names;
+        } finally {
+            unlock();
+        }
+    }
+
+    @Override
+    public BatteryHistoryFragment getEarliestFragment() {
+        ensureInitialized();
+        lock();
+        try {
+            if (!mHistoryFiles.isEmpty()) {
+                return mHistoryFiles.get(0);
+            }
+            return null;
+        } finally {
+            unlock();
+        }
+    }
+
+    @Override
+    public BatteryHistoryFragment getLatestFragment() {
+        ensureInitialized();
+        lock();
+        try {
+            if (!mHistoryFiles.isEmpty()) {
+                return mHistoryFiles.get(mHistoryFiles.size() - 1);
+            }
+            return null;
+        } finally {
+            unlock();
+        }
+    }
+
+    @Override
+    public BatteryHistoryFragment createFragment(long monotonicStartTime) {
+        ensureInitialized();
+
+        BatteryHistoryFile file = new BatteryHistoryFile(mDirectory, monotonicStartTime);
+        lock();
+        try {
+            try {
+                file.atomicFile.getBaseFile().createNewFile();
+            } catch (IOException e) {
+                Slog.e(TAG, "Could not create history file: " + file);
+            }
+            mHistoryFiles.add(file);
+        } finally {
+            unlock();
+        }
+
+        return file;
+    }
+
+    @Override
+    public BatteryHistoryFragment getNextFragment(BatteryHistoryFragment current, long startTimeMs,
+            long endTimeMs) {
+        ensureInitialized();
+
+        if (!mLock.isHeldByCurrentThread()) {
+            throw new IllegalStateException("Iterating battery history without a lock");
+        }
+
+        int nextFileIndex = 0;
+        int firstFileIndex = 0;
+        // skip the last file because its data is in history buffer.
+        int lastFileIndex = mHistoryFiles.size() - 2;
+        for (int i = lastFileIndex; i >= 0; i--) {
+            BatteryHistoryFragment fragment = mHistoryFiles.get(i);
+            if (current != null && fragment.monotonicTimeMs == current.monotonicTimeMs) {
+                nextFileIndex = i + 1;
+            }
+            if (fragment.monotonicTimeMs > endTimeMs) {
+                lastFileIndex = i - 1;
+            }
+            if (fragment.monotonicTimeMs <= startTimeMs) {
+                firstFileIndex = i;
+                break;
+            }
+        }
+
+        if (nextFileIndex < firstFileIndex) {
+            nextFileIndex = firstFileIndex;
+        }
+
+        if (nextFileIndex <= lastFileIndex) {
+            return mHistoryFiles.get(nextFileIndex);
+        }
+
+        return null;
+    }
+
+    @Override
+    public boolean hasCompletedFragments() {
+        ensureInitialized();
+
+        lock();
+        try {
+            // Active file is partial and does not count as "competed"
+            return mHistoryFiles.size() > 1;
+        } finally {
+            unlock();
+        }
+    }
+
+    @Override
+    public int getSize() {
+        ensureInitialized();
+
+        lock();
+        try {
+            int ret = 0;
+            for (int i = 0; i < mHistoryFiles.size() - 1; i++) {
+                ret += (int) mHistoryFiles.get(i).atomicFile.getBaseFile().length();
+            }
+            return ret;
+        } finally {
+            unlock();
+        }
+    }
+
+    @Override
+    public void reset() {
+        ensureInitialized();
+
+        lock();
+        try {
+            if (DEBUG) {
+                Slog.i(TAG, "********** CLEARING HISTORY!");
+            }
+            for (BatteryHistoryFile file : mHistoryFiles) {
+                file.atomicFile.delete();
+            }
+            mHistoryFiles.clear();
+        } finally {
+            unlock();
+        }
+    }
+
+    private void trim() {
+        ensureInitialized();
+
+        Trace.traceBegin(TRACE_TAG_SYSTEM_SERVER, "BatteryStatsHistory.trim");
+        try {
+            lock();
+            try {
+                // if there is more history stored than allowed, delete oldest history files.
+                int size = 0;
+                for (int i = 0; i < mHistoryFiles.size(); i++) {
+                    size += (int) mHistoryFiles.get(i).atomicFile.getBaseFile().length();
+                }
+                while (size > mMaxHistorySize) {
+                    BatteryHistoryFile oldest = mHistoryFiles.get(0);
+                    int length = (int) oldest.atomicFile.getBaseFile().length();
+                    oldest.atomicFile.delete();
+                    mHistoryFiles.remove(0);
+                    size -= length;
+                }
+            } finally {
+                unlock();
+            }
+        } finally {
+            Trace.traceEnd(TRACE_TAG_SYSTEM_SERVER);
+        }
+    }
+
+    private static void writeInt(OutputStream stream, int value) throws IOException {
+        stream.write(value >> 24);
+        stream.write(value >> 16);
+        stream.write(value >> 8);
+        stream.write(value >> 0);
+    }
+
+    private static int readInt(InputStream stream) throws IOException {
+        return (readByte(stream) << 24)
+                | (readByte(stream) << 16)
+                | (readByte(stream) << 8)
+                | (readByte(stream) << 0);
+    }
+
+    private static int readByte(InputStream stream) throws IOException {
+        int out = stream.read();
+        if (out == -1) {
+            throw new IOException();
+        }
+        return out;
+    }
+}
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 68768b8..90bc54b 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -195,6 +195,8 @@
     private static final boolean DEBUG_BINDER_STATS = false;
     private static final boolean DEBUG_MEMORY = false;
 
+    private static final String HISTORY_DIR = "battery-history";
+
     // TODO: remove "tcp" from network methods, since we measure total stats.
 
     // Current on-disk Parcel version. Must be updated when the format of the parcelable changes
@@ -1143,6 +1145,8 @@
     private int mBatteryTemperature;
     private int mBatteryVoltageMv;
 
+    @Nullable
+    private final BatteryHistoryDirectory mBatteryHistoryDirectory;
     @NonNull
     private final BatteryStatsHistory mHistory;
 
@@ -11476,7 +11480,10 @@
             @NonNull UserInfoProvider userInfoProvider, @NonNull PowerProfile powerProfile,
             @NonNull CpuScalingPolicies cpuScalingPolicies,
             @NonNull PowerStatsUidResolver powerStatsUidResolver) {
-        this(config, clock, monotonicClock, systemDir, handler, platformIdleStateCallback,
+        this(config, clock, monotonicClock, systemDir,
+                systemDir != null ? new BatteryHistoryDirectory(new File(systemDir, HISTORY_DIR),
+                        config.getMaxHistorySizeBytes()) : null,
+                handler, platformIdleStateCallback,
                 energyStatsRetriever, userInfoProvider, powerProfile, cpuScalingPolicies,
                 powerStatsUidResolver, new FrameworkStatsLogger(),
                 new BatteryStatsHistory.TraceDelegate(), new BatteryStatsHistory.EventLogger());
@@ -11484,6 +11491,7 @@
 
     public BatteryStatsImpl(@NonNull BatteryStatsConfig config, @NonNull Clock clock,
             @NonNull MonotonicClock monotonicClock, @Nullable File systemDir,
+            @Nullable BatteryHistoryDirectory batteryHistoryDirectory,
             @NonNull Handler handler, @Nullable PlatformIdleStateCallback platformIdleStateCallback,
             @Nullable EnergyStatsRetriever energyStatsRetriever,
             @NonNull UserInfoProvider userInfoProvider, @NonNull PowerProfile powerProfile,
@@ -11517,9 +11525,10 @@
             mDailyFile = null;
         }
 
-        mHistory = new BatteryStatsHistory(null /* historyBuffer */, systemDir,
-                mConstants.MAX_HISTORY_SIZE, mConstants.MAX_HISTORY_BUFFER, mStepDetailsCalculator,
-                mClock, mMonotonicClock, traceDelegate, eventLogger);
+        mBatteryHistoryDirectory = batteryHistoryDirectory;
+        mHistory = new BatteryStatsHistory(null /* historyBuffer */, mConstants.MAX_HISTORY_BUFFER,
+                mBatteryHistoryDirectory, mStepDetailsCalculator, mClock, mMonotonicClock,
+                traceDelegate, eventLogger);
 
         mCpuPowerStatsCollector = new CpuPowerStatsCollector(mPowerStatsCollectorInjector);
         mCpuPowerStatsCollector.addConsumer(this::recordPowerStats);
@@ -12060,7 +12069,7 @@
     }
 
     public int getHistoryTotalSize() {
-        return mHistory.getMaxHistorySize();
+        return mBatteryHistoryDirectory.getMaxHistorySize();
     }
 
     public int getHistoryUsedSize() {
@@ -12160,6 +12169,13 @@
         mResetBatteryHistoryOnNewSession = enabled;
     }
 
+    /**
+     * Enables or disables battery history file compression.
+     */
+    public void setBatteryHistoryCompressionEnabled(boolean enabled) {
+        mBatteryHistoryDirectory.setFileCompressionEnabled(enabled);
+    }
+
     @GuardedBy("this")
     public void resetAllStatsAndHistoryLocked(int reason) {
         final long mSecUptime = mClock.uptimeMillis();
@@ -16354,7 +16370,9 @@
          */
         @VisibleForTesting
         public void onChange() {
-            mHistory.setMaxHistorySize(MAX_HISTORY_SIZE);
+            if (mBatteryHistoryDirectory != null) {
+                mBatteryHistoryDirectory.setMaxHistorySize(MAX_HISTORY_SIZE);
+            }
             mHistory.setMaxHistoryBufferSize(MAX_HISTORY_BUFFER);
         }
 
diff --git a/services/core/java/com/android/server/power/stats/OWNERS b/services/core/java/com/android/server/power/stats/OWNERS
index 4068e2b..208b2dd 100644
--- a/services/core/java/com/android/server/power/stats/OWNERS
+++ b/services/core/java/com/android/server/power/stats/OWNERS
@@ -1 +1,4 @@
+# Bug component: 987260
+set noparent
+
 include /BATTERY_STATS_OWNERS
diff --git a/services/core/java/com/android/server/power/stats/WakelockStatsFrameworkEvents.java b/services/core/java/com/android/server/power/stats/WakelockStatsFrameworkEvents.java
index f387fec..a2971f3 100644
--- a/services/core/java/com/android/server/power/stats/WakelockStatsFrameworkEvents.java
+++ b/services/core/java/com/android/server/power/stats/WakelockStatsFrameworkEvents.java
@@ -272,14 +272,10 @@
                 WakeLockStats extraTime =
                         openOverflowStats.computeIfAbsent(key, k -> new WakeLockStats());
 
-                stats.uptimeMillis += openWakeLockUptime + extraTime.uptimeMillis;
-
-                logger.logResult(
-                        key.getUid(),
-                        key.getTag(),
-                        key.getPowerManagerWakeLockLevel(),
-                        stats.uptimeMillis,
-                        stats.completedCount);
+                long totalUpdate = openWakeLockUptime + stats.uptimeMillis + extraTime.uptimeMillis;
+                long totalCount = stats.completedCount + extraTime.completedCount;
+                logger.logResult(key.getUid(), key.getTag(), key.getPowerManagerWakeLockLevel(),
+                        totalUpdate, totalCount);
             }
         }
     }
diff --git a/services/core/java/com/android/server/power/stats/flags.aconfig b/services/core/java/com/android/server/power/stats/flags.aconfig
index c8dbbd29..521ee58 100644
--- a/services/core/java/com/android/server/power/stats/flags.aconfig
+++ b/services/core/java/com/android/server/power/stats/flags.aconfig
@@ -97,3 +97,13 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "extended_battery_history_compression_enabled"
+    namespace: "backstage_power"
+    description: "Compress each battery history chunk on disk"
+    bug: "381937912"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
index 8121701..16658e3 100644
--- a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
@@ -536,8 +536,12 @@
                     user.getIdentifier());
             String inputMethodPackageName = null;
             if (inputMethodComponent != null) {
-                inputMethodPackageName = ComponentName.unflattenFromString(
-                        inputMethodComponent).getPackageName();
+                ComponentName component = ComponentName.unflattenFromString(inputMethodComponent);
+                if (component != null) {
+                    inputMethodPackageName = component.getPackageName();
+                } else {
+                    Log.w(TAG, "Failed to parse inputMethodComponent: " + inputMethodComponent);
+                }
             }
 
             int capability;
diff --git a/services/core/java/com/android/server/slice/SlicePermissionManager.java b/services/core/java/com/android/server/slice/SlicePermissionManager.java
index 343d2e3..d118eae 100644
--- a/services/core/java/com/android/server/slice/SlicePermissionManager.java
+++ b/services/core/java/com/android/server/slice/SlicePermissionManager.java
@@ -29,6 +29,7 @@
 import android.util.Slog;
 import android.util.Xml.Encoding;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.XmlUtils;
 import com.android.server.slice.SliceProviderPermissions.SliceAuthority;
@@ -76,8 +77,11 @@
     private final File mSliceDir;
     private final Context mContext;
     private final Handler mHandler;
+    @GuardedBy("itself")
     private final ArrayMap<PkgUser, SliceProviderPermissions> mCachedProviders = new ArrayMap<>();
+    @GuardedBy("itself")
     private final ArrayMap<PkgUser, SliceClientPermissions> mCachedClients = new ArrayMap<>();
+    @GuardedBy("this")
     private final ArraySet<Persistable> mDirty = new ArraySet<>();
 
     @VisibleForTesting
@@ -354,14 +358,22 @@
     // use addPersistableDirty(); this is just for tests
     @VisibleForTesting
     void addDirtyImmediate(Persistable obj) {
-        mDirty.add(obj);
+        synchronized (this) {
+            mDirty.add(obj);
+        }
     }
 
     private void handleRemove(PkgUser pkgUser) {
         getFile(SliceClientPermissions.getFileName(pkgUser)).delete();
         getFile(SliceProviderPermissions.getFileName(pkgUser)).delete();
-        mDirty.remove(mCachedClients.remove(pkgUser));
-        mDirty.remove(mCachedProviders.remove(pkgUser));
+        synchronized (this) {
+            synchronized (mCachedClients) {
+                mDirty.remove(mCachedClients.remove(pkgUser));
+            }
+            synchronized (mCachedProviders) {
+                mDirty.remove(mCachedProviders.remove(pkgUser));
+            }
+        }
     }
 
     private final class H extends Handler {
@@ -379,7 +391,9 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MSG_ADD_DIRTY:
-                    mDirty.add((Persistable) msg.obj);
+                    synchronized (SlicePermissionManager.this) {
+                        mDirty.add((Persistable) msg.obj);
+                    }
                     break;
                 case MSG_PERSIST:
                     handlePersist();
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index a580504..804cf46 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -79,7 +79,7 @@
 import com.android.internal.util.DumpUtils;
 import com.android.server.SystemService;
 import com.android.server.pm.BackgroundUserSoundNotifier;
-import com.android.server.pm.UserManagerService;
+import com.android.server.pm.UserManagerInternal;
 import com.android.server.vibrator.VibrationSession.CallerInfo;
 import com.android.server.vibrator.VibrationSession.DebugInfo;
 import com.android.server.vibrator.VibrationSession.Status;
@@ -201,7 +201,7 @@
                             VibratorManagerService.this::shouldCancelOnScreenOffLocked,
                             Status.CANCELLED_BY_SCREEN_OFF);
                 }
-            } else if (UserManagerService.shouldShowNotificationForBackgroundUserSounds()
+            } else if (UserManagerInternal.shouldShowNotificationForBackgroundUserSounds()
                     && intent.getAction().equals(BackgroundUserSoundNotifier.ACTION_MUTE_SOUND)) {
                 synchronized (mLock) {
                     maybeClearCurrentAndNextSessionsLocked(
@@ -325,7 +325,7 @@
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SCREEN_OFF);
-        if (UserManagerService.shouldShowNotificationForBackgroundUserSounds()) {
+        if (UserManagerInternal.shouldShowNotificationForBackgroundUserSounds()) {
             filter.addAction(BackgroundUserSoundNotifier.ACTION_MUTE_SOUND);
         }
         context.registerReceiver(mIntentReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 09b1073..d9c79b5 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -781,13 +781,71 @@
         if (mLastWallpaper == null || mFallbackWallpaper == null) return;
         final WallpaperConnection systemConnection = mLastWallpaper.connection;
         final WallpaperConnection fallbackConnection = mFallbackWallpaper.connection;
+        final WallpaperConnection lockConnection;
+        if (mLastLockWallpaper != null) {
+            lockConnection = mLastLockWallpaper.connection;
+        } else {
+            lockConnection = null;
+        }
         if (fallbackConnection == null) {
             Slog.w(TAG, "Fallback wallpaper connection has not been created yet!!");
             return;
         }
-        // TODO(b/384520326) Passing DEFAULT_DISPLAY temporarily before we revamp the
-        //  multi-display supports.
-        if (isWallpaperCompatibleForDisplay(DEFAULT_DISPLAY, systemConnection)) {
+
+        if (enableConnectedDisplaysWallpaper()) {
+            mWallpaperDisplayHelper.forEachDisplayData(displayData -> {
+                int displayId = displayData.mDisplayId;
+                // If the display is already connected to the desired wallpaper(s), either the
+                // same wallpaper for both lock and system, or different wallpapers for each,
+                // any existing fallback wallpaper connection will be removed.
+                if (systemConnection.containsDisplay(displayId)
+                        && (lockConnection == null || lockConnection.containsDisplay(displayId))) {
+                    DisplayConnector fallbackConnector =
+                            mFallbackWallpaper.connection.mDisplayConnector.get(displayId);
+                    if (fallbackConnector != null && fallbackConnector.mEngine != null) {
+                        fallbackConnector.disconnectLocked(mFallbackWallpaper.connection);
+                        mFallbackWallpaper.connection.mDisplayConnector.remove(displayId);
+                    }
+                    return;
+                }
+
+                // Identify if the fallback wallpaper should be use for lock or system or both.
+                int which = 0;
+                if (!systemConnection.containsDisplay(displayId)) {
+                    which |= FLAG_SYSTEM;
+                }
+                if (lockConnection == null || !lockConnection.containsDisplay(displayId)) {
+                    which |= FLAG_LOCK;
+                }
+                if (mFallbackWallpaper.connection.containsDisplay(displayId)) {
+                    // For existing fallback wallpaper connection, update the `which` flags.
+                    DisplayConnector fallbackConnector =
+                            mFallbackWallpaper.connection.mDisplayConnector.get(displayId);
+                    try {
+                        if (fallbackConnector != null && fallbackConnector.mEngine != null
+                                && fallbackConnector.mWhich != which) {
+                            fallbackConnector.mEngine.setWallpaperFlags(which);
+                            mWindowManagerInternal.setWallpaperShowWhenLocked(
+                                    fallbackConnector.mToken,
+                                    /* showWhenLocked= */ (which & FLAG_LOCK) != 0);
+                            fallbackConnector.mWhich = which;
+                        }
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "Failed to update fallback wallpaper engine flags", e);
+                    }
+                } else {
+                    // For new fallback connection, establish the connection with the desired
+                    // `which` flag.
+                    DisplayConnector fallbackConnector =
+                            mFallbackWallpaper.connection.getDisplayConnectorOrCreate(displayId);
+                    if (fallbackConnector != null && fallbackConnector.mEngine != null) {
+                        fallbackConnector.mWhich = which;
+                        fallbackConnector.connectLocked(mFallbackWallpaper.connection,
+                                mFallbackWallpaper);
+                    }
+                }
+            });
+        } else if (isWallpaperCompatibleForDisplay(DEFAULT_DISPLAY, systemConnection)) {
             if (fallbackConnection.mDisplayConnector.size() != 0) {
                 fallbackConnection.forEachDisplayConnector(connector -> {
                     if (connector.mEngine != null) {
@@ -820,8 +878,13 @@
         boolean mDimensionsChanged;
         boolean mPaddingChanged;
 
-        DisplayConnector(int displayId) {
+        // This field is added for the fallback wallpaper, which may have a different which flag for
+        // a different display.
+        int mWhich;
+
+        DisplayConnector(int displayId, int which) {
             mDisplayId = displayId;
+            mWhich = which;
         }
 
         void ensureStatusHandled() {
@@ -850,13 +913,17 @@
                 Slog.w(TAG, "WallpaperService is not connected yet");
                 return;
             }
+            int which = wallpaper.mWhich;
+            if (enableConnectedDisplaysWallpaper()) {
+                which = mWhich;
+            }
             TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG);
             t.traceBegin("WPMS.connectLocked-" + wallpaper.getComponent());
             if (DEBUG) Slog.v(TAG, "Adding window token: " + mToken);
             mWindowManagerInternal.addWindowToken(mToken, TYPE_WALLPAPER, mDisplayId,
                     null /* options */);
             mWindowManagerInternal.setWallpaperShowWhenLocked(
-                    mToken, (wallpaper.mWhich & FLAG_LOCK) != 0);
+                    mToken, (which & FLAG_LOCK) != 0);
             if (multiCrop() && mImageWallpaper.equals(wallpaper.getComponent())) {
                 mWindowManagerInternal.setWallpaperCropHints(mToken,
                         mWallpaperCropper.getRelativeCropHints(wallpaper));
@@ -868,16 +935,15 @@
             try {
                 if (liveWallpaperContentHandling()) {
                     connection.mService.attach(connection, mToken, TYPE_WALLPAPER, false,
-                            wpdData.mWidth, wpdData.mHeight,
-                            wpdData.mPadding, mDisplayId, wallpaper.mWhich, connection.mInfo,
-                            wallpaper.getDescription());
+                            wpdData.mWidth, wpdData.mHeight, wpdData.mPadding, mDisplayId, which,
+                            connection.mInfo, wallpaper.getDescription());
                 } else {
                     WallpaperDescription desc = new WallpaperDescription.Builder().setComponent(
                             (connection.mInfo != null) ? connection.mInfo.getComponent()
                                     : null).build();
                     connection.mService.attach(connection, mToken, TYPE_WALLPAPER, false,
-                            wpdData.mWidth, wpdData.mHeight,
-                            wpdData.mPadding, mDisplayId, wallpaper.mWhich, connection.mInfo, desc);
+                            wpdData.mWidth, wpdData.mHeight, wpdData.mPadding, mDisplayId, which,
+                            connection.mInfo, desc);
                 }
             } catch (RemoteException e) {
                 Slog.w(TAG, "Failed attaching wallpaper on display", e);
@@ -980,7 +1046,8 @@
                     final int displayId = display.getDisplayId();
                     final DisplayConnector connector = mDisplayConnector.get(displayId);
                     if (connector == null) {
-                        mDisplayConnector.append(displayId, new DisplayConnector(displayId));
+                        mDisplayConnector.append(displayId,
+                                new DisplayConnector(displayId, mWallpaper.mWhich));
                     }
                 }
             }
@@ -1006,7 +1073,7 @@
             DisplayConnector connector = mDisplayConnector.get(displayId);
             if (connector == null) {
                 if (mWallpaperDisplayHelper.isUsableDisplay(displayId, mClientUid)) {
-                    connector = new DisplayConnector(displayId);
+                    connector = new DisplayConnector(displayId, mWallpaper.mWhich);
                     mDisplayConnector.append(displayId, connector);
                 }
             }
@@ -1364,6 +1431,17 @@
                                 Slog.v(TAG, "static system+lock to system failure");
                             }
                             WallpaperData currentSystem = mWallpaperMap.get(mNewWallpaper.userId);
+                            // In the constructor, we copied the system+lock wallpaper to
+                            // mOriginalSystem. However, the copied WallpaperData#connection is a
+                            // reference, not a deep copy. This means
+                            // currentSystem.connection.mWallpaper points to mOriginalSystem, so
+                            // changes to currentSystem.mWhich alone won't update the corresponding
+                            // flag in currentSystem.connection.mWallpaper.mWhich. Let's point
+                            // currentSystem.connection.mWallpaper back to currentSystem.
+                            if (enableConnectedDisplaysWallpaper()
+                                    && currentSystem.connection != null) {
+                                currentSystem.connection.mWallpaper = currentSystem;
+                            }
                             currentSystem.mWhich = FLAG_SYSTEM | FLAG_LOCK;
                             updateEngineFlags(currentSystem);
                             mLockWallpaperMap.remove(mNewWallpaper.userId);
@@ -1385,6 +1463,11 @@
                     }
                     WallpaperData currentSystem = mWallpaperMap.get(mNewWallpaper.userId);
                     if (currentSystem.wallpaperId == mOriginalSystem.wallpaperId) {
+                        // Fixing the reference, see above for more details.
+                        if (enableConnectedDisplaysWallpaper()
+                                && currentSystem.connection != null) {
+                            currentSystem.connection.mWallpaper = currentSystem;
+                        }
                         currentSystem.mWhich = FLAG_SYSTEM;
                         updateEngineFlags(currentSystem);
                     }
@@ -3814,6 +3897,7 @@
         wallpaper.connection.forEachDisplayConnector(
                 connector -> {
                     try {
+                        connector.mWhich = wallpaper.mWhich;
                         if (connector.mEngine != null) {
                             connector.mEngine.setWallpaperFlags(wallpaper.mWhich);
                             mWindowManagerInternal.setWallpaperShowWhenLocked(
@@ -3949,8 +4033,8 @@
             if (mLastWallpaper == null) {
                 return;
             }
+            int useFallbackWallpaperWhich = 0;
             if (enableConnectedDisplaysWallpaper()) {
-                int useFallbackWallpaperWhich = 0;
                 List<WallpaperData> wallpapers = new ArrayList<>();
                 wallpapers.add(mLastWallpaper);
                 // If the system and the lock wallpapers are not the same, we should also
@@ -3981,7 +4065,6 @@
                         || mFallbackWallpaper.connection == null) {
                     return;
                 }
-                mFallbackWallpaper.mWhich = useFallbackWallpaperWhich;
             } else {
                 if (isWallpaperCompatibleForDisplay(displayId, mLastWallpaper.connection)) {
                     final DisplayConnector connector =
@@ -3999,6 +4082,7 @@
                 final DisplayConnector connector = mFallbackWallpaper
                         .connection.getDisplayConnectorOrCreate(displayId);
                 if (connector == null) return;
+                connector.mWhich = useFallbackWallpaperWhich;
                 connector.connectLocked(mFallbackWallpaper.connection, mFallbackWallpaper);
             } else {
                 Slog.w(TAG, "No wallpaper can be added to the new display");
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 89b46bc..f38394e 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -46,7 +46,6 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.app.WindowConfiguration.activityTypeToString;
-import static android.app.WindowConfiguration.isFloating;
 import static android.app.admin.DevicePolicyResources.Drawables.Source.PROFILE_SWITCH_ANIMATION;
 import static android.app.admin.DevicePolicyResources.Drawables.Style.OUTLINE;
 import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON;
@@ -178,6 +177,7 @@
 import static com.android.server.wm.ActivityRecordProto.PROVIDES_MAX_BOUNDS;
 import static com.android.server.wm.ActivityRecordProto.REPORTED_DRAWN;
 import static com.android.server.wm.ActivityRecordProto.REPORTED_VISIBLE;
+import static com.android.server.wm.ActivityRecordProto.REQUEST_OPEN_IN_BROWSER_EDUCATION_TIMESTAMP;
 import static com.android.server.wm.ActivityRecordProto.SHOULD_ENABLE_USER_ASPECT_RATIO_SETTINGS;
 import static com.android.server.wm.ActivityRecordProto.SHOULD_FORCE_ROTATE_FOR_CAMERA_COMPAT;
 import static com.android.server.wm.ActivityRecordProto.SHOULD_IGNORE_ORIENTATION_REQUEST_LOOP;
@@ -5604,7 +5604,6 @@
         }
 
         mAtmService.mBackNavigationController.onAppVisibilityChanged(this, visible);
-        onChildVisibilityRequested(visible);
 
         final DisplayContent displayContent = getDisplayContent();
         displayContent.mOpeningApps.remove(this);
@@ -8377,7 +8376,6 @@
         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
         getResolvedOverrideConfiguration().seq = mConfigurationSeq;
 
-        // TODO(b/392069771): Move to AppCompatSandboxingPolicy.
         // Sandbox max bounds by setting it to the activity bounds, if activity is letterboxed, or
         // has or will have mAppCompatDisplayInsets for size compat. Also forces an activity to be
         // sandboxed or not depending upon the configuration settings.
@@ -8406,20 +8404,6 @@
             resolvedConfig.windowConfiguration.setMaxBounds(mTmpBounds);
         }
 
-        // Sandbox activity bounds in freeform to app bounds to force app to display within the
-        // container. This prevents UI cropping when activities can draw below insets which are
-        // normally excluded from appBounds before targetSDK < 35
-        // (see ConfigurationContainer#applySizeOverrideIfNeeded).
-        if (isFloating(parentWindowingMode)) {
-            Rect appBounds = resolvedConfig.windowConfiguration.getAppBounds();
-            if (appBounds == null || appBounds.isEmpty()) {
-                // When there is no override bounds, the activity will inherit the bounds from
-                // parent.
-                appBounds = mResolveConfigHint.mParentAppBoundsOverride;
-            }
-            resolvedConfig.windowConfiguration.setBounds(appBounds);
-        }
-
         applySizeOverrideIfNeeded(
                 mDisplayContent,
                 info.applicationInfo,
@@ -9961,6 +9945,8 @@
                 aspectRatioOverrides.shouldEnableUserAspectRatioSettings());
         proto.write(IS_USER_FULLSCREEN_OVERRIDE_ENABLED,
                 aspectRatioOverrides.isUserFullscreenOverrideEnabled());
+        proto.write(REQUEST_OPEN_IN_BROWSER_EDUCATION_TIMESTAMP,
+                mRequestOpenInBrowserEducationTimestamp);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 6f76618..247264f 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -3035,6 +3035,12 @@
             }
         }
 
+        if (com.android.window.flags.Flags.fixLayoutExistingTask()) {
+            // Layout the task to ensure the Task is in correct bounds.
+            mSupervisor.getLaunchParamsController().layoutTask(intentTask,
+                    mStartActivity.info.windowLayout, mStartActivity, mSourceRecord, mOptions);
+        }
+
         // If the target task is not in the front, then we need to bring it to the front.
         final boolean differentTopTask;
         if (mTargetRootTask.getDisplayArea() == mPreferredTaskDisplayArea) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 906befc..6a5adca 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -145,6 +145,7 @@
 import android.view.Display;
 import android.webkit.URLUtil;
 import android.window.ActivityWindowInfo;
+import android.window.DesktopModeFlags;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
@@ -278,7 +279,7 @@
     /** Helper for {@link Task#fillTaskInfo}. */
     final TaskInfoHelper mTaskInfoHelper = new TaskInfoHelper();
 
-    final OpaqueActivityHelper mOpaqueActivityHelper = new OpaqueActivityHelper();
+    final OpaqueContainerHelper mOpaqueContainerHelper = new OpaqueContainerHelper();
 
     private final ActivityTaskSupervisorHandler mHandler;
     final Looper mLooper;
@@ -2913,41 +2914,90 @@
         }
     }
 
-    /** The helper to get the top opaque activity of a container. */
-    static class OpaqueActivityHelper implements Predicate<ActivityRecord> {
+    /** The helper to calculate whether a container is opaque. */
+    static class OpaqueContainerHelper implements Predicate<ActivityRecord> {
         private ActivityRecord mStarting;
-        private boolean mIncludeInvisibleAndFinishing;
+        private boolean mIgnoringInvisibleActivity;
         private boolean mIgnoringKeyguard;
 
-        ActivityRecord getOpaqueActivity(@NonNull WindowContainer<?> container) {
-            mIncludeInvisibleAndFinishing = true;
-            mIgnoringKeyguard = true;
-            return container.getActivity(this,
-                    true /* traverseTopToBottom */, null /* boundary */);
+        /** Whether the container is opaque. */
+        boolean isOpaque(@NonNull WindowContainer<?> container) {
+            return isOpaque(container, null /* starting */, true /* ignoringKeyguard */,
+                    false /* ignoringInvisibleActivity */);
         }
 
-        ActivityRecord getVisibleOpaqueActivity(
+        /**
+         * Whether the container is opaque, but only including visible activities in its
+         * calculation.
+         */
+        boolean isOpaque(
                 @NonNull WindowContainer<?> container, @Nullable ActivityRecord starting,
-                boolean ignoringKeyguard) {
+                boolean ignoringKeyguard,  boolean ignoringInvisibleActivity) {
             mStarting = starting;
-            mIncludeInvisibleAndFinishing = false;
+            mIgnoringInvisibleActivity = ignoringInvisibleActivity;
             mIgnoringKeyguard = ignoringKeyguard;
-            final ActivityRecord opaque = container.getActivity(this,
-                    true /* traverseTopToBottom */, null /* boundary */);
+
+            final boolean isOpaque;
+            if (!Flags.enableMultipleDesktopsBackend()) {
+                isOpaque = container.getActivity(this,
+                        true /* traverseTopToBottom */, null /* boundary */) != null;
+            } else {
+                isOpaque = isOpaqueInner(container);
+            }
             mStarting = null;
-            return opaque;
+            return isOpaque;
+        }
+
+        private boolean isOpaqueInner(@NonNull WindowContainer<?> container) {
+            // If it's a leaf task fragment, then opacity is calculated based on its activities.
+            if (container.asTaskFragment() != null
+                    && ((TaskFragment) container).isLeafTaskFragment()) {
+                return container.getActivity(this,
+                        true /* traverseTopToBottom */, null /* boundary */) != null;
+            }
+            // When not a leaf, it's considered opaque if any of its opaque children fill this
+            // container, unless the children are adjacent fragments, in which case as long as they
+            // are all opaque then |container| is also considered opaque, even if the adjacent
+            // task fragment aren't filling.
+            for (int i = 0; i < container.getChildCount(); i++) {
+                final WindowContainer<?> child = container.getChildAt(i);
+                if (child.fillsParent() && isOpaque(child)) {
+                    return true;
+                }
+
+                if (child.asTaskFragment() != null
+                        && child.asTaskFragment().hasAdjacentTaskFragment()) {
+                    final boolean isAnyTranslucent;
+                    if (Flags.allowMultipleAdjacentTaskFragments()) {
+                        final TaskFragment.AdjacentSet set =
+                                child.asTaskFragment().getAdjacentTaskFragments();
+                        isAnyTranslucent = set.forAllTaskFragments(
+                                tf -> !isOpaque(tf), null);
+                    } else {
+                        final TaskFragment adjacent = child.asTaskFragment()
+                                .getAdjacentTaskFragment();
+                        isAnyTranslucent = !isOpaque(child) || !isOpaque(adjacent);
+                    }
+                    if (!isAnyTranslucent) {
+                        // This task fragment and all its adjacent task fragments are opaque,
+                        // consider it opaque even if it doesn't fill its parent.
+                        return true;
+                    }
+                }
+            }
+            return false;
         }
 
         @Override
         public boolean test(ActivityRecord r) {
-            if (!mIncludeInvisibleAndFinishing && r != mStarting
+            if (mIgnoringInvisibleActivity && r != mStarting
                     && ((mIgnoringKeyguard && !r.visibleIgnoringKeyguard)
                     || (!mIgnoringKeyguard && !r.isVisible()))) {
                 // Ignore invisible activities that are not the currently starting activity
                 // (about to be visible).
                 return false;
             }
-            return r.occludesParent(mIncludeInvisibleAndFinishing /* includingFinishing */);
+            return r.occludesParent(!mIgnoringInvisibleActivity /* includingFinishing */);
         }
     }
 
@@ -2974,7 +3024,8 @@
 
         @Override
         public void accept(ActivityRecord r) {
-            if (Flags.enableDesktopWindowingAppToWeb() && mInfo.capturedLink == null) {
+            if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_APP_TO_WEB.isTrue()
+                    && mInfo.capturedLink == null) {
                 setCapturedLink(r);
             }
             if (r.mLaunchCookie != null) {
diff --git a/services/core/java/com/android/server/wm/AppCompatConfiguration.java b/services/core/java/com/android/server/wm/AppCompatConfiguration.java
index 9a15c4a..0d8950b 100644
--- a/services/core/java/com/android/server/wm/AppCompatConfiguration.java
+++ b/services/core/java/com/android/server/wm/AppCompatConfiguration.java
@@ -311,7 +311,7 @@
 
     // Whether should ignore app requested orientation in response to an app
     // calling Activity#setRequestedOrientation. See
-    // LetterboxUiController#shouldIgnoreRequestedOrientation for details.
+    // AppCompatOrientationPolicy#shouldIgnoreRequestedOrientation for details.
     private final boolean mIsPolicyForIgnoringRequestedOrientationEnabled;
 
     // Flags dynamically updated with {@link android.provider.DeviceConfig}.
@@ -1259,7 +1259,7 @@
     /**
      * Whether should ignore app requested orientation in response to an app calling
      * {@link android.app.Activity#setRequestedOrientation}. See {@link
-     * LetterboxUiController#shouldIgnoreRequestedOrientation} for details.
+     * AppCompatOrientationPolicy#shouldIgnoreRequestedOrientation} for details.
      */
     boolean isPolicyForIgnoringRequestedOrientationEnabled() {
         return mIsPolicyForIgnoringRequestedOrientationEnabled;
diff --git a/services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java b/services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java
index a7c52bd..b4778667 100644
--- a/services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java
@@ -32,6 +32,7 @@
 import android.graphics.Rect;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
 
 import java.io.PrintWriter;
 import java.util.function.Supplier;
@@ -97,8 +98,11 @@
     private void handleHorizontalDoubleTap(int x) {
         final AppCompatReachabilityOverrides reachabilityOverrides =
                 mActivityRecord.mAppCompatController.getReachabilityOverrides();
-        if (!reachabilityOverrides.isHorizontalReachabilityEnabled()
-                || mActivityRecord.isInTransition()) {
+        // We don't return early when the Shell letterbox implementation is enabled because
+        // double tap is always sent via transitions.
+        final boolean isInTransition = !Flags.appCompatRefactoring()
+                && mActivityRecord.isInTransition();
+        if (!reachabilityOverrides.isHorizontalReachabilityEnabled() || isInTransition) {
             return;
         }
         final Rect letterboxInnerFrame = getLetterboxInnerFrame();
@@ -143,8 +147,11 @@
     private void handleVerticalDoubleTap(int y) {
         final AppCompatReachabilityOverrides reachabilityOverrides =
                 mActivityRecord.mAppCompatController.getReachabilityOverrides();
-        if (!reachabilityOverrides.isVerticalReachabilityEnabled()
-                || mActivityRecord.isInTransition()) {
+        // We don't return early when the Shell letterbox implementation is enabled because
+        // double tap is always sent via transitions.
+        final boolean isInTransition = !Flags.appCompatRefactoring()
+                && mActivityRecord.isInTransition();
+        if (!reachabilityOverrides.isVerticalReachabilityEnabled() || isInTransition) {
             return;
         }
         final Rect letterboxInnerFrame = getLetterboxInnerFrame();
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 0a2f685..d5fe056 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -80,7 +80,6 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Pair;
-import android.view.Display;
 import android.view.RemoteAnimationAdapter;
 import android.view.RemoteAnimationDefinition;
 import android.view.WindowManager;
@@ -252,7 +251,6 @@
         // Check if there is any override
         if (!overrideWithTaskFragmentRemoteAnimation(transit, activityTypes)) {
             // Unfreeze the windows that were previously frozen for TaskFragment animation.
-            unfreezeEmbeddedChangingWindows();
             overrideWithRemoteAnimationIfSet(animLpActivity, transit, activityTypes);
         }
 
@@ -545,16 +543,6 @@
                 : null;
     }
 
-    private void unfreezeEmbeddedChangingWindows() {
-        final ArraySet<WindowContainer> changingContainers = mDisplayContent.mChangingContainers;
-        for (int i = changingContainers.size() - 1; i >= 0; i--) {
-            final WindowContainer wc = changingContainers.valueAt(i);
-            if (wc.isEmbedded()) {
-                wc.mSurfaceFreezer.unfreeze(wc.getSyncTransaction());
-            }
-        }
-    }
-
     private boolean transitionMayContainNonAppWindows(@TransitionOldType int transit) {
         // We don't want to have the client to animate any non-app windows.
         // Having {@code transit} of those types doesn't mean it will contain non-app windows, but
diff --git a/services/core/java/com/android/server/wm/DesktopModeHelper.java b/services/core/java/com/android/server/wm/DesktopModeHelper.java
index e3906f9..0eea30a 100644
--- a/services/core/java/com/android/server/wm/DesktopModeHelper.java
+++ b/services/core/java/com/android/server/wm/DesktopModeHelper.java
@@ -52,8 +52,7 @@
      * Return {@code true} if the current device supports desktop mode.
      */
     // TODO(b/337819319): use a companion object instead.
-    @VisibleForTesting
-    static boolean isDesktopModeSupported(@NonNull Context context) {
+    private static boolean isDesktopModeSupported(@NonNull Context context) {
         return context.getResources().getBoolean(R.bool.config_isDesktopModeSupported);
     }
 
diff --git a/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java b/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
index 548addb..ac98792 100644
--- a/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/DesktopModeLaunchParamsModifier.java
@@ -74,6 +74,12 @@
             appendLog("task null, skipping");
             return RESULT_SKIP;
         }
+        if (com.android.window.flags.Flags.fixLayoutExistingTask()
+                && task.getOrganizedTask() != null) {
+            appendLog("task is organized, skipping");
+            return RESULT_SKIP;
+        }
+
         if (!task.isActivityTypeStandardOrUndefined()) {
             appendLog("not standard or undefined activity type, skipping");
             return RESULT_SKIP;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a0d2d26..ecf2787 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -5165,7 +5165,7 @@
     /**
      * Creates a LayerCaptureArgs object to represent the entire DisplayContent
      */
-    LayerCaptureArgs getLayerCaptureArgs(Set<Integer> windowTypesToExclude) {
+    LayerCaptureArgs getLayerCaptureArgs(@Nullable ToBooleanFunction<WindowState> predicate) {
         if (!mWmService.mPolicy.isScreenOn()) {
             if (DEBUG_SCREENSHOT) {
                 Slog.i(TAG_WM, "Attempted to take screenshot while display was off.");
@@ -5178,17 +5178,16 @@
         LayerCaptureArgs.Builder builder = new LayerCaptureArgs.Builder(getSurfaceControl())
                 .setSourceCrop(mTmpRect);
 
-        if (!windowTypesToExclude.isEmpty()) {
-            ArrayList<SurfaceControl> surfaceControls = new ArrayList<>();
+        if (predicate != null) {
+            ArrayList<SurfaceControl> excludeLayers = new ArrayList<>();
             forAllWindows(
                     window -> {
-                        if (windowTypesToExclude.contains(window.getWindowType())) {
-                            surfaceControls.add(window.mSurfaceControl);
+                        if (!predicate.apply(window)) {
+                            excludeLayers.add(window.mSurfaceControl);
                         }
-                    }, true
-            );
-            if (!surfaceControls.isEmpty()) {
-                builder.setExcludeLayers(surfaceControls.toArray(new SurfaceControl[0]));
+                    }, true);
+            if (!excludeLayers.isEmpty()) {
+                builder.setExcludeLayers(excludeLayers.toArray(new SurfaceControl[0]));
             }
         }
         return builder.build();
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 5329e3b..5090ed0 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -74,7 +74,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static com.android.window.flags.Flags.enableFullyImmersiveInDesktop;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -120,6 +119,7 @@
 import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityManager;
 import android.window.ClientWindowFrames;
+import android.window.DesktopModeFlags;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
@@ -2525,7 +2525,7 @@
                 && !topFreeformTask.getBounds().equals(mDisplayContent.getBounds());
 
         getInsetsPolicy().updateSystemBars(win, adjacentTasksVisible,
-                enableFullyImmersiveInDesktop()
+                DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()
                         ? inNonFullscreenFreeformMode : freeformRootTaskVisible);
 
         final boolean topAppHidesStatusBar = topAppHidesSystemBar(Type.statusBars());
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 59ca79c..cf16204 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -182,12 +182,18 @@
             if (control != null && control.getLeash() != null) {
                 ImeTracker.Token statsToken = getAndClearStatsToken();
                 if (statsToken == null) {
-                    ProtoLog.d(WM_DEBUG_IME, "IME getControl without statsToken");
-                } else {
-                    ImeTracker.forLogging().onProgress(statsToken,
-                            ImeTracker.PHASE_WM_GET_CONTROL_WITH_LEASH);
-                    control.setImeStatsToken(statsToken);
+                    ProtoLog.w(WM_DEBUG_IME,
+                            "IME getControl without statsToken (check previous request!). "
+                                    + "Start new request");
+                    // TODO(b/353463205) remove this later after fixing the race of two requests
+                    //  that cancel each other (cf. b/383466954#comment19).
+                    statsToken = ImeTracker.forLogging().onStart(ImeTracker.TYPE_SHOW,
+                            ImeTracker.ORIGIN_SERVER, SoftInputShowHideReason.CONTROLS_CHANGED,
+                            false /* fromUser */);
                 }
+                ImeTracker.forLogging().onProgress(statsToken,
+                        ImeTracker.PHASE_WM_GET_CONTROL_WITH_LEASH);
+                control.setImeStatsToken(statsToken);
             }
         }
         return control;
diff --git a/services/core/java/com/android/server/wm/LaunchParamsController.java b/services/core/java/com/android/server/wm/LaunchParamsController.java
index 4f5c0c8..fa65bda 100644
--- a/services/core/java/com/android/server/wm/LaunchParamsController.java
+++ b/services/core/java/com/android/server/wm/LaunchParamsController.java
@@ -124,31 +124,19 @@
         }
     }
 
-    /**
-     * A convenience method for laying out a task.
-     * @return {@code true} if bounds were set on the task. {@code false} otherwise.
-     */
-    boolean layoutTask(Task task, WindowLayout layout) {
-        return layoutTask(task, layout, null /*activity*/, null /*source*/, null /*options*/);
-    }
-
+    /** @return {@code true} if bounds were set on the task. {@code false} otherwise. */
     boolean layoutTask(Task task, WindowLayout layout, ActivityRecord activity,
             ActivityRecord source, ActivityOptions options) {
         calculate(task, layout, activity, source, options, null /* request */, PHASE_BOUNDS,
                 mTmpParams);
 
         // No changes, return.
-        if (mTmpParams.isEmpty()) {
+        if (mTmpParams.isEmpty() || mTmpParams.mBounds.isEmpty()) {
             return false;
         }
 
         mService.deferWindowLayout();
-
         try {
-            if (mTmpParams.mBounds.isEmpty()) {
-                return false;
-            }
-
             if (task.getRootTask().inMultiWindowMode()) {
                 task.setBounds(mTmpParams.mBounds);
                 return true;
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index cf464c7..1fe6ad6 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1948,7 +1948,7 @@
         final IntArray rootTaskIdsToRestore = mUserVisibleRootTasks.get(userId);
         boolean homeInFront = false;
         if (Flags.enableTopVisibleRootTaskPerUserTracking()) {
-            if (rootTaskIdsToRestore == null) {
+            if (rootTaskIdsToRestore == null || rootTaskIdsToRestore.size() == 0) {
                 // If there are no root tasks saved, try restore id 0 which should create and launch
                 // the home task.
                 handleRootTaskLaunchOnUserSwitch(/* restoreRootTaskId */INVALID_TASK_ID);
@@ -1958,11 +1958,8 @@
                     handleRootTaskLaunchOnUserSwitch(rootTaskIdsToRestore.get(i));
                 }
                 // Check if the top task is type home
-                if (rootTaskIdsToRestore.size() > 0) {
-                    final int topRootTaskId = rootTaskIdsToRestore.get(
-                            rootTaskIdsToRestore.size() - 1);
-                    homeInFront = isHomeTask(topRootTaskId);
-                }
+                final int topRootTaskId = rootTaskIdsToRestore.get(rootTaskIdsToRestore.size() - 1);
+                homeInFront = isHomeTask(topRootTaskId);
             }
         } else {
             handleRootTaskLaunchOnUserSwitch(restoreRootTaskId);
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index d7b6d96..3dfff39 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -60,8 +60,6 @@
     @VisibleForTesting
     SurfaceControl mLeash;
     @VisibleForTesting
-    SurfaceFreezer.Snapshot mSnapshot;
-    @VisibleForTesting
     final Animatable mAnimatable;
     @VisibleForTesting
     final OnAnimationFinishedCallback mInnerAnimationFinishedCallback;
@@ -165,7 +163,7 @@
             @AnimationType int type,
             @Nullable OnAnimationFinishedCallback animationFinishedCallback,
             @Nullable Runnable animationCancelledCallback,
-            @Nullable AnimationAdapter snapshotAnim, @Nullable SurfaceFreezer freezer) {
+            @Nullable AnimationAdapter snapshotAnim) {
         cancelAnimation(t, true /* restarting */, true /* forwardCancel */);
         mAnimation = anim;
         mAnimationType = type;
@@ -177,7 +175,6 @@
             cancelAnimation();
             return;
         }
-        mLeash = freezer != null ? freezer.takeLeashForAnimation() : null;
         if (mLeash == null) {
             mLeash = createAnimationLeash(mAnimatable, surface, t, type,
                     mAnimatable.getSurfaceWidth(), mAnimatable.getSurfaceHeight(), 0 /* x */,
@@ -192,21 +189,13 @@
             mAnimation.dump(pw, "");
             ProtoLog.d(WM_DEBUG_ANIM, "Animation start for %s, anim=%s", mAnimatable, sw);
         }
-        if (snapshotAnim != null) {
-            mSnapshot = freezer.takeSnapshotForAnimation();
-            if (mSnapshot == null) {
-                Slog.e(TAG, "No snapshot target to start animation on for " + mAnimatable);
-                return;
-            }
-            mSnapshot.startAnimation(t, snapshotAnim, type);
-        }
         setAnimatorPendingState(t);
     }
 
     void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
             @AnimationType int type) {
         startAnimation(t, anim, hidden, type, null /* animationFinishedCallback */,
-                null /* animationCancelledCallback */, null /* snapshotAnim */, null /* freezer */);
+                null /* animationCancelledCallback */, null /* snapshotAnim */);
     }
 
     /** Indicates that there are surface operations in the pending transaction. */
@@ -317,7 +306,6 @@
         final OnAnimationFinishedCallback animationFinishedCallback =
                 mSurfaceAnimationFinishedCallback;
         final Runnable animationCancelledCallback = mAnimationCancelledCallback;
-        final SurfaceFreezer.Snapshot snapshot = mSnapshot;
         reset(t, false);
         if (animation != null) {
             if (forwardCancel) {
@@ -337,9 +325,6 @@
         }
 
         if (forwardCancel) {
-            if (snapshot != null) {
-                snapshot.cancelAnimation(t, false /* restarting */);
-            }
             if (leash != null) {
                 t.remove(leash);
                 mService.scheduleAnimationLocked();
@@ -352,12 +337,6 @@
         mAnimation = null;
         mSurfaceAnimationFinishedCallback = null;
         mAnimationType = ANIMATION_TYPE_NONE;
-        final SurfaceFreezer.Snapshot snapshot = mSnapshot;
-        mSnapshot = null;
-        if (snapshot != null) {
-            // Reset the mSnapshot reference before calling the callback to prevent circular reset.
-            snapshot.cancelAnimation(t, !destroyLeash);
-        }
         if (mLeash == null) {
             return;
         }
@@ -597,8 +576,7 @@
         void commitPendingTransaction();
 
         /**
-         * Called when the animation leash is created. Note that this is also called by
-         * {@link SurfaceFreezer}, so this doesn't mean we're about to start animating.
+         * Called when the animation leash is created.
          *
          * @param t The transaction to use to apply any necessary changes.
          * @param leash The leash that was created.
diff --git a/services/core/java/com/android/server/wm/SurfaceFreezer.java b/services/core/java/com/android/server/wm/SurfaceFreezer.java
deleted file mode 100644
index e126ed6..0000000
--- a/services/core/java/com/android/server/wm/SurfaceFreezer.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import static com.android.internal.protolog.WmProtoLogGroups.WM_SHOW_TRANSACTIONS;
-import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_SCREEN_ROTATION;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.graphics.GraphicBuffer;
-import android.graphics.PixelFormat;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.hardware.HardwareBuffer;
-import android.util.Slog;
-import android.view.SurfaceControl;
-import android.window.ScreenCapture;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.ProtoLog;
-
-/**
- * This class handles "freezing" of an Animatable. The Animatable in question should implement
- * Freezable.
- *
- * The point of this is to enable WindowContainers to each be capable of freezing themselves.
- * Freezing means taking a snapshot and placing it above everything in the sub-hierarchy.
- * The "placing above" requires that a parent surface be inserted above the target surface so that
- * the target surface and the snapshot are siblings.
- *
- * The overall flow for a transition using this would be:
- * 1. Set transition and record animatable in mChangingApps
- * 2. Call {@link #freeze} to set-up the leashes and cover with a snapshot.
- * 3. When transition participants are ready, start SurfaceAnimator with this as a parameter
- * 4. SurfaceAnimator will then {@link #takeLeashForAnimation} instead of creating another leash.
- * 5. The animation system should eventually clean this up via {@link #unfreeze}.
- */
-class SurfaceFreezer {
-
-    private static final String TAG = "SurfaceFreezer";
-
-    private final @NonNull Freezable mAnimatable;
-    private final @NonNull WindowManagerService mWmService;
-    @VisibleForTesting
-    SurfaceControl mLeash;
-    Snapshot mSnapshot = null;
-    final Rect mFreezeBounds = new Rect();
-
-    /**
-     * @param animatable The object to animate.
-     */
-    SurfaceFreezer(@NonNull Freezable animatable, @NonNull WindowManagerService service) {
-        mAnimatable = animatable;
-        mWmService = service;
-    }
-
-    /**
-     * Freeze the target surface. This is done by creating a leash (inserting a parent surface
-     * above the target surface) and then taking a snapshot and placing it over the target surface.
-     *
-     * @param startBounds The original bounds (on screen) of the surface we are snapshotting.
-     * @param relativePosition The related position of the snapshot surface to its parent.
-     * @param freezeTarget The surface to take snapshot from. If {@code null}, we will take a
-     *                     snapshot from the {@link #mAnimatable} surface.
-     */
-    void freeze(SurfaceControl.Transaction t, Rect startBounds, Point relativePosition,
-            @Nullable SurfaceControl freezeTarget) {
-        reset(t);
-        mFreezeBounds.set(startBounds);
-
-        mLeash = SurfaceAnimator.createAnimationLeash(mAnimatable, mAnimatable.getSurfaceControl(),
-                t, ANIMATION_TYPE_SCREEN_ROTATION, startBounds.width(), startBounds.height(),
-                relativePosition.x, relativePosition.y, false /* hidden */,
-                mWmService.mTransactionFactory);
-        mAnimatable.onAnimationLeashCreated(t, mLeash);
-
-        freezeTarget = freezeTarget != null ? freezeTarget : mAnimatable.getFreezeSnapshotTarget();
-        if (freezeTarget != null) {
-            ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer = createSnapshotBufferInner(
-                    freezeTarget, startBounds);
-            final HardwareBuffer buffer = screenshotBuffer == null ? null
-                    : screenshotBuffer.getHardwareBuffer();
-            if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
-                // This can happen when display is not ready.
-                Slog.w(TAG, "Failed to capture screenshot for " + mAnimatable);
-                unfreeze(t);
-                return;
-            }
-            mSnapshot = new Snapshot(t, screenshotBuffer, mLeash);
-        }
-    }
-
-    /**
-     * Used by {@link SurfaceAnimator}. This "transfers" the leash to be used for animation.
-     * By transferring the leash, this will no longer try to clean-up the leash when finished.
-     */
-    SurfaceControl takeLeashForAnimation() {
-        SurfaceControl out = mLeash;
-        mLeash = null;
-        return out;
-    }
-
-    /**
-     * Used by {@link SurfaceAnimator}. This "transfers" the snapshot leash to be used for
-     * animation. By transferring the leash, this will no longer try to clean-up the leash when
-     * finished.
-     */
-    @Nullable
-    Snapshot takeSnapshotForAnimation() {
-        final Snapshot out = mSnapshot;
-        mSnapshot = null;
-        return out;
-    }
-
-    /**
-     * Clean-up the snapshot and remove leash. If the leash was taken, this just cleans-up the
-     * snapshot.
-     */
-    void unfreeze(SurfaceControl.Transaction t) {
-        unfreezeInner(t);
-        mAnimatable.onUnfrozen();
-    }
-
-    private void unfreezeInner(SurfaceControl.Transaction t) {
-        if (mSnapshot != null) {
-            mSnapshot.cancelAnimation(t, false /* restarting */);
-            mSnapshot = null;
-        }
-        if (mLeash == null) {
-            return;
-        }
-        SurfaceControl leash = mLeash;
-        mLeash = null;
-        final boolean scheduleAnim = SurfaceAnimator.removeLeash(t, mAnimatable, leash,
-                true /* destroy */);
-        if (scheduleAnim) {
-            mWmService.scheduleAnimationLocked();
-        }
-    }
-
-    /** Resets the snapshot before taking another one if the animation hasn't been started yet. */
-    private void reset(SurfaceControl.Transaction t) {
-        // Those would have been taken by the SurfaceAnimator if the animation has been started, so
-        // we can remove the leash directly.
-        // No need to reset the mAnimatable leash, as this is called before a new animation leash is
-        // created, so another #onAnimationLeashCreated will be called.
-        if (mSnapshot != null) {
-            mSnapshot.destroy(t);
-            mSnapshot = null;
-        }
-        if (mLeash != null) {
-            t.remove(mLeash);
-            mLeash = null;
-        }
-    }
-
-    void setLayer(SurfaceControl.Transaction t, int layer) {
-        if (mLeash != null) {
-            t.setLayer(mLeash, layer);
-        }
-    }
-
-    void setRelativeLayer(SurfaceControl.Transaction t, SurfaceControl relativeTo, int layer) {
-        if (mLeash != null) {
-            t.setRelativeLayer(mLeash, relativeTo, layer);
-        }
-    }
-
-    boolean hasLeash() {
-        return mLeash != null;
-    }
-
-    private static ScreenCapture.ScreenshotHardwareBuffer createSnapshotBuffer(
-            @NonNull SurfaceControl target, @Nullable Rect bounds) {
-        Rect cropBounds = null;
-        if (bounds != null) {
-            cropBounds = new Rect(bounds);
-            cropBounds.offsetTo(0, 0);
-        }
-        ScreenCapture.LayerCaptureArgs captureArgs =
-                new ScreenCapture.LayerCaptureArgs.Builder(target)
-                        .setSourceCrop(cropBounds)
-                        .setCaptureSecureLayers(true)
-                        .setAllowProtected(true)
-                        .build();
-        return ScreenCapture.captureLayers(captureArgs);
-    }
-
-    @VisibleForTesting
-    ScreenCapture.ScreenshotHardwareBuffer createSnapshotBufferInner(
-            SurfaceControl target, Rect bounds) {
-        return createSnapshotBuffer(target, bounds);
-    }
-
-    @VisibleForTesting
-    GraphicBuffer createFromHardwareBufferInner(
-            ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer) {
-        return GraphicBuffer.createFromHardwareBuffer(screenshotBuffer.getHardwareBuffer());
-    }
-
-    class Snapshot {
-        private SurfaceControl mSurfaceControl;
-        private AnimationAdapter mAnimation;
-
-        /**
-         * @param t Transaction to create the thumbnail in.
-         * @param screenshotBuffer A thumbnail or placeholder for thumbnail to initialize with.
-         */
-        Snapshot(SurfaceControl.Transaction t,
-                ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer, SurfaceControl parent) {
-            GraphicBuffer graphicBuffer = createFromHardwareBufferInner(screenshotBuffer);
-
-            mSurfaceControl = mAnimatable.makeAnimationLeash()
-                    .setName("snapshot anim: " + mAnimatable.toString())
-                    .setFormat(PixelFormat.TRANSLUCENT)
-                    .setParent(parent)
-                    .setSecure(screenshotBuffer.containsSecureLayers())
-                    .setCallsite("SurfaceFreezer.Snapshot")
-                    .setBLASTLayer()
-                    .build();
-
-            ProtoLog.i(WM_SHOW_TRANSACTIONS, "  THUMBNAIL %s: CREATE", mSurfaceControl);
-
-            t.setBuffer(mSurfaceControl, graphicBuffer);
-            t.setColorSpace(mSurfaceControl, screenshotBuffer.getColorSpace());
-            t.show(mSurfaceControl);
-
-            // We parent the thumbnail to the container, and just place it on top of anything else
-            // in the container.
-            t.setLayer(mSurfaceControl, Integer.MAX_VALUE);
-        }
-
-        void destroy(SurfaceControl.Transaction t) {
-            if (mSurfaceControl == null) {
-                return;
-            }
-            t.remove(mSurfaceControl);
-            mSurfaceControl = null;
-        }
-
-        /**
-         * Starts an animation.
-         *
-         * @param anim The object that bridges the controller, {@link SurfaceAnimator}, with the
-         *             component responsible for running the animation. It runs the animation with
-         *             {@link AnimationAdapter#startAnimation} once the hierarchy with
-         *             the Leash has been set up.
-         */
-        void startAnimation(SurfaceControl.Transaction t, AnimationAdapter anim, int type) {
-            cancelAnimation(t, true /* restarting */);
-            mAnimation = anim;
-            if (mSurfaceControl == null) {
-                cancelAnimation(t, false /* restarting */);
-                return;
-            }
-            mAnimation.startAnimation(mSurfaceControl, t, type, (typ, ani) -> { });
-        }
-
-        /**
-         * Cancels the animation, and resets the leash.
-         *
-         * @param t The transaction to use for all cancelling surface operations.
-         * @param restarting Whether we are restarting the animation.
-         */
-        void cancelAnimation(SurfaceControl.Transaction t, boolean restarting) {
-            final SurfaceControl leash = mSurfaceControl;
-            final AnimationAdapter animation = mAnimation;
-            mAnimation = null;
-            if (animation != null) {
-                animation.onAnimationCancelled(leash);
-            }
-            if (!restarting) {
-                destroy(t);
-            }
-        }
-    }
-
-    /** freezable */
-    public interface Freezable extends SurfaceAnimator.Animatable {
-        /**
-         * @return The surface to take a snapshot of. If this returns {@code null}, no snapshot
-         *         will be generated (but the rest of the freezing logic will still happen).
-         */
-        @Nullable SurfaceControl getFreezeSnapshotTarget();
-
-        /** Called when the {@link #unfreeze(SurfaceControl.Transaction)} is called. */
-        void onUnfrozen();
-    }
-}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index c6136f3..4b07e9e 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -52,11 +52,9 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
-import static android.view.WindowManager.TRANSIT_CHANGE;
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED;
 import static android.view.WindowManager.TRANSIT_NONE;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
@@ -75,7 +73,6 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CLEANUP;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
@@ -161,16 +158,15 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.voice.IVoiceInteractionSession;
-import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 import android.view.DisplayInfo;
 import android.view.InsetsState;
-import android.view.RemoteAnimationAdapter;
 import android.view.SurfaceControl;
 import android.view.WindowInsets;
 import android.view.WindowManager;
+import android.window.DesktopModeFlags;
 import android.window.ITaskOrganizer;
 import android.window.PictureInPictureSurfaceTransaction;
 import android.window.StartingWindowInfo;
@@ -2345,31 +2341,8 @@
     }
 
     @VisibleForTesting
-    Point getLastSurfaceSize() {
-        return mLastSurfaceSize;
-    }
-
-    @VisibleForTesting
     boolean isInChangeTransition() {
-        return mSurfaceFreezer.hasLeash() || AppTransition.isChangeTransitOld(mTransit);
-    }
-
-    @Override
-    public SurfaceControl getFreezeSnapshotTarget() {
-        if (!mDisplayContent.mAppTransition.containsTransitRequest(TRANSIT_CHANGE)) {
-            return null;
-        }
-        // Skip creating snapshot if this transition is controlled by a remote animator which
-        // doesn't need it.
-        final ArraySet<Integer> activityTypes = new ArraySet<>();
-        activityTypes.add(getActivityType());
-        final RemoteAnimationAdapter adapter =
-                mDisplayContent.mAppTransitionController.getRemoteAnimationOverride(
-                        this, TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE, activityTypes);
-        if (adapter != null && !adapter.getChangeNeedsSnapshot()) {
-            return null;
-        }
-        return getSurfaceControl();
+        return AppTransition.isChangeTransitOld(mTransit);
     }
 
     @Override
@@ -3470,8 +3443,10 @@
         info.lastNonFullscreenBounds = topTask.mLastNonFullscreenBounds;
         final WindowState windowState = top != null
                 ? top.findMainWindow(/* includeStartingApp= */ false) : null;
-        info.requestedVisibleTypes = (windowState != null && Flags.enableFullyImmersiveInDesktop())
-                ? windowState.getRequestedVisibleTypes() : WindowInsets.Type.defaultVisible();
+        info.requestedVisibleTypes =
+                (windowState != null && DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue())
+                        ? windowState.getRequestedVisibleTypes()
+                        : WindowInsets.Type.defaultVisible();
         AppCompatUtils.fillAppCompatTaskInfo(this, info, top);
         info.topActivityMainWindowFrame = calculateTopActivityMainWindowFrameForTaskInfo(top);
     }
@@ -5257,7 +5232,6 @@
 
         final boolean[] resumed = new boolean[1];
         final TaskFragment topFragment = topActivity.getTaskFragment();
-        resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
         forAllLeafTaskFragments(f -> {
             if (topFragment == f) {
                 return;
@@ -5267,6 +5241,7 @@
             }
             resumed[0] |= f.resumeTopActivity(prev, options, deferPause);
         }, true);
+        resumed[0] |= topFragment.resumeTopActivity(prev, options, deferPause);
         return resumed[0];
     }
 
@@ -6058,7 +6033,7 @@
             IVoiceInteractor voiceInteractor, boolean toTop, ActivityRecord activity,
             ActivityRecord source, ActivityOptions options) {
 
-        Task task;
+        final Task task;
         if (canReuseAsLeafTask()) {
             // This root task will only contain one task, so just return itself since all root
             // tasks ara now tasks and all tasks are now root tasks.
@@ -6068,7 +6043,6 @@
             final int taskId = activity != null
                     ? mTaskSupervisor.getNextTaskIdForUser(activity.mUserId)
                     : mTaskSupervisor.getNextTaskIdForUser();
-            final int activityType = getActivityType();
             task = new Task.Builder(mAtmService)
                     .setTaskId(taskId)
                     .setActivityInfo(info)
@@ -6081,17 +6055,21 @@
                     .build();
         }
 
-        int displayId = getDisplayId();
-        if (displayId == INVALID_DISPLAY) displayId = DEFAULT_DISPLAY;
-        final boolean isLockscreenShown = mAtmService.mTaskSupervisor.getKeyguardController()
-                .isKeyguardOrAodShowing(displayId);
-        if (!mTaskSupervisor.getLaunchParamsController()
-                .layoutTask(task, info.windowLayout, activity, source, options)
-                && !getRequestedOverrideBounds().isEmpty()
-                && task.isResizeable() && !isLockscreenShown) {
-            task.setBounds(getRequestedOverrideBounds());
+        if (com.android.window.flags.Flags.fixLayoutExistingTask()) {
+            mTaskSupervisor.getLaunchParamsController()
+                    .layoutTask(task, info.windowLayout, activity, source, options);
+        } else {
+            int displayId = getDisplayId();
+            if (displayId == INVALID_DISPLAY) displayId = DEFAULT_DISPLAY;
+            final boolean isLockscreenShown =
+                    mAtmService.mKeyguardController.isKeyguardOrAodShowing(displayId);
+            if (!mTaskSupervisor.getLaunchParamsController()
+                    .layoutTask(task, info.windowLayout, activity, source, options)
+                    && !getRequestedOverrideBounds().isEmpty()
+                    && task.isResizeable() && !isLockscreenShown) {
+                task.setBounds(getRequestedOverrideBounds());
+            }
         }
-
         return task;
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index fc7437b..ba48fdc 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1195,10 +1195,8 @@
         if (!isAttached() || isForceHidden() || isForceTranslucent()) {
             return true;
         }
-        // A TaskFragment isn't translucent if it has at least one visible activity that occludes
-        // this TaskFragment.
-        return mTaskSupervisor.mOpaqueActivityHelper.getVisibleOpaqueActivity(this,
-                starting, true /* ignoringKeyguard */) == null;
+        return !mTaskSupervisor.mOpaqueContainerHelper.isOpaque(
+                this, starting, true /* ignoringKeyguard */, true /* ignoringInvisibleActivity */);
     }
 
     /**
@@ -1211,7 +1209,7 @@
             return true;
         }
         // Including finishing Activity if the TaskFragment is becoming invisible in the transition.
-        return mTaskSupervisor.mOpaqueActivityHelper.getOpaqueActivity(this) == null;
+        return !mTaskSupervisor.mOpaqueContainerHelper.isOpaque(this);
     }
 
     /**
@@ -1222,8 +1220,8 @@
         if (!isAttached() || isForceHidden() || isForceTranslucent()) {
             return true;
         }
-        return mTaskSupervisor.mOpaqueActivityHelper.getVisibleOpaqueActivity(this, null,
-                false /* ignoringKeyguard */) == null;
+        return !mTaskSupervisor.mOpaqueContainerHelper.isOpaque(this, /* starting */ null,
+                false /* ignoringKeyguard */, true /* ignoringInvisibleActivity */);
     }
 
     ActivityRecord getTopNonFinishingActivity() {
@@ -2758,7 +2756,7 @@
             // We only want to update for organized TaskFragment. Task will handle itself.
             return;
         }
-        if (mSurfaceControl == null || mSurfaceAnimator.hasLeash() || mSurfaceFreezer.hasLeash()) {
+        if (mSurfaceControl == null || mSurfaceAnimator.hasLeash()) {
             return;
         }
 
@@ -2900,20 +2898,6 @@
         return task != null && !task.isDragResizing() && super.canStartChangeTransition();
     }
 
-    /**
-     * Returns {@code true} if the starting bounds of the closing organized TaskFragment is
-     * recorded. Otherwise, return {@code false}.
-     */
-    boolean setClosingChangingStartBoundsIfNeeded() {
-        if (isOrganizedTaskFragment() && mDisplayContent != null
-                && mDisplayContent.mChangingContainers.remove(this)) {
-            mDisplayContent.mClosingChangingContainers.put(
-                    this, new Rect(mSurfaceFreezer.mFreezeBounds));
-            return true;
-        }
-        return false;
-    }
-
     @Override
     boolean isSyncFinished(BLASTSyncEngine.SyncGroup group) {
         return super.isSyncFinished(group) && isReadyToTransit();
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 27683b2..5217a75 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -505,7 +505,7 @@
                 final WindowContainer<?> sibling = rootParent.getChildAt(j);
                 if (sibling == transientRoot) break;
                 if (!sibling.getWindowConfiguration().isAlwaysOnTop() && mController.mAtm
-                        .mTaskSupervisor.mOpaqueActivityHelper.getOpaqueActivity(sibling) != null) {
+                        .mTaskSupervisor.mOpaqueContainerHelper.isOpaque(sibling)) {
                     occludedCount++;
                     break;
                 }
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 883d8f9..225951d 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -138,7 +138,7 @@
  * changes are made to this class.
  */
 class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>
-        implements Comparable<WindowContainer>, Animatable, SurfaceFreezer.Freezable,
+        implements Comparable<WindowContainer>, Animatable,
         InsetsControlTarget {
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowContainer" : TAG_WM;
@@ -226,7 +226,6 @@
     @Nullable
     private SurfaceControl mAnimationLeash;
 
-    final SurfaceFreezer mSurfaceFreezer;
     protected final WindowManagerService mWmService;
     final TransitionController mTransitionController;
 
@@ -361,7 +360,6 @@
         mTransitionController = mWmService.mAtmService.getTransitionController();
         mSyncTransaction = wms.mTransactionFactory.get();
         mSurfaceAnimator = new SurfaceAnimator(this, this::onAnimationFinished, wms);
-        mSurfaceFreezer = new SurfaceFreezer(this, wms);
     }
 
     /**
@@ -908,7 +906,6 @@
         final DisplayContent dc = getDisplayContent();
         if (dc != null) {
             dc.mClosingChangingContainers.remove(this);
-            mSurfaceFreezer.unfreeze(getSyncTransaction());
         }
         while (!mChildren.isEmpty()) {
             final E child = mChildren.getLast();
@@ -1124,9 +1121,7 @@
             // Cancel any change transition queued-up for this container on the old display when
             // this container is moved from the old display.
             mDisplayContent.mClosingChangingContainers.remove(this);
-            if (mDisplayContent.mChangingContainers.remove(this)) {
-                mSurfaceFreezer.unfreeze(getSyncTransaction());
-            }
+            mDisplayContent.mChangingContainers.remove(this);
         }
         mDisplayContent = dc;
         if (dc != null && dc != this && mPendingTransaction != null) {
@@ -1434,33 +1429,6 @@
         return setVisibleRequested(newVisReq);
     }
 
-    /**
-     * Called when the visibility of a child is asked to change. This is before visibility actually
-     * changes (eg. a transition animation might play out first).
-     */
-    void onChildVisibilityRequested(boolean visible) {
-        // If we are losing visibility, then a snapshot isn't necessary and we are no-longer
-        // part of a change transition.
-        if (!visible) {
-            boolean skipUnfreeze = false;
-            if (asTaskFragment() != null) {
-                // If the organized TaskFragment is closing while resizing, we want to keep track of
-                // its starting bounds to make sure the animation starts at the correct position.
-                // This should be called before unfreeze() because we record the starting bounds
-                // in SurfaceFreezer.
-                skipUnfreeze = asTaskFragment().setClosingChangingStartBoundsIfNeeded();
-            }
-
-            if (!skipUnfreeze) {
-                mSurfaceFreezer.unfreeze(getSyncTransaction());
-            }
-        }
-        WindowContainer parent = getParent();
-        if (parent != null) {
-            parent.onChildVisibilityRequested(visible);
-        }
-    }
-
     /** Whether this window is closing while resizing. */
     boolean isClosingWhenResizing() {
         return mDisplayContent != null
@@ -1545,9 +1513,6 @@
     }
 
     void onAppTransitionDone() {
-        if (mSurfaceFreezer.hasLeash()) {
-            mSurfaceFreezer.unfreeze(getSyncTransaction());
-        }
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final WindowContainer wc = mChildren.get(i);
             wc.onAppTransitionDone();
@@ -2773,15 +2738,9 @@
     }
 
     protected void setLayer(Transaction t, int layer) {
-        if (mSurfaceFreezer.hasLeash()) {
-            // When the freezer has created animation leash parent for the window, set the layer
-            // there instead.
-            mSurfaceFreezer.setLayer(t, layer);
-        } else {
-            // Route through surface animator to accommodate that our surface control might be
-            // attached to the leash, and leash is attached to parent container.
-            mSurfaceAnimator.setLayer(t, layer);
-        }
+        // Route through surface animator to accommodate that our surface control might be
+        // attached to the leash, and leash is attached to parent container.
+        mSurfaceAnimator.setLayer(t, layer);
     }
 
     int getLastLayer() {
@@ -2793,20 +2752,14 @@
     }
 
     protected void setRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
-        if (mSurfaceFreezer.hasLeash()) {
-            // When the freezer has created animation leash parent for the window, set the layer
-            // there instead.
-            mSurfaceFreezer.setRelativeLayer(t, relativeTo, layer);
-        } else {
-            // Route through surface animator to accommodate that our surface control might be
-            // attached to the leash, and leash is attached to parent container.
-            mSurfaceAnimator.setRelativeLayer(t, relativeTo, layer);
-        }
+        // Route through surface animator to accommodate that our surface control might be
+        // attached to the leash, and leash is attached to parent container.
+        mSurfaceAnimator.setRelativeLayer(t, relativeTo, layer);
     }
 
     protected void reparentSurfaceControl(Transaction t, SurfaceControl newParent) {
         // Don't reparent active leashes since the animator won't know about the change.
-        if (mSurfaceFreezer.hasLeash() || mSurfaceAnimator.hasLeash()) return;
+        if (mSurfaceAnimator.hasLeash()) return;
         t.reparent(getSurfaceControl(), newParent);
     }
 
@@ -3044,7 +2997,7 @@
         // TODO: This should use isVisible() but because isVisible has a really weird meaning at
         // the moment this doesn't work for all animatable window containers.
         mSurfaceAnimator.startAnimation(t, anim, hidden, type, animationFinishedCallback,
-                animationCancelledCallback, snapshotAnim, mSurfaceFreezer);
+                animationCancelledCallback, snapshotAnim);
     }
 
     void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
@@ -3066,7 +3019,6 @@
     void cancelAnimation() {
         doAnimationFinished(mSurfaceAnimator.getAnimationType(), mSurfaceAnimator.getAnimation());
         mSurfaceAnimator.cancelAnimation();
-        mSurfaceFreezer.unfreeze(getSyncTransaction());
     }
 
     /** Whether we can start change transition with this window and current display status. */
@@ -3097,7 +3049,7 @@
     }
 
     /**
-     * Initializes a change transition. See {@link SurfaceFreezer} for more information.
+     * Initializes a change transition.
      *
      * For now, this will only be called for the following cases:
      * 1. {@link Task} is changing windowing mode between fullscreen and freeform.
@@ -3109,8 +3061,6 @@
      * use case.
      *
      * @param startBounds The original bounds (on screen) of the surface we are snapshotting.
-     * @param freezeTarget The surface to take snapshot from. If {@code null}, we will take a
-     *                     snapshot from {@link #getFreezeSnapshotTarget()}.
      */
     void initializeChangeTransition(Rect startBounds, @Nullable SurfaceControl freezeTarget) {
         if (mDisplayContent.mTransitionController.isShellTransitionsEnabled()) {
@@ -3122,7 +3072,6 @@
         // Calculate the relative position in parent container.
         final Rect parentBounds = getParent().getBounds();
         mTmpPoint.set(startBounds.left - parentBounds.left, startBounds.top - parentBounds.top);
-        mSurfaceFreezer.freeze(getSyncTransaction(), startBounds, mTmpPoint, freezeTarget);
     }
 
     void initializeChangeTransition(Rect startBounds) {
@@ -3134,23 +3083,6 @@
     }
 
     @Override
-    public SurfaceControl getFreezeSnapshotTarget() {
-        // Only allow freezing if this window is in a TRANSIT_CHANGE
-        if (!mDisplayContent.mAppTransition.containsTransitRequest(TRANSIT_CHANGE)
-                || !mDisplayContent.mChangingContainers.contains(this)) {
-            return null;
-        }
-        return getSurfaceControl();
-    }
-
-    @Override
-    public void onUnfrozen() {
-        if (mDisplayContent != null) {
-            mDisplayContent.mChangingContainers.remove(this);
-        }
-    }
-
-    @Override
     public Builder makeAnimationLeash() {
         return makeSurface().setContainerLayer();
     }
@@ -3279,7 +3211,7 @@
                         this, mTmpPoint, localBounds, screenBounds, closingStartBounds,
                         showBackdrop, false /* shouldCreateSnapshot */);
             } else {
-                final Rect startBounds = isChanging ? mSurfaceFreezer.mFreezeBounds : null;
+                final Rect startBounds = null;
                 adapters = controller.createRemoteAnimationRecord(
                         this, mTmpPoint, localBounds, screenBounds, startBounds, showBackdrop);
             }
@@ -3298,16 +3230,12 @@
             mTmpRect.offsetTo(mTmpPoint.x, mTmpPoint.y);
 
             final AnimationAdapter adapter = new LocalAnimationAdapter(
-                    new WindowChangeAnimationSpec(mSurfaceFreezer.mFreezeBounds, mTmpRect,
+                    new WindowChangeAnimationSpec(null /* startBounds */, mTmpRect,
                             displayInfo, durationScale, true /* isAppAnimation */,
                             false /* isThumbnail */),
                     getSurfaceAnimationRunner());
 
-            final AnimationAdapter thumbnailAdapter = mSurfaceFreezer.mSnapshot != null
-                    ? new LocalAnimationAdapter(new WindowChangeAnimationSpec(
-                    mSurfaceFreezer.mFreezeBounds, mTmpRect, displayInfo, durationScale,
-                    true /* isAppAnimation */, true /* isThumbnail */), getSurfaceAnimationRunner())
-                    : null;
+            final AnimationAdapter thumbnailAdapter = null;
             resultAdapters = new Pair<>(adapter, thumbnailAdapter);
             mTransit = transit;
             mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
@@ -3731,7 +3659,7 @@
      */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
     void updateSurfacePosition(Transaction t) {
-        if (mSurfaceControl == null || mSurfaceAnimator.hasLeash() || mSurfaceFreezer.hasLeash()) {
+        if (mSurfaceControl == null || mSurfaceAnimator.hasLeash()) {
             return;
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index c77b1d9..6e224f0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -1137,6 +1137,15 @@
      * Returns an instance of {@link ScreenshotHardwareBuffer} containing the current
      * screenshot.
      */
-    public abstract ScreenshotHardwareBuffer takeAssistScreenshot(
-            Set<Integer> windowTypesToExclude);
+    public abstract ScreenshotHardwareBuffer takeAssistScreenshot();
+
+    /**
+     * Returns an instance of {@link ScreenshotHardwareBuffer} containing the current
+     * screenshot, excluding layers that are not appropriate to pass to contextual search
+     * services - such as the cursor or any current contextual search window.
+     *
+     * @param uid the UID of the contextual search application. System alert windows belonging
+     * to this UID will be excluded from the screenshot.
+     */
+    public abstract ScreenshotHardwareBuffer takeContextualSearchScreenshot(int uid);
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 3a1d652..7f19240 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -325,6 +325,7 @@
 import android.window.WindowContextInfo;
 
 import com.android.internal.R;
+import com.android.internal.util.ToBooleanFunction;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.annotations.VisibleForTesting.Visibility;
@@ -4159,7 +4160,8 @@
     }
 
     @Nullable
-    private ScreenshotHardwareBuffer takeAssistScreenshot(Set<Integer> windowTypesToExclude) {
+    private ScreenshotHardwareBuffer takeAssistScreenshot(
+            @Nullable ToBooleanFunction<WindowState> predicate) {
         if (!checkCallingPermission(READ_FRAME_BUFFER, "requestAssistScreenshot()")) {
             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
         }
@@ -4174,7 +4176,7 @@
                 }
                 captureArgs = null;
             } else {
-                captureArgs = displayContent.getLayerCaptureArgs(windowTypesToExclude);
+                captureArgs = displayContent.getLayerCaptureArgs(predicate);
             }
         }
 
@@ -4204,8 +4206,7 @@
      */
     @Override
     public boolean requestAssistScreenshot(final IAssistDataReceiver receiver) {
-        final ScreenshotHardwareBuffer shb =
-                takeAssistScreenshot(/* windowTypesToExclude= */ Set.of());
+        final ScreenshotHardwareBuffer shb = takeAssistScreenshot(/* predicate= */ null);
         final Bitmap bm = shb != null ? shb.asBitmap() : null;
         FgThread.getHandler().post(() -> {
             try {
@@ -8618,9 +8619,27 @@
         }
 
         @Override
-        public ScreenshotHardwareBuffer takeAssistScreenshot(Set<Integer> windowTypesToExclude) {
+        public ScreenshotHardwareBuffer takeAssistScreenshot() {
             // WMS.takeAssistScreenshot takes care of the locking.
-            return WindowManagerService.this.takeAssistScreenshot(windowTypesToExclude);
+            return WindowManagerService.this.takeAssistScreenshot(/* predicate */ null);
+        }
+
+        @Override
+        public ScreenshotHardwareBuffer takeContextualSearchScreenshot(int uid) {
+            // WMS.takeAssistScreenshot takes care of the locking.
+            return WindowManagerService.this.takeAssistScreenshot(win -> {
+                switch (win.getWindowType()) {
+                    case LayoutParams.TYPE_STATUS_BAR:
+                    case LayoutParams.TYPE_NAVIGATION_BAR:
+                    case LayoutParams.TYPE_NAVIGATION_BAR_PANEL:
+                    case LayoutParams.TYPE_POINTER:
+                        return false;
+                    case LayoutParams.TYPE_APPLICATION_OVERLAY:
+                        return uid != win.getOwningUid();
+                    default:
+                        return true;
+                }
+            });
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index b4c2c01..a11f4b1 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -52,6 +52,7 @@
 import static android.window.WindowContainerTransaction.Change.CHANGE_FORCE_TRANSLUCENT;
 import static android.window.WindowContainerTransaction.Change.CHANGE_HIDDEN;
 import static android.window.WindowContainerTransaction.Change.CHANGE_RELATIVE_BOUNDS;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_ROOT_TASK;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_KEYGUARD_STATE;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_INSETS_FRAME_PROVIDER;
@@ -77,6 +78,8 @@
 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;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_SHORTCUT;
+import static android.window.WindowContainerTransaction.HierarchyOp.REACHABILITY_EVENT_X;
+import static android.window.WindowContainerTransaction.HierarchyOp.REACHABILITY_EVENT_Y;
 
 import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_WINDOW_ORGANIZER;
 import static com.android.server.wm.ActivityRecord.State.PAUSING;
@@ -1196,6 +1199,30 @@
                         caller.mPid, caller.mUid, taskId, safeOptions));
                 break;
             }
+            case HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY: {
+                int doubleTapX = hop.getAppCompatOptions().getInt(REACHABILITY_EVENT_X);
+                int doubleTapY = hop.getAppCompatOptions().getInt(REACHABILITY_EVENT_Y);
+                final WindowContainer<?> wc = WindowContainer.fromBinder(hop.getContainer());
+                if (wc == null) {
+                    break;
+                }
+                final Task currentTask = wc.asTask();
+                if (chain.mTransition != null) {
+                    chain.mTransition.collect(wc);
+                }
+                if (currentTask != null) {
+                    final ActivityRecord top = currentTask.topRunningActivity();
+                    if (top != null) {
+                        if (chain.mTransition != null) {
+                            chain.mTransition.collect(top);
+                        }
+                        top.mAppCompatController.getReachabilityPolicy().handleDoubleTap(doubleTapX,
+                                doubleTapY);
+                    }
+                }
+                effects |= TRANSACT_EFFECTS_CLIENT_CONFIG;
+                break;
+            }
             case HIERARCHY_OP_TYPE_REORDER:
             case HIERARCHY_OP_TYPE_REPARENT: {
                 final WindowContainer wc = WindowContainer.fromBinder(hop.getContainer());
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 582cd4e..e11c31c 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2723,16 +2723,16 @@
         }
     }
 
-    /**
-     * Apply default restrictions that haven't been applied to a given admin yet.
-     */
+    /** Apply default restrictions that haven't been applied to a given admin yet. */
     private void maybeSetDefaultRestrictionsForAdminLocked(int userId, ActiveAdmin admin) {
-        Set<String> defaultRestrictions =
-                UserRestrictionsUtils.getDefaultEnabledForManagedProfiles();
-        if (defaultRestrictions.equals(admin.defaultEnabledRestrictionsAlreadySet)) {
+        Set<String> newDefaultRestrictions = new HashSet(
+            UserRestrictionsUtils.getDefaultEnabledForManagedProfiles());
+        newDefaultRestrictions.removeAll(admin.defaultEnabledRestrictionsAlreadySet);
+        if (newDefaultRestrictions.isEmpty()) {
             return; // The same set of default restrictions has been already applied.
         }
-        for (String restriction : defaultRestrictions) {
+
+        for (String restriction : newDefaultRestrictions) {
             mDevicePolicyEngine.setLocalPolicy(
                     PolicyDefinition.getPolicyDefinitionForUserRestriction(restriction),
                     EnforcingAdmin.createEnterpriseEnforcingAdmin(
@@ -2740,10 +2740,9 @@
                             admin.getUserHandle().getIdentifier()),
                     new BooleanPolicyValue(true),
                     userId);
+            admin.defaultEnabledRestrictionsAlreadySet.add(restriction);
+            Slogf.i(LOG_TAG, "Enabled the following restriction by default: " + restriction);
         }
-        admin.defaultEnabledRestrictionsAlreadySet.addAll(defaultRestrictions);
-        Slogf.i(LOG_TAG, "Enabled the following restrictions by default: "
-                + defaultRestrictions);
     }
 
     private void maybeStartSecurityLogMonitorOnActivityManagerReady() {
@@ -10282,7 +10281,8 @@
                 return false;
             }
 
-            if (isAdb(caller)) {
+            boolean isAdb = isAdb(caller);
+            if (isAdb) {
                 // Log profile owner provisioning was started using adb.
                 MetricsLogger.action(mContext, PROVISIONING_ENTRY_POINT_ADB, LOG_TAG_PROFILE_OWNER);
                 DevicePolicyEventLogger
@@ -10305,6 +10305,18 @@
                     ensureUnknownSourcesRestrictionForProfileOwnerLocked(userHandle, admin,
                             true /* newOwner */);
                 }
+                if(isAdb) {
+                    // DISALLOW_DEBUGGING_FEATURES is being added to newly-created
+                    // work profile by default due to b/382064697 . This would have
+                    //  impacted certain CTS test flows when they interact with the
+                    // work profile via ADB (for example installing an app into the
+                    // work profile). Remove DISALLOW_DEBUGGING_FEATURES here to
+                    // reduce the potential impact.
+                    setLocalUserRestrictionInternal(
+                        EnforcingAdmin.createEnterpriseEnforcingAdmin(who, userHandle),
+                        UserManager.DISALLOW_DEBUGGING_FEATURES, false, userHandle);
+                }
+
                 sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_PROFILE_OWNER_CHANGED,
                         userHandle);
             });
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 c62cd6e..7128af5 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
@@ -467,11 +467,17 @@
     override fun getPermissionRequestState(
         packageName: String,
         permissionName: String,
-        deviceId: String
+        deviceId: Int,
+        persistentDeviceId: String
     ): Int {
         val pid = Binder.getCallingPid()
         val uid = Binder.getCallingUid()
-        val result = context.checkPermission(permissionName, pid, uid)
+        val deviceContext = if (deviceId == context.deviceId){
+            context
+        } else {
+            context.createDeviceContext(deviceId)
+        }
+        val result = deviceContext.checkPermission(permissionName, pid, uid)
         if (result == PackageManager.PERMISSION_GRANTED) {
             return Context.PERMISSION_REQUEST_STATE_GRANTED
         }
@@ -497,14 +503,14 @@
 
         val permissionFlags =
             service.getState {
-                getPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId)
+                getPermissionFlagsWithPolicy(appId, userId, permissionName, persistentDeviceId)
             }
         val isUnreqestable = permissionFlags.hasAnyBit(UNREQUESTABLE_MASK)
         // Special case for READ_MEDIA_IMAGES due to photo picker
         if ((permissionName == Manifest.permission.READ_MEDIA_IMAGES ||
                 permissionName == Manifest.permission.READ_MEDIA_VIDEO) && isUnreqestable) {
             val isUserSelectedGranted =
-                context.checkPermission(
+                deviceContext.checkPermission(
                     Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED,
                     pid,
                     uid,
@@ -515,7 +521,7 @@
                         appId,
                         userId,
                         Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED,
-                        deviceId,
+                        persistentDeviceId,
                     )
                 }
             if (
diff --git a/services/supervision/java/com/android/server/supervision/SupervisionService.java b/services/supervision/java/com/android/server/supervision/SupervisionService.java
index ea85710..a96c477 100644
--- a/services/supervision/java/com/android/server/supervision/SupervisionService.java
+++ b/services/supervision/java/com/android/server/supervision/SupervisionService.java
@@ -177,23 +177,24 @@
         }
     }
 
-    /** Ensures that supervision is enabled when the supervision app is the profile owner. */
+    /**
+     * Ensures that supervision is enabled when the supervision app is the profile owner.
+     *
+     * <p>The state syncing with the DevicePolicyManager can only enable supervision and never
+     * disable. Supervision can only be disabled explicitly via calls to the
+     * {@link #setSupervisionEnabledForUser} method.
+     */
     private void syncStateWithDevicePolicyManager(@UserIdInt int userId) {
         final DevicePolicyManagerInternal dpmInternal = mInjector.getDpmInternal();
         final ComponentName po =
                 dpmInternal != null ? dpmInternal.getProfileOwnerAsUser(userId) : null;
 
         if (po != null && po.getPackageName().equals(getSystemSupervisionPackage())) {
-            setSupervisionEnabledForUserInternal(userId, true, po.getPackageName());
+            setSupervisionEnabledForUserInternal(userId, true, getSystemSupervisionPackage());
         } else if (po != null && po.equals(getSupervisionProfileOwnerComponent())) {
             // TODO(b/392071637): Consider not enabling supervision in case profile owner is given
             // to the legacy supervision profile owner component.
             setSupervisionEnabledForUserInternal(userId, true, po.getPackageName());
-        } else {
-            // TODO(b/381428475): Avoid disabling supervision when the app is not the profile owner.
-            // This might only be possible after introducing specific and public APIs to enable
-            // and disable supervision.
-            setSupervisionEnabledForUserInternal(userId, false, /* supervisionAppPackage= */ null);
         }
     }
 
@@ -279,7 +280,7 @@
         }
 
         @VisibleForTesting
-        @SuppressLint("MissingPermission") // not needed for a service
+        @SuppressLint("MissingPermission")  // not needed for a system service
         void registerProfileOwnerListener() {
             IntentFilter poIntentFilter = new IntentFilter();
             poIntentFilter.addAction(DevicePolicyManager.ACTION_PROFILE_OWNER_CHANGED);
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
index d087155..c954b18 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
@@ -183,7 +183,7 @@
         setShowImeWithHardKeyboard(true /* enabled */);
 
         // Triggers to show IME via public API.
-        verifyInputViewStatus(
+        verifyInputViewStatusOnMainSync(
                 () -> assertThat(mActivity.showImeWithWindowInsetsController()).isTrue(),
                 true /* expected */,
                 true /* inputViewStarted */);
@@ -211,7 +211,6 @@
      * lose flags like HIDE_IMPLICIT_ONLY.
      */
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)
     public void testShowHideSelf() throws Exception {
         setShowImeWithHardKeyboard(true /* enabled */);
 
@@ -223,13 +222,16 @@
                 true /* inputViewStarted */);
         assertThat(mInputMethodService.isInputViewShown()).isTrue();
 
-        // IME request to hide itself with flag HIDE_IMPLICIT_ONLY, expect not hide (shown).
-        Log.i(TAG, "Call IMS#requestHideSelf(InputMethodManager.HIDE_IMPLICIT_ONLY)");
-        verifyInputViewStatusOnMainSync(
-                () -> mInputMethodService.requestHideSelf(InputMethodManager.HIDE_IMPLICIT_ONLY),
-                false /* expected */,
-                true /* inputViewStarted */);
-        assertThat(mInputMethodService.isInputViewShown()).isTrue();
+        if (!mFlagsValueProvider.getBoolean(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)) {
+            // IME request to hide itself with flag HIDE_IMPLICIT_ONLY, expect not hide (shown).
+            Log.i(TAG, "Call IMS#requestHideSelf(InputMethodManager.HIDE_IMPLICIT_ONLY)");
+            verifyInputViewStatusOnMainSync(
+                    () -> mInputMethodService.requestHideSelf(
+                            InputMethodManager.HIDE_IMPLICIT_ONLY),
+                    false /* expected */,
+                    true /* inputViewStarted */);
+            assertThat(mInputMethodService.isInputViewShown()).isTrue();
+        }
 
         // IME request to hide itself without any flags, expect hidden.
         Log.i(TAG, "Call IMS#requestHideSelf(0)");
@@ -237,23 +239,32 @@
                 () -> mInputMethodService.requestHideSelf(0 /* flags */),
                 true /* expected */,
                 false /* inputViewStarted */);
-        assertThat(mInputMethodService.isInputViewShown()).isFalse();
+        if (mFlagsValueProvider.getBoolean(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)) {
+            // The IME visibility is only sent at the end of the animation. Therefore, we have to
+            // wait until the visibility was sent to the server and the IME window hidden.
+            eventually(() -> assertThat(mInputMethodService.isInputViewShown()).isFalse());
+        } else {
+            assertThat(mInputMethodService.isInputViewShown()).isFalse();
+        }
 
-        // IME request to show itself with flag SHOW_IMPLICIT, expect shown.
-        Log.i(TAG, "Call IMS#requestShowSelf(InputMethodManager.SHOW_IMPLICIT)");
-        verifyInputViewStatusOnMainSync(
-                () -> mInputMethodService.requestShowSelf(InputMethodManager.SHOW_IMPLICIT),
-                true /* expected */,
-                true /* inputViewStarted */);
-        assertThat(mInputMethodService.isInputViewShown()).isTrue();
+        if (!mFlagsValueProvider.getBoolean(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)) {
+            // IME request to show itself with flag SHOW_IMPLICIT, expect shown.
+            Log.i(TAG, "Call IMS#requestShowSelf(InputMethodManager.SHOW_IMPLICIT)");
+            verifyInputViewStatusOnMainSync(
+                    () -> mInputMethodService.requestShowSelf(InputMethodManager.SHOW_IMPLICIT),
+                    true /* expected */,
+                    true /* inputViewStarted */);
+            assertThat(mInputMethodService.isInputViewShown()).isTrue();
 
-        // IME request to hide itself with flag HIDE_IMPLICIT_ONLY, expect hidden.
-        Log.i(TAG, "Call IMS#requestHideSelf(InputMethodManager.HIDE_IMPLICIT_ONLY)");
-        verifyInputViewStatusOnMainSync(
-                () -> mInputMethodService.requestHideSelf(InputMethodManager.HIDE_IMPLICIT_ONLY),
-                true /* expected */,
-                false /* inputViewStarted */);
-        assertThat(mInputMethodService.isInputViewShown()).isFalse();
+            // IME request to hide itself with flag HIDE_IMPLICIT_ONLY, expect hidden.
+            Log.i(TAG, "Call IMS#requestHideSelf(InputMethodManager.HIDE_IMPLICIT_ONLY)");
+            verifyInputViewStatusOnMainSync(
+                    () -> mInputMethodService.requestHideSelf(
+                            InputMethodManager.HIDE_IMPLICIT_ONLY),
+                    true /* expected */,
+                    false /* inputViewStarted */);
+            assertThat(mInputMethodService.isInputViewShown()).isFalse();
+        }
     }
 
     /**
@@ -992,35 +1003,26 @@
      * @param expected whether the runnable is expected to trigger the signal.
      * @param orientationPortrait whether the orientation is expected to be portrait.
      */
-    private void verifyFullscreenMode(
-            Runnable runnable, boolean expected, boolean orientationPortrait)
-            throws InterruptedException {
-        CountDownLatch signal = new CountDownLatch(1);
-        mInputMethodService.setCountDownLatchForTesting(signal);
-
-        // Runnable to trigger onConfigurationChanged()
-        try {
-            runnable.run();
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-        // Waits for onConfigurationChanged() to finish.
-        mInstrumentation.waitForIdleSync();
-        boolean completed = signal.await(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS);
-        if (expected && !completed) {
-            fail("Timed out waiting for onConfigurationChanged()");
-        } else if (!expected && completed) {
-            fail("Unexpected call onConfigurationChanged()");
+    private void verifyFullscreenMode(@NonNull Runnable runnable, boolean expected,
+            boolean orientationPortrait) throws InterruptedException {
+        verifyInputViewStatus(runnable, expected, false /* inputViewStarted */);
+        if (expected) {
+            // Wait for the TestActivity to be recreated.
+            eventually(() ->
+                    assertThat(TestActivity.getLastCreatedInstance()).isNotEqualTo(mActivity));
+            // Get the new TestActivity.
+            mActivity = TestActivity.getLastCreatedInstance();
         }
 
-        clickOnEditorText();
-        eventually(() -> assertThat(mInputMethodService.isInputViewShown()).isTrue());
+        verifyInputViewStatusOnMainSync(
+                () -> mActivity.showImeWithWindowInsetsController(),
+                true /* expected */,
+                true /* inputViewStarted */);
+        assertThat(mInputMethodService.isInputViewShown()).isTrue();
 
         assertThat(mInputMethodService.getResources().getConfiguration().orientation)
-                .isEqualTo(
-                        orientationPortrait
-                                ? Configuration.ORIENTATION_PORTRAIT
-                                : Configuration.ORIENTATION_LANDSCAPE);
+                .isEqualTo(orientationPortrait
+                        ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE);
         EditorInfo editorInfo = mInputMethodService.getCurrentInputEditorInfo();
         assertThat(editorInfo.imeOptions & EditorInfo.IME_FLAG_NO_FULLSCREEN).isEqualTo(0);
         assertThat(editorInfo.internalImeOptions & EditorInfo.IME_INTERNAL_FLAG_APP_WINDOW_PORTRAIT)
@@ -1029,7 +1031,19 @@
         assertThat(mInputMethodService.onEvaluateFullscreenMode()).isEqualTo(!orientationPortrait);
         assertThat(mInputMethodService.isFullscreenMode()).isEqualTo(!orientationPortrait);
 
-        mUiDevice.pressBack();
+        // Hide IME before finishing the run.
+        verifyInputViewStatusOnMainSync(
+                () -> mActivity.hideImeWithWindowInsetsController(),
+                true /* expected */,
+                false /* inputViewStarted */);
+
+        if (mFlagsValueProvider.getBoolean(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)) {
+            // The IME visibility is only sent at the end of the animation. Therefore, we have to
+            // wait until the visibility was sent to the server and the IME window hidden.
+            eventually(() -> assertThat(mInputMethodService.isInputViewShown()).isFalse());
+        } else {
+            assertThat(mInputMethodService.isInputViewShown()).isFalse();
+        }
     }
 
     private void prepareIme() throws Exception {
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 a0e18ff..e0e4425 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -107,6 +107,7 @@
 import android.hardware.display.DisplayManagerInternal;
 import android.hardware.display.DisplayManagerInternal.DisplayOffloader;
 import android.hardware.display.DisplayTopology;
+import android.hardware.display.DisplayTopologyGraph;
 import android.hardware.display.DisplayViewport;
 import android.hardware.display.DisplayedContentSample;
 import android.hardware.display.DisplayedContentSamplingAttributes;
@@ -136,6 +137,7 @@
 import android.test.mock.MockContentResolver;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseIntArray;
 import android.util.Spline;
 import android.view.ContentRecordingSession;
 import android.view.Display;
@@ -3875,8 +3877,16 @@
                 displayManager.new BinderService();
         registerDefaultDisplays(displayManager);
         initDisplayPowerController(localService);
+        displayManager.windowManagerAndInputReady();
 
-        displayManagerBinderService.setDisplayTopology(new DisplayTopology());
+        DisplayTopology topology = mock(DisplayTopology.class);
+        when(topology.copy()).thenReturn(topology);
+        DisplayTopologyGraph graph = mock(DisplayTopologyGraph.class);
+        when(topology.getGraph(any(SparseIntArray.class))).thenReturn(graph);
+        displayManagerBinderService.setDisplayTopology(topology);
+        waitForIdleHandler(displayManager.getDisplayHandler());
+
+        verify(mMockInputManagerInternal).setDisplayTopology(graph);
     }
 
     @Test
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyCoordinatorTest.kt b/services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyCoordinatorTest.kt
index 04dff1d..3c134b5d 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyCoordinatorTest.kt
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyCoordinatorTest.kt
@@ -18,39 +18,52 @@
 
 import android.hardware.display.DisplayTopology
 import android.hardware.display.DisplayTopology.pxToDp
+import android.hardware.display.DisplayTopologyGraph
 import android.util.SparseArray
+import android.util.SparseIntArray
 import android.view.Display
 import android.view.DisplayInfo
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
+import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers.anyFloat
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.kotlin.any
+import org.mockito.kotlin.clearInvocations
 import org.mockito.kotlin.eq
 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
 
 class DisplayTopologyCoordinatorTest {
     private lateinit var coordinator: DisplayTopologyCoordinator
-    private val displayInfo = DisplayInfo()
+    private lateinit var displayInfos: List<DisplayInfo>
     private val topologyChangeExecutor = Runnable::run
 
     private val mockTopologyStore = mock<DisplayTopologyStore>()
     private val mockTopology = mock<DisplayTopology>()
     private val mockTopologyCopy = mock<DisplayTopology>()
+    private val mockTopologyGraph = mock<DisplayTopologyGraph>()
     private val mockIsExtendedDisplayEnabled = mock<() -> Boolean>()
     private val mockTopologySavedCallback = mock<() -> Unit>()
-    private val mockTopologyChangedCallback = mock<(DisplayTopology) -> Unit>()
+    private val mockTopologyChangedCallback =
+        mock<(android.util.Pair<DisplayTopology, DisplayTopologyGraph>) -> Unit>()
 
     @Before
     fun setUp() {
-        displayInfo.displayId = Display.DEFAULT_DISPLAY
-        displayInfo.logicalWidth = 300
-        displayInfo.logicalHeight = 200
-        displayInfo.logicalDensityDpi = 100
+        displayInfos = (1..10).map { i ->
+            val info = DisplayInfo()
+            info.displayId = i
+            info.displayGroupId = Display.DEFAULT_DISPLAY_GROUP
+            info.logicalWidth = i * 300
+            info.logicalHeight = i * 200
+            info.logicalDensityDpi = i * 100
+            info.type = Display.TYPE_EXTERNAL
+            return@map info
+        }
 
         val injector = object : DisplayTopologyCoordinator.Injector() {
             override fun getTopology() = mockTopology
@@ -62,6 +75,7 @@
         }
         whenever(mockIsExtendedDisplayEnabled()).thenReturn(true)
         whenever(mockTopology.copy()).thenReturn(mockTopologyCopy)
+        whenever(mockTopologyCopy.getGraph(any())).thenReturn(mockTopologyGraph)
         coordinator = DisplayTopologyCoordinator(injector, mockIsExtendedDisplayEnabled,
             mockTopologyChangedCallback, topologyChangeExecutor, DisplayManagerService.SyncRoot(),
             mockTopologySavedCallback)
@@ -69,20 +83,136 @@
 
     @Test
     fun addDisplay() {
-        coordinator.onDisplayAdded(displayInfo)
+        displayInfos.forEachIndexed { i, displayInfo ->
+            coordinator.onDisplayAdded(displayInfo)
 
-        val widthDp = pxToDp(displayInfo.logicalWidth.toFloat(), displayInfo.logicalDensityDpi)
-        val heightDp = pxToDp(displayInfo.logicalHeight.toFloat(), displayInfo.logicalDensityDpi)
-        verify(mockTopology).addDisplay(displayInfo.displayId, widthDp, heightDp)
-        verify(mockTopologyChangedCallback).invoke(mockTopologyCopy)
-        verify(mockTopologyStore).restoreTopology(mockTopology)
+            val widthDp = pxToDp(displayInfo.logicalWidth.toFloat(), displayInfo.logicalDensityDpi)
+            val heightDp =
+                pxToDp(displayInfo.logicalHeight.toFloat(), displayInfo.logicalDensityDpi)
+            verify(mockTopology).addDisplay(displayInfo.displayId, widthDp, heightDp)
+        }
+
+        val captor = ArgumentCaptor.forClass(SparseIntArray::class.java)
+        verify(mockTopologyCopy, times(displayInfos.size)).getGraph(captor.capture())
+        val densities = captor.value
+        assertThat(densities.size()).isEqualTo(displayInfos.size)
+        for (displayInfo in displayInfos) {
+            assertThat(densities.get(displayInfo.displayId))
+                .isEqualTo(displayInfo.logicalDensityDpi)
+        }
+
+        verify(mockTopologyChangedCallback, times(displayInfos.size)).invoke(
+            android.util.Pair(
+                mockTopologyCopy,
+                mockTopologyGraph
+            )
+        )
+        verify(mockTopologyStore, times(displayInfos.size)).restoreTopology(mockTopology)
+
+        // Clear invocations for other tests that call this method
+        clearInvocations(mockTopologyCopy)
+        clearInvocations(mockTopologyChangedCallback)
+        clearInvocations(mockTopologyStore)
     }
 
     @Test
-    fun addDisplay_extendedDisplaysDisabled() {
+    fun addDisplay_internal() {
+        displayInfos[0].displayId = Display.DEFAULT_DISPLAY
+        displayInfos[0].type = Display.TYPE_INTERNAL
+        coordinator.onDisplayAdded(displayInfos[0])
+
+        val widthDp =
+            pxToDp(displayInfos[0].logicalWidth.toFloat(), displayInfos[0].logicalDensityDpi)
+        val heightDp =
+            pxToDp(displayInfos[0].logicalHeight.toFloat(), displayInfos[0].logicalDensityDpi)
+        verify(mockTopology).addDisplay(displayInfos[0].displayId, widthDp, heightDp)
+        verify(mockTopologyChangedCallback).invoke(
+            android.util.Pair(
+                mockTopologyCopy,
+                mockTopologyGraph
+            )
+        )
+    }
+
+    @Test
+    fun addDisplay_overlay() {
+        displayInfos[0].type = Display.TYPE_OVERLAY
+        coordinator.onDisplayAdded(displayInfos[0])
+
+        val widthDp =
+            pxToDp(displayInfos[0].logicalWidth.toFloat(), displayInfos[0].logicalDensityDpi)
+        val heightDp =
+            pxToDp(displayInfos[0].logicalHeight.toFloat(), displayInfos[0].logicalDensityDpi)
+        verify(mockTopology).addDisplay(displayInfos[0].displayId, widthDp, heightDp)
+        verify(mockTopologyChangedCallback).invoke(
+            android.util.Pair(
+                mockTopologyCopy,
+                mockTopologyGraph
+            )
+        )
+    }
+
+    @Test
+    fun addDisplay_typeUnknown() {
+        displayInfos[0].type = Display.TYPE_UNKNOWN
+
+        coordinator.onDisplayAdded(displayInfos[0])
+
+        verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat())
+        verify(mockTopologyChangedCallback, never()).invoke(any())
+    }
+
+    @Test
+    fun addDisplay_wifi() {
+        displayInfos[0].type = Display.TYPE_WIFI
+
+        coordinator.onDisplayAdded(displayInfos[0])
+
+        verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat())
+        verify(mockTopologyChangedCallback, never()).invoke(any())
+    }
+
+    @Test
+    fun addDisplay_virtual() {
+        displayInfos[0].type = Display.TYPE_VIRTUAL
+
+        coordinator.onDisplayAdded(displayInfos[0])
+
+        verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat())
+        verify(mockTopologyChangedCallback, never()).invoke(any())
+    }
+
+    @Test
+    fun addDisplay_internal_nonDefault() {
+        displayInfos[0].displayId = 2
+        displayInfos[0].type = Display.TYPE_INTERNAL
+
+        coordinator.onDisplayAdded(displayInfos[0])
+
+        verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat())
+        verify(mockTopologyChangedCallback, never()).invoke(any())
+    }
+
+    @Test
+    fun addDisplay_external_extendedDisplaysDisabled() {
         whenever(mockIsExtendedDisplayEnabled()).thenReturn(false)
 
-        coordinator.onDisplayAdded(displayInfo)
+        for (displayInfo in displayInfos) {
+            coordinator.onDisplayAdded(displayInfo)
+        }
+
+        verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat())
+        verify(mockTopologyChangedCallback, never()).invoke(any())
+    }
+
+    @Test
+    fun addDisplay_overlay_extendedDisplaysDisabled() {
+        displayInfos[0].type = Display.TYPE_OVERLAY
+        whenever(mockIsExtendedDisplayEnabled()).thenReturn(false)
+
+        for (displayInfo in displayInfos) {
+            coordinator.onDisplayAdded(displayInfo)
+        }
 
         verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat())
         verify(mockTopologyChangedCallback, never()).invoke(any())
@@ -91,9 +221,9 @@
 
     @Test
     fun addDisplay_notInDefaultDisplayGroup() {
-        displayInfo.displayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1
+        displayInfos[0].displayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1
 
-        coordinator.onDisplayAdded(displayInfo)
+        coordinator.onDisplayAdded(displayInfos[0])
 
         verify(mockTopology, never()).addDisplay(anyInt(), anyFloat(), anyFloat())
         verify(mockTopologyChangedCallback, never()).invoke(any())
@@ -102,39 +232,164 @@
 
     @Test
     fun updateDisplay() {
-        whenever(mockTopology.updateDisplay(eq(Display.DEFAULT_DISPLAY), anyFloat(), anyFloat()))
+        whenever(mockTopology.updateDisplay(eq(displayInfos[0].displayId), anyFloat(), anyFloat()))
             .thenReturn(true)
+        addDisplay()
 
-        coordinator.onDisplayChanged(displayInfo)
+        displayInfos[0].logicalWidth += 100
+        displayInfos[0].logicalHeight += 100
+        coordinator.onDisplayChanged(displayInfos[0])
 
-        verify(mockTopologyChangedCallback).invoke(mockTopologyCopy)
+        val widthDp =
+            pxToDp(displayInfos[0].logicalWidth.toFloat(), displayInfos[0].logicalDensityDpi)
+        val heightDp =
+            pxToDp(displayInfos[0].logicalHeight.toFloat(), displayInfos[0].logicalDensityDpi)
+        verify(mockTopology).updateDisplay(displayInfos[0].displayId, widthDp, heightDp)
+
+        val captor = ArgumentCaptor.forClass(SparseIntArray::class.java)
+        verify(mockTopologyCopy).getGraph(captor.capture())
+        val densities = captor.value
+        assertThat(densities.size()).isEqualTo(displayInfos.size)
+        assertThat(densities.get(displayInfos[0].displayId))
+            .isEqualTo(displayInfos[0].logicalDensityDpi)
+
+        verify(mockTopologyChangedCallback).invoke(
+            android.util.Pair(
+                mockTopologyCopy,
+                mockTopologyGraph
+            )
+        )
     }
 
     @Test
     fun updateDisplay_notChanged() {
-        whenever(mockTopology.updateDisplay(eq(Display.DEFAULT_DISPLAY), anyFloat(), anyFloat()))
-            .thenReturn(false)
+        addDisplay()
 
-        coordinator.onDisplayChanged(displayInfo)
+        for (displayInfo in displayInfos) {
+            coordinator.onDisplayChanged(displayInfo)
+        }
 
+        // Try to update a display that does not exist
+        val info = DisplayInfo()
+        info.displayId = 100
+        coordinator.onDisplayChanged(info)
+
+        verify(mockTopologyCopy, never()).getGraph(any())
+        verify(mockTopologyChangedCallback, never()).invoke(any())
+    }
+
+    @Test
+    fun updateDisplay_typeUnknown() {
+        displayInfos[0].type = Display.TYPE_UNKNOWN
+
+        coordinator.onDisplayChanged(displayInfos[0])
+
+        verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat())
+        verify(mockTopologyCopy, never()).getGraph(any())
+        verify(mockTopologyChangedCallback, never()).invoke(any())
+    }
+
+    @Test
+    fun updateDisplay_wifi() {
+        displayInfos[0].type = Display.TYPE_WIFI
+
+        coordinator.onDisplayChanged(displayInfos[0])
+
+        verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat())
+        verify(mockTopologyCopy, never()).getGraph(any())
+        verify(mockTopologyChangedCallback, never()).invoke(any())
+    }
+
+    @Test
+    fun updateDisplay_virtual() {
+        displayInfos[0].type = Display.TYPE_VIRTUAL
+
+        coordinator.onDisplayChanged(displayInfos[0])
+
+        verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat())
+        verify(mockTopologyCopy, never()).getGraph(any())
+        verify(mockTopologyChangedCallback, never()).invoke(any())
+    }
+
+    @Test
+    fun updateDisplay_internal_nonDefault() {
+        displayInfos[0].displayId = 2
+        displayInfos[0].type = Display.TYPE_INTERNAL
+
+        coordinator.onDisplayChanged(displayInfos[0])
+
+        verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat())
+        verify(mockTopologyCopy, never()).getGraph(any())
+        verify(mockTopologyChangedCallback, never()).invoke(any())
+    }
+
+    @Test
+    fun updateDisplay_external_extendedDisplaysDisabled() {
+        whenever(mockIsExtendedDisplayEnabled()).thenReturn(false)
+
+        for (displayInfo in displayInfos) {
+            coordinator.onDisplayChanged(displayInfo)
+        }
+
+        verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat())
+        verify(mockTopologyCopy, never()).getGraph(any())
+        verify(mockTopologyChangedCallback, never()).invoke(any())
+    }
+
+    @Test
+    fun updateDisplay_overlay_extendedDisplaysDisabled() {
+        displayInfos[0].type = Display.TYPE_OVERLAY
+        whenever(mockIsExtendedDisplayEnabled()).thenReturn(false)
+
+        coordinator.onDisplayChanged(displayInfos[0])
+
+        verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat())
+        verify(mockTopologyChangedCallback, never()).invoke(any())
+        verify(mockTopologyStore, never()).restoreTopology(any())
+    }
+
+    @Test
+    fun updateDisplay_notInDefaultDisplayGroup() {
+        displayInfos[0].displayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1
+
+        coordinator.onDisplayChanged(displayInfos[0])
+
+        verify(mockTopology, never()).updateDisplay(anyInt(), anyFloat(), anyFloat())
+        verify(mockTopologyCopy, never()).getGraph(any())
         verify(mockTopologyChangedCallback, never()).invoke(any())
     }
 
     @Test
     fun removeDisplay() {
-        whenever(mockTopology.removeDisplay(Display.DEFAULT_DISPLAY)).thenReturn(true)
+        addDisplay()
 
-        coordinator.onDisplayRemoved(Display.DEFAULT_DISPLAY)
+        val displaysToRemove = listOf(0, 2, 3).map { displayInfos[it] }
+        for (displayInfo in displaysToRemove) {
+            whenever(mockTopology.removeDisplay(displayInfo.displayId)).thenReturn(true)
 
-        verify(mockTopologyChangedCallback).invoke(mockTopologyCopy)
-        verify(mockTopologyStore).restoreTopology(mockTopology)
+            coordinator.onDisplayRemoved(displayInfo.displayId)
+        }
+
+        val captor = ArgumentCaptor.forClass(SparseIntArray::class.java)
+        verify(mockTopologyCopy, times(displaysToRemove.size)).getGraph(captor.capture())
+        val densities = captor.value
+        assertThat(densities.size()).isEqualTo(displayInfos.size - displaysToRemove.size)
+        for (displayInfo in displaysToRemove) {
+            assertThat(densities.get(displayInfo.displayId)).isEqualTo(0)
+        }
+
+        verify(mockTopologyChangedCallback, times(displaysToRemove.size)).invoke(
+            android.util.Pair(
+                mockTopologyCopy,
+                mockTopologyGraph
+            )
+        )
+        verify(mockTopologyStore, times(displaysToRemove.size)).restoreTopology(mockTopology)
     }
 
     @Test
     fun removeDisplay_notChanged() {
-        whenever(mockTopology.removeDisplay(Display.DEFAULT_DISPLAY)).thenReturn(false)
-
-        coordinator.onDisplayRemoved(Display.DEFAULT_DISPLAY)
+        coordinator.onDisplayRemoved(100)
 
         verify(mockTopologyChangedCallback, never()).invoke(any())
         verify(mockTopologyStore, never()).restoreTopology(any())
@@ -149,12 +404,20 @@
     fun setTopology_normalize() {
         val topology = mock<DisplayTopology>()
         val topologyCopy = mock<DisplayTopology>()
+        val topologyGraph = mock<DisplayTopologyGraph>()
         whenever(topology.copy()).thenReturn(topologyCopy)
+        whenever(topologyCopy.getGraph(any())).thenReturn(topologyGraph)
         whenever(mockTopologyStore.saveTopology(topology)).thenReturn(true)
+
         coordinator.topology = topology
 
         verify(topology).normalize()
-        verify(mockTopologyChangedCallback).invoke(topologyCopy)
+        verify(mockTopologyChangedCallback).invoke(
+            android.util.Pair(
+                topologyCopy,
+                topologyGraph
+            )
+        )
         verify(mockTopologyStore).saveTopology(topology)
         verify(mockTopologySavedCallback).invoke()
     }
diff --git a/services/tests/displayservicetests/src/com/android/server/display/color/ColorDisplayServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/color/ColorDisplayServiceTest.java
index 4e81b35..22c10f9 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/color/ColorDisplayServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/color/ColorDisplayServiceTest.java
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -1194,6 +1195,66 @@
         verify(mRbcSpy, times(1)).setUp(eq(mContext), anyBoolean());
     }
 
+    @Test
+    public void sliderScalesWithinRange() {
+        // setup
+        startService();
+        reset(mRbcSpy);
+        doReturn(true).when(mRbcSpy).isAvailable(mContext);
+        when(mContext.getResources().getInteger(
+                R.integer.config_reduceBrightColorsStrengthMax)).thenReturn(85);
+        when(mContext.getResources().getInteger(
+                R.integer.config_reduceBrightColorsStrengthMin)).thenReturn(10);
+        when(mContext.getResources().getInteger(
+                R.integer.config_reduceBrightColorsStrengthDefault)).thenReturn(44);
+
+        // Valid value test //
+        // set on, and to 90% of range
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1);
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 90);
+        // update
+        mCds.mHandler.runWithScissors(
+                () -> mCds.onDisplayColorModeChanged(ColorDisplayManager.COLOR_MODE_NATURAL),
+                1000);
+        // verify this:
+        assertEquals(90, Settings.Secure.getInt(mContext.getContentResolver(),
+                        Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 0));
+        assertEquals(/* 85 - 10 * 0.90f + 10 = */ 77, mRbcSpy.getStrength());
+
+        // Out of range test //
+        // set on, and to 101% of range
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1);
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 101);
+        // update
+        mCds.mHandler.runWithScissors(
+                () -> mCds.onDisplayColorModeChanged(ColorDisplayManager.COLOR_MODE_NATURAL),
+                1000);
+        // verify this:
+        assertEquals(101, Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 0));
+        assertEquals(/* 85 - 10 * 1.0f + 10 = */ 85, mRbcSpy.getStrength());
+
+        // Invalid value test //
+        // set on, and to an invalid value
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1);
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, -1);
+        // update
+        mCds.mHandler.runWithScissors(
+                () -> mCds.onDisplayColorModeChanged(ColorDisplayManager.COLOR_MODE_NATURAL),
+                1000);
+        // verify this, setting will stay the same, strength should set to default?:
+        assertEquals(-1, Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 0));
+        // default value is set instead!
+        assertEquals(/* default = */ 44, mRbcSpy.getStrength());
+    }
+
     /**
      * Configures Night display to use a custom schedule.
      *
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 8dc657e..f79cb11 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -61,9 +61,12 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.StorageManager;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
+import android.telecom.TelecomManager;
 import android.util.Log;
 import android.util.Pair;
 import android.util.SparseArray;
@@ -141,6 +144,7 @@
             .spyStatic(ActivityManager.class)
             .mockStatic(Settings.Global.class)
             .mockStatic(Settings.Secure.class)
+            .mockStatic(Resources.class)
             .build();
 
     @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(
@@ -165,6 +169,7 @@
     private @Mock PackageManagerInternal mPackageManagerInternal;
     private @Mock KeyguardManager mKeyguardManager;
     private @Mock PowerManager mPowerManager;
+    private @Mock TelecomManager mTelecomManager;
 
     /**
      * Reference to the {@link UserManagerService} being tested.
@@ -191,6 +196,7 @@
         when(mSpiedContext.getSystemService(StorageManager.class)).thenReturn(mStorageManager);
         doReturn(mKeyguardManager).when(mSpiedContext).getSystemService(KeyguardManager.class);
         when(mSpiedContext.getSystemService(PowerManager.class)).thenReturn(mPowerManager);
+        when(mSpiedContext.getSystemService(TelecomManager.class)).thenReturn(mTelecomManager);
         mockGetLocalService(LockSettingsInternal.class, mLockSettingsInternal);
         mockGetLocalService(PackageManagerInternal.class, mPackageManagerInternal);
         doNothing().when(mSpiedContext).sendBroadcastAsUser(any(), any(), any());
@@ -202,6 +208,7 @@
         doReturn(0)
                 .when(mSpyResources)
                 .getInteger(com.android.internal.R.integer.config_hsumBootStrategy);
+        doReturn(mSpyResources).when(() -> Resources.getSystem());
 
         // Must construct UserManagerService in the UiThread
         mTestDir = new File(mRealContext.getDataDir(), "umstest");
@@ -883,9 +890,7 @@
                 .getInteger(com.android.internal.R.integer.config_hsumBootStrategy);
         // Even if the headless system user switchable flag is true, the boot user should be the
         // first switchable full user.
-        doReturn(true)
-                .when(mSpyResources)
-                .getBoolean(com.android.internal.R.bool.config_canSwitchToHeadlessSystemUser);
+        mockCanSwitchToHeadlessSystemUser(true);
 
         assertThat(mUms.getBootUser()).isEqualTo(USER_ID);
     }
@@ -904,6 +909,75 @@
                 () -> mUms.getBootUser());
     }
 
+    @Test
+    @EnableFlags(android.multiuser.Flags.FLAG_LOGOUT_USER_API)
+    public void testGetUserLogoutability_HsumAndInteractiveHeadlessSystem_UserCanLogout()
+            throws Exception {
+        setSystemUserHeadless(true);
+        addUser(USER_ID);
+        setLastForegroundTime(USER_ID, 1_000_000L);
+        mockCurrentUser(USER_ID);
+
+        mockCanSwitchToHeadlessSystemUser(true);
+        mockUserIsInCall(false);
+
+        assertThat(mUms.getUserLogoutability(USER_ID))
+                .isEqualTo(UserManager.LOGOUTABILITY_STATUS_OK);
+    }
+
+    @Test
+    @EnableFlags(android.multiuser.Flags.FLAG_LOGOUT_USER_API)
+    public void testGetUserLogoutability_HsumAndNonInteractiveHeadlessSystem_UserCannotLogout()
+            throws Exception {
+        setSystemUserHeadless(true);
+        mockCanSwitchToHeadlessSystemUser(false);
+        addUser(USER_ID);
+        setLastForegroundTime(USER_ID, 1_000_000L);
+        mockCurrentUser(USER_ID);
+        mockUserIsInCall(false);
+
+        assertThat(mUms.getUserLogoutability(USER_ID))
+                .isEqualTo(UserManager.LOGOUTABILITY_STATUS_NO_SUITABLE_USER_TO_LOGOUT_TO);
+    }
+
+    @Test
+    @EnableFlags(android.multiuser.Flags.FLAG_LOGOUT_USER_API)
+    public void testGetUserLogoutability_Hsum_SystemUserCannotLogout() throws Exception {
+        setSystemUserHeadless(true);
+        mockCurrentUser(UserHandle.USER_SYSTEM);
+        assertThat(mUms.getUserLogoutability(UserHandle.USER_SYSTEM))
+                .isEqualTo(UserManager.LOGOUTABILITY_STATUS_CANNOT_LOGOUT_SYSTEM_USER);
+    }
+
+    @Test
+    @EnableFlags(android.multiuser.Flags.FLAG_LOGOUT_USER_API)
+    public void testGetUserLogoutability_NonHsum_SystemUserCannotLogout() throws Exception {
+        setSystemUserHeadless(false);
+        mockCurrentUser(UserHandle.USER_SYSTEM);
+        assertThat(
+                mUms.getUserLogoutability(UserHandle.USER_SYSTEM)).isEqualTo(
+                UserManager.LOGOUTABILITY_STATUS_CANNOT_LOGOUT_SYSTEM_USER);
+    }
+
+    @Test
+    @EnableFlags(android.multiuser.Flags.FLAG_LOGOUT_USER_API)
+    public void testGetUserLogoutability_CannotSwitch_CannotLogout() throws Exception {
+        setSystemUserHeadless(true);
+        addUser(USER_ID);
+        addUser(OTHER_USER_ID);
+        setLastForegroundTime(OTHER_USER_ID, 1_000_000L);
+        mockCurrentUser(USER_ID);
+        mUms.setUserRestriction(DISALLOW_USER_SWITCH, true, USER_ID);
+        assertThat(mUms.getUserLogoutability(USER_ID))
+                .isEqualTo(UserManager.LOGOUTABILITY_STATUS_CANNOT_SWITCH);
+    }
+
+    @Test
+    @DisableFlags(android.multiuser.Flags.FLAG_LOGOUT_USER_API)
+    public void testGetUserLogoutability_LogoutDisabled() throws Exception {
+        assertThrows(UnsupportedOperationException.class, () -> mUms.getUserLogoutability(USER_ID));
+    }
+
     /**
      * Returns true if the user's XML file has Default restrictions
      * @param userId Id of the user.
@@ -1019,6 +1093,16 @@
         doReturn(service).when(() -> LocalServices.getService(serviceClass));
     }
 
+    private void mockCanSwitchToHeadlessSystemUser(boolean canSwitch) {
+        doReturn(canSwitch)
+                .when(mSpyResources)
+                .getBoolean(com.android.internal.R.bool.config_canSwitchToHeadlessSystemUser);
+    }
+
+    private void mockUserIsInCall(boolean isInCall) {
+        when(mTelecomManager.isInCall()).thenReturn(isInCall);
+    }
+
     private void addDefaultProfileAndParent() {
         addUser(PARENT_USER_ID);
         addProfile(PROFILE_USER_ID, PARENT_USER_ID);
@@ -1061,6 +1145,7 @@
     private void addUserData(TestUserData userData) {
         Log.d(TAG, "Adding " + userData);
         mUsers.put(userData.info.id, userData);
+        mUms.putUserInfo(userData.info);
     }
 
     private void setSystemUserHeadless(boolean headless) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
index d80fd20..ef77a0e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
@@ -1028,6 +1028,154 @@
     }
     // Verify a secondary display removes system decorations ended
 
+    // Test setWallpaperComponent on multiple displays.
+    // GIVEN 3 displays, 0, 2, 3, the new wallpaper is only compatible for display 0 and 3 but not
+    // 2.
+    // WHEN the new wallpaper is set for system and lock via setWallpaperComponent.
+    // THEN there are 2 connections in mLastWallpaper and 1 connection in mFallbackWallpaper.
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER)
+    public void setWallpaperComponent_multiDisplays_shouldHaveExpectedConnections() {
+        // Skip if there is no pre-defined default wallpaper component.
+        assumeThat(sDefaultWallpaperComponent,
+                not(CoreMatchers.equalTo(sImageWallpaperComponentName)));
+
+        final int testUserId = USER_SYSTEM;
+        mService.switchUser(testUserId, null);
+        final int incompatibleDisplayId = 2;
+        final int compatibleDisplayId = 3;
+        setUpDisplays(List.of(DEFAULT_DISPLAY, incompatibleDisplayId, compatibleDisplayId));
+        mService.removeWallpaperCompatibleDisplayForTest(incompatibleDisplayId);
+
+        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
+                FLAG_SYSTEM | FLAG_LOCK, testUserId);
+
+        verifyLastWallpaperData(testUserId, sImageWallpaperComponentName);
+        verifyCurrentSystemData(testUserId);
+        assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(2);
+        assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue();
+        assertThat(mService.mLastWallpaper.connection.containsDisplay(compatibleDisplayId))
+                .isTrue();
+        assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(1);
+        assertThat(mService.mFallbackWallpaper.connection.containsDisplay(incompatibleDisplayId))
+                .isTrue();
+        assertThat(mService.mLastLockWallpaper).isNull();
+    }
+
+    // Test setWallpaperComponent on multiple displays.
+    // GIVEN 3 displays, 0, 2, 3, the existing wallpaper is only compatible for display 0 and 3 but
+    // not 2.
+    // GIVEN the new wallpaper is compatible to 2.
+    // WHEN the new wallpaper is set for system and lock via setWallpaperComponent.
+    // THEN there are 3 connections in mLastWallpaper and 0 connection in mFallbackWallpaper.
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER)
+    public void setWallpaperComponent_multiDisplays_displayBecomeCompatible_shouldHaveExpectedConnections() {
+        // Skip if there is no pre-defined default wallpaper component.
+        assumeThat(sDefaultWallpaperComponent,
+                not(CoreMatchers.equalTo(sImageWallpaperComponentName)));
+
+        final int testUserId = USER_SYSTEM;
+        mService.switchUser(testUserId, null);
+        final int display2 = 2;
+        final int display3 = 3;
+        setUpDisplays(List.of(DEFAULT_DISPLAY, display2, display3));
+        mService.removeWallpaperCompatibleDisplayForTest(display2);
+        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
+                FLAG_SYSTEM | FLAG_LOCK, testUserId);
+
+        mService.addWallpaperCompatibleDisplayForTest(display2);
+        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
+                FLAG_SYSTEM | FLAG_LOCK, testUserId);
+
+        verifyLastWallpaperData(testUserId, sImageWallpaperComponentName);
+        verifyCurrentSystemData(testUserId);
+        assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(3);
+        assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue();
+        assertThat(mService.mLastWallpaper.connection.containsDisplay(display2)).isTrue();
+        assertThat(mService.mLastWallpaper.connection.containsDisplay(display3)).isTrue();
+        assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(0);
+        assertThat(mService.mLastLockWallpaper).isNull();
+    }
+
+    // Test setWallpaperComponent on multiple displays.
+    // GIVEN 3 displays, 0, 2, 3, the existing wallpaper is only compatible for display 0 and 3 but
+    // not 2.
+    // GIVEN the new wallpaper is incompatible to 2 and 3.
+    // WHEN the new wallpaper is set for system and lock via setWallpaperComponent.
+    // THEN there are 1 connections in mLastWallpaper and 2 connection in mFallbackWallpaper.
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER)
+    public void setWallpaperComponent_multiDisplays_displayBecomeIncompatible_shouldHaveExpectedConnections() {
+        // Skip if there is no pre-defined default wallpaper component.
+        assumeThat(sDefaultWallpaperComponent,
+                not(CoreMatchers.equalTo(sImageWallpaperComponentName)));
+
+        final int testUserId = USER_SYSTEM;
+        mService.switchUser(testUserId, null);
+        final int display2 = 2;
+        final int display3 = 3;
+        setUpDisplays(List.of(DEFAULT_DISPLAY, display2, display3));
+        mService.removeWallpaperCompatibleDisplayForTest(display2);
+        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
+                FLAG_SYSTEM | FLAG_LOCK, testUserId);
+
+        mService.removeWallpaperCompatibleDisplayForTest(display3);
+        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
+                FLAG_SYSTEM | FLAG_LOCK, testUserId);
+
+        verifyLastWallpaperData(testUserId, sImageWallpaperComponentName);
+        verifyCurrentSystemData(testUserId);
+        assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(1);
+        assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue();
+        assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(2);
+        assertThat(mService.mFallbackWallpaper.connection.containsDisplay(display2)).isTrue();
+        assertThat(mService.mFallbackWallpaper.connection.containsDisplay(display3)).isTrue();
+        assertThat(mService.mLastLockWallpaper).isNull();
+    }
+
+    // Test setWallpaperComponent on multiple displays.
+    // GIVEN 3 displays, 0, 2, 3, the new wallpaper is only compatible for display 0 and 3 but not
+    // 2.
+    // WHEN two different wallpapers set for system and lock via setWallpaperComponent.
+    // THEN there are two connections in mLastWallpaper, two connection in mLastLockWallpaper and
+    // one connection in mFallbackWallpaper.
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WALLPAPER)
+    public void setWallpaperComponent_systemAndLockWallpapers_multiDisplays_shouldHaveExpectedConnections() {
+        // Skip if there is no pre-defined default wallpaper component.
+        assumeThat(sDefaultWallpaperComponent,
+                not(CoreMatchers.equalTo(sImageWallpaperComponentName)));
+
+        final int testUserId = USER_SYSTEM;
+        mService.switchUser(testUserId, null);
+        final int incompatibleDisplayId = 2;
+        final int compatibleDisplayId = 3;
+        setUpDisplays(List.of(DEFAULT_DISPLAY, incompatibleDisplayId, compatibleDisplayId));
+        mService.removeWallpaperCompatibleDisplayForTest(incompatibleDisplayId);
+
+        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
+                FLAG_SYSTEM, testUserId);
+        mService.setWallpaperComponent(sImageWallpaperComponentName, sContext.getOpPackageName(),
+                FLAG_LOCK, testUserId);
+
+        verifyLastWallpaperData(testUserId, sImageWallpaperComponentName);
+        verifyLastLockWallpaperData(testUserId, sImageWallpaperComponentName);
+        verifyCurrentSystemData(testUserId);
+        assertThat(mService.mLastWallpaper.connection.getConnectedEngineSize()).isEqualTo(2);
+        assertThat(mService.mLastWallpaper.connection.containsDisplay(DEFAULT_DISPLAY)).isTrue();
+        assertThat(mService.mLastWallpaper.connection.containsDisplay(compatibleDisplayId))
+                .isTrue();
+        assertThat(mService.mLastLockWallpaper.connection.getConnectedEngineSize()).isEqualTo(2);
+        assertThat(mService.mLastLockWallpaper.connection.containsDisplay(DEFAULT_DISPLAY))
+                .isTrue();
+        assertThat(mService.mLastLockWallpaper.connection.containsDisplay(compatibleDisplayId))
+                .isTrue();
+        assertThat(mService.mFallbackWallpaper.connection.getConnectedEngineSize()).isEqualTo(1);
+        assertThat(mService.mFallbackWallpaper.connection.containsDisplay(incompatibleDisplayId))
+                .isTrue();
+    }
+
     // Verify that after continue switch user from userId 0 to lastUserId, the wallpaper data for
     // non-current user must not bind to wallpaper service.
     private void verifyNoConnectionBeforeLastUser(int lastUserId) {
diff --git a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
index 6b138b9..29a17e1 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -89,9 +89,13 @@
 import android.os.PowerManagerInternal;
 import android.os.PowerSaveState;
 import android.os.UserHandle;
+import android.os.WorkSource;
 import android.os.test.TestLooper;
 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;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
@@ -200,6 +204,9 @@
 
     @Rule public SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
     private PowerManagerService mService;
     private ContextWrapper mContextSpy;
     private BatteryReceiver mBatteryReceiver;
@@ -3045,6 +3052,40 @@
     }
 
     /**
+     * Test IPowerManager.updateWakeLockUids() updates the workchain with the new uids
+     */
+    @Test
+    @RequiresFlagsEnabled({Flags.FLAG_WAKELOCK_ATTRIBUTION_VIA_WORKCHAIN})
+    public void test_updateWakelockUids_updatesWorkchain() {
+        createService();
+        startSystem();
+        final String tag = "wakelock1";
+        final String packageName = "pkg.name";
+        final IBinder token = new Binder();
+        int flags = PowerManager.PARTIAL_WAKE_LOCK;
+        final IWakeLockCallback callback1 = Mockito.mock(IWakeLockCallback.class);
+        final IBinder callbackBinder1 = Mockito.mock(Binder.class);
+        when(callback1.asBinder()).thenReturn(callbackBinder1);
+        WorkSource oldWorksource = new WorkSource();
+        oldWorksource.createWorkChain().addNode(1000, null);
+        mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
+                oldWorksource, null /* historyTag */, Display.INVALID_DISPLAY, callback1);
+        verify(mNotifierMock).onWakeLockAcquired(anyInt(), eq(tag), eq(packageName),
+                anyInt(), anyInt(), eq(oldWorksource), any(), same(callback1));
+
+        WorkSource newWorksource = new WorkSource();
+        newWorksource.createWorkChain().addNode(1011, null)
+                .addNode(Binder.getCallingUid(), null);
+        newWorksource.createWorkChain().addNode(1012, null)
+                .addNode(Binder.getCallingUid(), null);
+        mService.getBinderServiceInstance().updateWakeLockUids(token, new int[]{1011, 1012});
+        verify(mNotifierMock).onWakeLockChanging(anyInt(), eq(tag), eq(packageName),
+                anyInt(), anyInt(), eq(oldWorksource), any(), any(),
+                anyInt(), eq(tag), eq(packageName), anyInt(), anyInt(), eq(newWorksource), any(),
+                any());
+    }
+
+    /**
      * Test IPowerManager.updateWakeLockCallback() with a new IWakeLockCallback.
      */
     @Test
diff --git a/services/tests/powerstatstests/res/raw/history_01 b/services/tests/powerstatstests/res/raw/history_01
new file mode 100644
index 0000000..f69eb27
--- /dev/null
+++ b/services/tests/powerstatstests/res/raw/history_01
Binary files differ
diff --git a/services/tests/powerstatstests/res/raw/history_02 b/services/tests/powerstatstests/res/raw/history_02
new file mode 100644
index 0000000..1a536ab
--- /dev/null
+++ b/services/tests/powerstatstests/res/raw/history_02
Binary files differ
diff --git a/services/tests/powerstatstests/res/raw/history_03 b/services/tests/powerstatstests/res/raw/history_03
new file mode 100644
index 0000000..76a3c7b
--- /dev/null
+++ b/services/tests/powerstatstests/res/raw/history_03
Binary files differ
diff --git a/services/tests/powerstatstests/res/raw/history_04 b/services/tests/powerstatstests/res/raw/history_04
new file mode 100644
index 0000000..7e43ac6
--- /dev/null
+++ b/services/tests/powerstatstests/res/raw/history_04
Binary files differ
diff --git a/services/tests/powerstatstests/res/raw/history_05 b/services/tests/powerstatstests/res/raw/history_05
new file mode 100644
index 0000000..b587723
--- /dev/null
+++ b/services/tests/powerstatstests/res/raw/history_05
Binary files differ
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryCompressionPerfTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryCompressionPerfTest.java
new file mode 100644
index 0000000..48e0daa
--- /dev/null
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryCompressionPerfTest.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.platform.test.annotations.LargeTest;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import libcore.io.Streams;
+
+import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
+import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
+import org.apache.commons.compress.compressors.deflate.DeflateCompressorInputStream;
+import org.apache.commons.compress.compressors.deflate.DeflateCompressorOutputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
+import org.apache.commons.compress.compressors.gzip.GzipParameters;
+import org.apache.commons.compress.compressors.lz4.BlockLZ4CompressorInputStream;
+import org.apache.commons.compress.compressors.lz4.BlockLZ4CompressorOutputStream;
+import org.apache.commons.compress.compressors.lz4.FramedLZ4CompressorInputStream;
+import org.apache.commons.compress.compressors.lz4.FramedLZ4CompressorOutputStream;
+import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
+import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+import java.util.zip.Deflater;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+@android.platform.test.annotations.DisabledOnRavenwood(reason = "Performance test")
+@Ignore("Performance experiment. Comment out @Ignore to run")
+public class BatteryStatsHistoryCompressionPerfTest {
+
+    @Rule
+    public final PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Rule
+    public final TestName mTestName = new TestName();
+
+    private final List<byte[]> mHistorySamples = new ArrayList<>();
+
+    @Before
+    public void loadHistorySamples() throws IOException {
+        Context context = InstrumentationRegistry.getContext();
+        Resources resources = context.getResources();
+
+        for (String sampleResource
+                : List.of("history_01", "history_02", "history_03", "history_04", "history_05")) {
+            int resId = resources.getIdentifier(sampleResource, "raw", context.getPackageName());
+            try (InputStream stream = resources.openRawResource(resId)) {
+                byte[] data = Streams.readFully(stream);
+                mHistorySamples.add(data);
+            }
+        }
+    }
+
+    private interface StreamWrapper<T> {
+        T wrap(T stream) throws IOException;
+    }
+
+    private static class CompressorTester implements BatteryHistoryDirectory.Compressor {
+        private final StreamWrapper<OutputStream> mCompressorSupplier;
+        private final StreamWrapper<InputStream> mUncompressorSupplier;
+        private final ByteArrayOutputStream mOutputStream = new ByteArrayOutputStream(200000);
+        private final Random mRandom = new Random();
+
+        private static class Sample {
+            public byte[] uncompressed;
+            public byte[] compressed;
+        }
+
+        private final List<Sample> mSamples;
+
+        CompressorTester(StreamWrapper<OutputStream> compressorSupplier,
+                StreamWrapper<InputStream> uncompressorSupplier,
+                List<byte[]> uncompressedSamples) throws IOException {
+            mCompressorSupplier = compressorSupplier;
+            mUncompressorSupplier = uncompressorSupplier;
+            mSamples = new ArrayList<>();
+            for (byte[] uncompressed : uncompressedSamples) {
+                Sample s = new Sample();
+                s.uncompressed = Arrays.copyOf(uncompressed, uncompressed.length);
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                compress(baos, s.uncompressed);
+                s.compressed = baos.toByteArray();
+                mSamples.add(s);
+            }
+        }
+
+        float getCompressionRatio() {
+            long totalUncompressed = 0;
+            long totalCompressed = 0;
+            for (Sample sample : mSamples) {
+                totalUncompressed += sample.uncompressed.length;
+                totalCompressed += sample.compressed.length;
+            }
+            return (float) totalUncompressed / totalCompressed;
+        }
+
+        void compressSample() throws IOException {
+            Sample sample = mSamples.get(mRandom.nextInt(mSamples.size()));
+            mOutputStream.reset();
+            compress(mOutputStream, sample.uncompressed);
+            // Absence of an exception indicates success
+        }
+
+        void uncompressSample() throws IOException {
+            Sample sample = mSamples.get(mRandom.nextInt(mSamples.size()));
+            uncompress(sample.uncompressed, new ByteArrayInputStream(sample.compressed));
+            // Absence of an exception indicates success
+        }
+
+        @Override
+        public void compress(OutputStream stream, byte[] data) throws IOException {
+            OutputStream cos = mCompressorSupplier.wrap(stream);
+            cos.write(data);
+            cos.close();
+        }
+
+        @Override
+        public void uncompress(byte[] data, InputStream stream) throws IOException {
+            InputStream cos = mUncompressorSupplier.wrap(stream);
+            readFully(data, cos);
+        }
+    }
+
+    private void benchmarkCompress(StreamWrapper<OutputStream> compressorSupplier)
+            throws IOException {
+        CompressorTester tester = new CompressorTester(compressorSupplier, null, mHistorySamples);
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            tester.compressSample();
+        }
+        Bundle status = new Bundle();
+        status.putFloat(mTestName.getMethodName() + "_compressionRatio",
+                tester.getCompressionRatio());
+        InstrumentationRegistry.getInstrumentation().sendStatus(Activity.RESULT_OK, status);
+    }
+
+    private void benchmarkUncompress(StreamWrapper<OutputStream> compressorSupplier,
+            StreamWrapper<InputStream> uncompressorSupplier) throws IOException {
+        CompressorTester tester = new CompressorTester(compressorSupplier, uncompressorSupplier,
+                mHistorySamples);
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            tester.uncompressSample();
+        }
+    }
+
+    @Test
+    public void block_lz4_compress() throws IOException {
+        benchmarkCompress(BlockLZ4CompressorOutputStream::new);
+    }
+
+    @Test
+    public void block_lz4_uncompress() throws IOException {
+        benchmarkUncompress(BlockLZ4CompressorOutputStream::new,
+                BlockLZ4CompressorInputStream::new);
+    }
+
+    @Test
+    public void framed_lz4_compress() throws IOException {
+        benchmarkCompress(FramedLZ4CompressorOutputStream::new);
+    }
+
+    @Test
+    public void framed_lz4_uncompress() throws IOException {
+        benchmarkUncompress(FramedLZ4CompressorOutputStream::new,
+                FramedLZ4CompressorInputStream::new);
+    }
+
+    @Test
+    public void gzip_compress() throws IOException {
+        benchmarkCompress(GzipCompressorOutputStream::new);
+    }
+
+    @Test
+    public void gzip_uncompress() throws IOException {
+        benchmarkUncompress(GzipCompressorOutputStream::new,
+                GzipCompressorInputStream::new);
+    }
+
+    @Test
+    public void best_speed_gzip_compress() throws IOException {
+        benchmarkCompress(stream -> {
+            GzipParameters parameters = new GzipParameters();
+            parameters.setCompressionLevel(Deflater.BEST_SPEED);
+            return new GzipCompressorOutputStream(stream, parameters);
+        });
+    }
+
+    @Test
+    public void best_speed_gzip_uncompress() throws IOException {
+        benchmarkUncompress(stream -> {
+            GzipParameters parameters = new GzipParameters();
+            parameters.setCompressionLevel(Deflater.BEST_SPEED);
+            return new GzipCompressorOutputStream(stream, parameters);
+        }, GzipCompressorInputStream::new);
+    }
+
+    @Test
+    public void java_util_gzip_compress() throws IOException {
+        benchmarkCompress(GZIPOutputStream::new);
+    }
+
+    @Test
+    public void java_util_gzip_uncompress() throws IOException {
+        benchmarkUncompress(GZIPOutputStream::new,
+                GZIPInputStream::new);
+    }
+
+    @Test
+    public void bzip2_compress() throws IOException {
+        benchmarkCompress(BZip2CompressorOutputStream::new);
+    }
+
+    @Test
+    public void bzip2_uncompress() throws IOException {
+        benchmarkUncompress(BZip2CompressorOutputStream::new,
+                BZip2CompressorInputStream::new);
+    }
+
+    @Test
+    public void xz_compress() throws IOException {
+        benchmarkCompress(XZCompressorOutputStream::new);
+    }
+
+    @Test
+    public void xz_uncompress() throws IOException {
+        benchmarkUncompress(XZCompressorOutputStream::new,
+                XZCompressorInputStream::new);
+    }
+
+    @Test
+    public void deflate_compress() throws IOException {
+        benchmarkCompress(DeflateCompressorOutputStream::new);
+    }
+
+    @Test
+    public void deflate_uncompress() throws IOException {
+        benchmarkUncompress(DeflateCompressorOutputStream::new,
+                DeflateCompressorInputStream::new);
+    }
+}
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
index 164eec6..8fad931 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
@@ -17,6 +17,7 @@
 package com.android.server.power.stats;
 
 import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -30,18 +31,20 @@
 import android.os.BatteryManager;
 import android.os.BatteryStats;
 import android.os.BatteryStats.HistoryItem;
+import android.os.ConditionVariable;
 import android.os.Parcel;
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.UserHandle;
 import android.platform.test.annotations.EnableFlags;
 import android.platform.test.flag.junit.SetFlagsRule;
+import android.platform.test.ravenwood.RavenwoodRule;
 import android.telephony.NetworkRegistrationInfo;
-import android.util.AtomicFile;
 import android.util.Log;
 
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.BatteryStatsHistory;
 import com.android.internal.os.BatteryStatsHistoryIterator;
 import com.android.internal.os.MonotonicClock;
@@ -58,6 +61,8 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.nio.file.Files;
@@ -85,6 +90,7 @@
     private File mHistoryDir;
     private final MockClock mClock = new MockClock();
     private final MonotonicClock mMonotonicClock = new MonotonicClock(0, mClock);
+    private BatteryHistoryDirectory mDirectory;
     private BatteryStatsHistory mHistory;
     private BatteryStats.HistoryPrinter mHistoryPrinter;
     @Mock
@@ -108,11 +114,30 @@
         }
         mHistoryDir.delete();
 
+
+        BatteryHistoryDirectory.Compressor compressor;
+        if (RavenwoodRule.isOnRavenwood()) {
+            compressor = new BatteryHistoryDirectory.Compressor() {
+                @Override
+                public void compress(OutputStream stream, byte[] data) throws IOException {
+                    stream.write(data);
+                }
+
+                @Override
+                public void uncompress(byte[] data, InputStream stream) throws IOException {
+                    readFully(data, stream);
+                }
+            };
+        } else {
+            compressor = BatteryHistoryDirectory.DEFAULT_COMPRESSOR;
+        }
+        mDirectory = new BatteryHistoryDirectory(mHistoryDir, 32768, compressor);
+
         mClock.realtime = 123;
         mClock.currentTime = 1743645660000L;    //  2025-04-03, 2:01:00 AM
 
-        mHistory = new BatteryStatsHistory(mHistoryBuffer, mSystemDir, 32768,
-                MAX_HISTORY_BUFFER_SIZE, mStepDetailsCalculator, mClock, mMonotonicClock, mTracer,
+        mHistory = new BatteryStatsHistory(mHistoryBuffer, MAX_HISTORY_BUFFER_SIZE, mDirectory,
+                mStepDetailsCalculator, mClock, mMonotonicClock, mTracer,
                 mEventLogger);
         mHistory.forceRecordAllHistory();
         mHistory.startRecordingHistory(mClock.realtime, mClock.uptime, false);
@@ -210,8 +235,9 @@
     }
 
     @Test
-    public void testStartNextFile() throws Exception {
+    public void testStartNextFile() {
         mHistory.forceRecordAllHistory();
+        mDirectory.setFileCompressionEnabled(false);
 
         mClock.realtime = 123;
 
@@ -225,7 +251,7 @@
             mClock.realtime = 1000 * i;
             fileList.add(mClock.realtime + ".bh");
 
-            mHistory.startNextFile(mClock.realtime);
+            mHistory.startNextFragment(mClock.realtime);
             createActiveFile(mHistory);
             fillActiveFile(mHistory);
 
@@ -235,8 +261,9 @@
 
         // create file 32
         mClock.realtime = 1000 * 32;
-        mHistory.startNextFile(mClock.realtime);
+        mHistory.startNextFragment(mClock.realtime);
         createActiveFile(mHistory);
+        fillActiveFile(mHistory);
         fileList.add("32000.bh");
         fileList.remove(0);
         // verify file 0 is deleted.
@@ -244,21 +271,22 @@
         verifyFileNames(mHistory, fileList);
         verifyActiveFile(mHistory, "32000.bh");
 
-        fillActiveFile(mHistory);
-
         // create file 33
         mClock.realtime = 1000 * 33;
-        mHistory.startNextFile(mClock.realtime);
+        mHistory.startNextFragment(mClock.realtime);
         createActiveFile(mHistory);
-        // verify file 1 is deleted
+        fillActiveFile(mHistory);
         fileList.add("33000.bh");
         fileList.remove(0);
+        mHistory.writeHistory();
+
+        // verify file 1 is deleted
         verifyFileDeleted("1000.bh");
         verifyFileNames(mHistory, fileList);
         verifyActiveFile(mHistory, "33000.bh");
 
         // create a new BatteryStatsHistory object, it will pick up existing history files.
-        BatteryStatsHistory history2 = new BatteryStatsHistory(mHistoryBuffer, mSystemDir, 32, 1024,
+        BatteryStatsHistory history2 = new BatteryStatsHistory(mHistoryBuffer, 1024, mDirectory,
                 null, mClock, mMonotonicClock, mTracer, mEventLogger);
         // verify constructor can pick up all files from file system.
         verifyFileNames(history2, fileList);
@@ -281,7 +309,7 @@
         // create file 1.
         mClock.realtime = 2345678;
 
-        history2.startNextFile(mClock.realtime);
+        history2.startNextFragment(mClock.realtime);
         createActiveFile(history2);
         verifyFileNames(history2, Arrays.asList("1234567.bh", "2345678.bh"));
         verifyActiveFile(history2, "2345678.bh");
@@ -297,10 +325,10 @@
         mHistory = spy(mHistory.copy());
 
         doAnswer(invocation -> {
-            AtomicFile file = invocation.getArgument(1);
-            mReadFiles.add(file.getBaseFile().getName());
+            BatteryHistoryDirectory.BatteryHistoryFile file = invocation.getArgument(1);
+            mReadFiles.add(file.atomicFile.getBaseFile().getName());
             return invocation.callRealMethod();
-        }).when(mHistory).readFileToParcel(any(), any());
+        }).when(mHistory).readFragmentToParcel(any(), any());
 
         // Prepare history for iteration
         mHistory.iterate(0, MonotonicClock.UNDEFINED);
@@ -339,10 +367,10 @@
         mHistory = spy(mHistory.copy());
 
         doAnswer(invocation -> {
-            AtomicFile file = invocation.getArgument(1);
-            mReadFiles.add(file.getBaseFile().getName());
+            BatteryHistoryDirectory.BatteryHistoryFile file = invocation.getArgument(1);
+            mReadFiles.add(file.atomicFile.getBaseFile().getName());
             return invocation.callRealMethod();
-        }).when(mHistory).readFileToParcel(any(), any());
+        }).when(mHistory).readFragmentToParcel(any(), any());
 
         // Prepare history for iteration
         mHistory.iterate(1000, 3000);
@@ -371,14 +399,14 @@
         mHistory.recordEvent(mClock.realtime, mClock.uptime,
                 BatteryStats.HistoryItem.EVENT_JOB_START, "job", 42);
 
-        mHistory.startNextFile(mClock.realtime);       // 1000.bh
+        mHistory.startNextFragment(mClock.realtime);       // 1000.bh
 
         mClock.realtime = 2000;
         mClock.uptime = 2000;
         mHistory.recordEvent(mClock.realtime, mClock.uptime,
                 BatteryStats.HistoryItem.EVENT_JOB_FINISH, "job", 42);
 
-        mHistory.startNextFile(mClock.realtime);       // 2000.bh
+        mHistory.startNextFragment(mClock.realtime);       // 2000.bh
 
         mClock.realtime = 3000;
         mClock.uptime = 3000;
@@ -386,30 +414,37 @@
                 HistoryItem.EVENT_ALARM, "alarm", 42);
 
         // Flush accumulated history to disk
-        mHistory.startNextFile(mClock.realtime);
+        mHistory.startNextFragment(mClock.realtime);
     }
 
     private void verifyActiveFile(BatteryStatsHistory history, String file) {
         final File expectedFile = new File(mHistoryDir, file);
-        assertEquals(expectedFile.getPath(), history.getActiveFile().getBaseFile().getPath());
+        assertEquals(expectedFile.getPath(),
+                ((BatteryHistoryDirectory.BatteryHistoryFile) history.getActiveFragment())
+                        .atomicFile.getBaseFile().getPath());
         assertTrue(expectedFile.exists());
     }
 
     private void verifyFileNames(BatteryStatsHistory history, List<String> fileList) {
-        assertEquals(fileList.size(), history.getFilesNames().size());
+        awaitCompletion();
+        List<String> fileNames =
+                ((BatteryHistoryDirectory) history.getBatteryHistoryStore()).getFileNames();
+        assertThat(fileNames).isEqualTo(fileList);
         for (int i = 0; i < fileList.size(); i++) {
-            assertEquals(fileList.get(i), history.getFilesNames().get(i));
             final File expectedFile = new File(mHistoryDir, fileList.get(i));
-            assertTrue(expectedFile.exists());
+            assertWithMessage("File does not exist " + expectedFile)
+                    .that(expectedFile.exists()).isTrue();
         }
     }
 
     private void verifyFileDeleted(String file) {
+        awaitCompletion();
         assertFalse(new File(mHistoryDir, file).exists());
     }
 
     private void createActiveFile(BatteryStatsHistory history) {
-        final File file = history.getActiveFile().getBaseFile();
+        File file = ((BatteryHistoryDirectory.BatteryHistoryFile) history.getActiveFragment())
+                .atomicFile.getBaseFile();
         if (file.exists()) {
             return;
         }
@@ -561,7 +596,7 @@
     public void largeTagPool() {
         // Keep the preserved part of history short - we only need to capture the very tail of
         // history.
-        mHistory = new BatteryStatsHistory(mHistoryBuffer, mSystemDir, 1, 6000,
+        mHistory = new BatteryStatsHistory(mHistoryBuffer, 6000, mDirectory,
                 mStepDetailsCalculator, mClock, mMonotonicClock, mTracer, mEventLogger);
 
         mHistory.forceRecordAllHistory();
@@ -699,7 +734,7 @@
         assertThat(size).isGreaterThan(lastHistorySize);
         lastHistorySize = size;
 
-        mHistory.startNextFile(mClock.realtime);
+        mHistory.startNextFragment(mClock.realtime);
 
         size = mHistory.getMonotonicHistorySize();
         assertThat(size).isEqualTo(lastHistorySize);
@@ -713,7 +748,7 @@
         assertThat(size).isGreaterThan(lastHistorySize);
         lastHistorySize = size;
 
-        mHistory.startNextFile(mClock.realtime);
+        mHistory.startNextFragment(mClock.realtime);
 
         mClock.realtime = 3000;
         mClock.uptime = 3000;
@@ -788,4 +823,58 @@
 
         parcel.recycle();
     }
+
+    @Test
+    public void compressHistoryFiles() {
+        // The first history file will be uncompressed
+        mDirectory.setFileCompressionEnabled(false);
+
+        mClock.realtime = 1000;
+        mClock.uptime = 1000;
+        mHistory.recordEvent(mClock.realtime, mClock.uptime,
+                BatteryStats.HistoryItem.EVENT_JOB_START, "job", 42);
+
+        mHistory.startNextFragment(mClock.realtime);
+
+        // The second file will be compressed
+        mDirectory.setFileCompressionEnabled(true);
+
+        mClock.realtime = 2000;
+        mClock.uptime = 2000;
+        mHistory.recordEvent(mClock.realtime, mClock.uptime,
+                BatteryStats.HistoryItem.EVENT_JOB_FINISH, "job", 42);
+
+        mHistory.startNextFragment(mClock.realtime);
+
+        awaitCompletion();
+
+        assertThat(historySummary(mHistory)).isEqualTo(List.of("+42:job", "-42:job"));
+
+        Parcel parcel = Parcel.obtain();
+        mHistory.writeToBatteryUsageStatsParcel(parcel, Long.MAX_VALUE);
+        parcel.setDataPosition(0);
+
+        BatteryStatsHistory actual = BatteryStatsHistory.createFromBatteryUsageStatsParcel(parcel);
+        assertThat(historySummary(actual)).isEqualTo(List.of("+42:job", "-42:job"));
+    }
+
+    private List<String> historySummary(BatteryStatsHistory history) {
+        List<String> events = new ArrayList<>();
+        try (BatteryStatsHistoryIterator it = history.iterate(0, Long.MAX_VALUE)) {
+            HistoryItem item;
+            while ((item = it.next()) != null) {
+                if ((item.eventCode & HistoryItem.EVENT_TYPE_MASK) == HistoryItem.EVENT_JOB) {
+                    events.add(((item.eventCode & HistoryItem.EVENT_FLAG_START) != 0 ? "+" : "-")
+                            + item.eventTag.uid + ":" + item.eventTag.string);
+                }
+            }
+        }
+        return events;
+    }
+
+    private static void awaitCompletion() {
+        ConditionVariable done = new ConditionVariable();
+        BackgroundThread.getHandler().post(done::open);
+        done.block();
+    }
 }
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
index e94ef5b..31ff50f 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
@@ -877,9 +877,19 @@
     }
 
     @Test
-    @EnableFlags(Flags.FLAG_EXTENDED_BATTERY_HISTORY_CONTINUOUS_COLLECTION_ENABLED)
+    @EnableFlags({
+            Flags.FLAG_EXTENDED_BATTERY_HISTORY_CONTINUOUS_COLLECTION_ENABLED,
+            Flags.FLAG_EXTENDED_BATTERY_HISTORY_COMPRESSION_ENABLED
+    })
     public void testIncludeSubsetOfHistory() throws IOException {
         MockBatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
+        BatteryHistoryDirectory store =
+                (BatteryHistoryDirectory) batteryStats.getHistory().getBatteryHistoryStore();
+        store.setFileCompressionEnabled(true);
+        // Make history fragment size predictable. Without this protection, holding the history
+        // directory lock in the background would prevent new fragments from being created.
+        store.makeDirectoryLockUnconditional();
+
         batteryStats.getHistory().setMaxHistoryBufferSize(100);
         synchronized (batteryStats) {
             batteryStats.setRecordAllHistoryLocked(true);
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
index a69e2fd..c7a19ce 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
@@ -41,6 +41,9 @@
 import com.android.internal.power.EnergyConsumerStats;
 
 import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Queue;
@@ -49,6 +52,18 @@
  * Mocks a BatteryStatsImpl object.
  */
 public class MockBatteryStatsImpl extends BatteryStatsImpl {
+    public static final BatteryHistoryDirectory.Compressor PASS_THROUGH_COMPRESSOR =
+            new BatteryHistoryDirectory.Compressor() {
+                @Override
+                public void compress(OutputStream stream, byte[] data) throws IOException {
+                    stream.write(data);
+                }
+
+                @Override
+                public void uncompress(byte[] data, InputStream stream) throws IOException {
+                    readFully(data, stream);
+                }
+            };
     public boolean mForceOnBattery;
     // The mNetworkStats will be used for both wifi and mobile categories
     private NetworkStats mNetworkStats;
@@ -83,7 +98,11 @@
     MockBatteryStatsImpl(BatteryStatsConfig config, Clock clock, MonotonicClock monotonicClock,
             File historyDirectory, Handler handler, PowerProfile powerProfile,
             PowerStatsUidResolver powerStatsUidResolver) {
-        super(config, clock, monotonicClock, historyDirectory, handler,
+        super(config, clock, monotonicClock, historyDirectory,
+                historyDirectory != null ? new BatteryHistoryDirectory(
+                        new File(historyDirectory, "battery-history"),
+                        config.getMaxHistorySizeBytes(), PASS_THROUGH_COMPRESSOR) : null,
+                handler,
                 mock(PlatformIdleStateCallback.class), mock(EnergyStatsRetriever.class),
                 mock(UserInfoProvider.class), powerProfile,
                 new CpuScalingPolicies(new SparseArray<>(), new SparseArray<>()),
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockStatsFrameworkEventsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockStatsFrameworkEventsTest.java
index 1fe3f58..f24e9ef 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockStatsFrameworkEventsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockStatsFrameworkEventsTest.java
@@ -186,14 +186,16 @@
     public void wakelockOpen() throws Exception {
         mEvents.noteStartWakeLock(UID_1, TAG_1, WAKELOCK_TYPE_1, TS_1);
 
-        ArrayList<WakelockInfo> info = pullResults(TS_3);
+        for (int i = 0; i < 5; i++) {
+            ArrayList<WakelockInfo> info = pullResults(TS_3);
 
-        assertEquals("size", 1, info.size());
-        assertEquals("uid", UID_1, info.get(0).uid);
-        assertEquals("tag", TAG_1, info.get(0).tag);
-        assertEquals("type", WAKELOCK_TYPE_1, info.get(0).type);
-        assertEquals("duration", TS_3 - TS_1, info.get(0).uptimeMillis);
-        assertEquals("count", 0, info.get(0).completedCount);
+            assertEquals("size", 1, info.size());
+            assertEquals("uid", UID_1, info.get(0).uid);
+            assertEquals("tag", TAG_1, info.get(0).tag);
+            assertEquals("type", WAKELOCK_TYPE_1, info.get(0).type);
+            assertEquals("duration", TS_3 - TS_1, info.get(0).uptimeMillis);
+            assertEquals("count", 0, info.get(0).completedCount);
+        }
     }
 
     @Test
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsAggregatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsAggregatorTest.java
index 3bdbcb5..73d491c 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsAggregatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsAggregatorTest.java
@@ -59,7 +59,7 @@
 
     @Before
     public void setup() throws ParseException {
-        mHistory = new BatteryStatsHistory(null, null, 0, 1024,
+        mHistory = new BatteryStatsHistory(null, 1024, null,
                 mock(BatteryStatsHistory.HistoryStepDetailsCalculator.class), mClock,
                 mMonotonicClock, mock(BatteryStatsHistory.TraceDelegate.class), null);
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java
index d243f92..9ef58cc 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java
@@ -42,6 +42,7 @@
 import com.android.internal.os.MonotonicClock;
 import com.android.internal.os.PowerProfile;
 import com.android.internal.os.PowerStats;
+import com.android.server.power.stats.BatteryHistoryDirectory;
 import com.android.server.power.stats.BatteryUsageStatsRule;
 import com.android.server.power.stats.MockClock;
 import com.android.server.power.stats.PowerStatsStore;
@@ -84,6 +85,7 @@
     private PowerStatsStore mPowerStatsStore;
     private PowerStatsAggregator mPowerStatsAggregator;
     private MultiStatePowerAttributor mPowerAttributor;
+    private BatteryHistoryDirectory mDirectory;
     private BatteryStatsHistory mHistory;
     private CpuPowerStatsLayout mCpuStatsArrayLayout;
     private PowerStats.Descriptor mPowerStatsDescriptor;
@@ -117,7 +119,8 @@
                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE);
 
         mPowerStatsStore = new PowerStatsStore(storeDirectory, new TestHandler());
-        mHistory = new BatteryStatsHistory(Parcel.obtain(), storeDirectory, 0, 10000,
+        mDirectory = new BatteryHistoryDirectory(storeDirectory, 0);
+        mHistory = new BatteryStatsHistory(Parcel.obtain(), 10000, mDirectory,
                 mock(BatteryStatsHistory.HistoryStepDetailsCalculator.class), mClock,
                 mMonotonicClock, null, null);
         mPowerStatsAggregator = new PowerStatsAggregator(config);
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/WakelockPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/WakelockPowerStatsProcessorTest.java
index ed3cda0..8257d71 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/WakelockPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/WakelockPowerStatsProcessorTest.java
@@ -87,7 +87,7 @@
         PowerStats ps = new PowerStats(descriptor);
         long[] uidStats = new long[descriptor.uidStatsArrayLength];
 
-        BatteryStatsHistory history = new BatteryStatsHistory(null, null, 0, 10000,
+        BatteryStatsHistory history = new BatteryStatsHistory(null, 10000, null,
                 mock(BatteryStatsHistory.HistoryStepDetailsCalculator.class),
                 mStatsRule.getMockClock(),
                 new MonotonicClock(START_TIME, mStatsRule.getMockClock()), null, null);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java
index f02bdae..457fde8d 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java
@@ -20,11 +20,11 @@
 
 import static com.android.server.testutils.MockitoUtilsKt.eq;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertNotNull;
-import static org.testng.AssertJUnit.assertNull;
 
 import android.content.Context;
 import android.platform.test.annotations.DisableFlags;
@@ -35,6 +35,7 @@
 import android.testing.TestableContext;
 import android.testing.TestableLooper;
 import android.view.InputDevice;
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
@@ -82,69 +83,89 @@
 
     @Test
     public void onMotionEvent_lazyInitClickScheduler() {
-        assertNull(mController.mClickScheduler);
+        assertThat(mController.mClickScheduler).isNull();
 
         injectFakeMouseActionDownEvent();
 
-        assertNotNull(mController.mClickScheduler);
+        assertThat(mController.mClickScheduler).isNotNull();
     }
 
     @Test
     public void onMotionEvent_nonMouseSource_notInitClickScheduler() {
-        assertNull(mController.mClickScheduler);
+        assertThat(mController.mClickScheduler).isNull();
 
         injectFakeNonMouseActionDownEvent();
 
-        assertNull(mController.mClickScheduler);
+        assertThat(mController.mClickScheduler).isNull();
     }
 
     @Test
     public void onMotionEvent_lazyInitAutoclickSettingsObserver() {
-        assertNull(mController.mAutoclickSettingsObserver);
+        assertThat(mController.mAutoclickSettingsObserver).isNull();
 
         injectFakeMouseActionDownEvent();
 
-        assertNotNull(mController.mAutoclickSettingsObserver);
+        assertThat(mController.mAutoclickSettingsObserver).isNotNull();
     }
 
     @Test
     @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR)
     public void onMotionEvent_flagOn_lazyInitAutoclickIndicatorScheduler() {
-        assertNull(mController.mAutoclickIndicatorScheduler);
+        assertThat(mController.mAutoclickIndicatorScheduler).isNull();
 
         injectFakeMouseActionDownEvent();
 
-        assertNotNull(mController.mAutoclickIndicatorScheduler);
+        assertThat(mController.mAutoclickIndicatorScheduler).isNotNull();
     }
 
     @Test
     @DisableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR)
     public void onMotionEvent_flagOff_notInitAutoclickIndicatorScheduler() {
-        assertNull(mController.mAutoclickIndicatorScheduler);
+        assertThat(mController.mAutoclickIndicatorScheduler).isNull();
 
         injectFakeMouseActionDownEvent();
 
-        assertNull(mController.mAutoclickIndicatorScheduler);
+        assertThat(mController.mAutoclickIndicatorScheduler).isNull();
     }
 
     @Test
     @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR)
     public void onMotionEvent_flagOn_lazyInitAutoclickIndicatorView() {
-        assertNull(mController.mAutoclickIndicatorView);
+        assertThat(mController.mAutoclickIndicatorView).isNull();
 
         injectFakeMouseActionDownEvent();
 
-        assertNotNull(mController.mAutoclickIndicatorView);
+        assertThat(mController.mAutoclickIndicatorView).isNotNull();
     }
 
     @Test
     @DisableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR)
     public void onMotionEvent_flagOff_notInitAutoclickIndicatorView() {
-        assertNull(mController.mAutoclickIndicatorView);
+        assertThat(mController.mAutoclickIndicatorView).isNull();
 
         injectFakeMouseActionDownEvent();
 
-        assertNull(mController.mAutoclickIndicatorView);
+        assertThat(mController.mAutoclickIndicatorView).isNull();
+    }
+
+    @Test
+    @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR)
+    public void onMotionEvent_flagOn_lazyInitAutoclickTypePanelView() {
+        assertThat(mController.mAutoclickTypePanel).isNull();
+
+        injectFakeMouseActionDownEvent();
+
+        assertThat(mController.mAutoclickTypePanel).isNotNull();
+    }
+
+    @Test
+    @DisableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR)
+    public void onMotionEvent_flagOff_notInitAutoclickTypePanelView() {
+        assertThat(mController.mAutoclickTypePanel).isNull();
+
+        injectFakeMouseActionDownEvent();
+
+        assertThat(mController.mAutoclickTypePanel).isNull();
     }
 
     @Test
@@ -166,6 +187,18 @@
     }
 
     @Test
+    @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR)
+    public void onDestroy_flagOn_removeAutoclickTypePanelViewToWindowManager() {
+        injectFakeMouseActionDownEvent();
+        AutoclickTypePanel mockAutoclickTypePanel = mock(AutoclickTypePanel.class);
+        mController.mAutoclickTypePanel = mockAutoclickTypePanel;
+
+        mController.onDestroy();
+
+        verify(mockAutoclickTypePanel).hide();
+    }
+
+    @Test
     public void onMotionEvent_initClickSchedulerDelayFromSetting() {
         injectFakeMouseActionDownEvent();
 
@@ -175,7 +208,7 @@
                         Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY,
                         AccessibilityManager.AUTOCLICK_DELAY_DEFAULT,
                         mTestableContext.getUserId());
-        assertEquals(delay, mController.mClickScheduler.getDelayForTesting());
+        assertThat(mController.mClickScheduler.getDelayForTesting()).isEqualTo(delay);
     }
 
     @Test
@@ -189,7 +222,40 @@
                         Settings.Secure.ACCESSIBILITY_AUTOCLICK_CURSOR_AREA_SIZE,
                         AccessibilityManager.AUTOCLICK_CURSOR_AREA_SIZE_DEFAULT,
                         mTestableContext.getUserId());
-        assertEquals(size, mController.mAutoclickIndicatorView.getRadiusForTesting());
+        assertThat(mController.mAutoclickIndicatorView.getRadiusForTesting()).isEqualTo(size);
+    }
+
+    @Test
+    @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR)
+    public void onKeyEvent_modifierKey_doNotUpdateMetaStateWhenControllerIsNull() {
+        assertThat(mController.mClickScheduler).isNull();
+
+        injectFakeKeyEvent(KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.META_ALT_ON);
+
+        assertThat(mController.mClickScheduler).isNull();
+    }
+
+    @Test
+    @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR)
+    public void onKeyEvent_modifierKey_updateMetaStateWhenControllerNotNull() {
+        injectFakeMouseActionDownEvent();
+
+        int metaState = KeyEvent.META_ALT_ON | KeyEvent.META_META_ON;
+        injectFakeKeyEvent(KeyEvent.KEYCODE_ALT_LEFT, metaState);
+
+        assertThat(mController.mClickScheduler).isNotNull();
+        assertThat(mController.mClickScheduler.getMetaStateForTesting()).isEqualTo(metaState);
+    }
+
+    @Test
+    @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR)
+    public void onKeyEvent_modifierKey_cancelAutoClickWhenAdditionalRegularKeyPresssed() {
+        injectFakeMouseActionDownEvent();
+
+        injectFakeKeyEvent(KeyEvent.KEYCODE_J, KeyEvent.META_ALT_ON);
+
+        assertThat(mController.mClickScheduler).isNotNull();
+        assertThat(mController.mClickScheduler.getMetaStateForTesting()).isEqualTo(0);
     }
 
     @Test
@@ -198,7 +264,7 @@
 
         mController.onDestroy();
 
-        assertNull(mController.mClickScheduler);
+        assertThat(mController.mClickScheduler).isNull();
     }
 
     @Test
@@ -207,7 +273,7 @@
 
         mController.onDestroy();
 
-        assertNull(mController.mAutoclickSettingsObserver);
+        assertThat(mController.mAutoclickSettingsObserver).isNull();
     }
 
     @Test
@@ -217,7 +283,7 @@
 
         mController.onDestroy();
 
-        assertNull(mController.mAutoclickIndicatorScheduler);
+        assertThat(mController.mAutoclickIndicatorScheduler).isNull();
     }
 
     private void injectFakeMouseActionDownEvent() {
@@ -232,6 +298,17 @@
         mController.onMotionEvent(event, event, /* policyFlags= */ 0);
     }
 
+    private void injectFakeKeyEvent(int keyCode, int modifiers) {
+        KeyEvent keyEvent = new KeyEvent(
+                /* downTime= */ 0,
+                /* eventTime= */ 0,
+                /* action= */ KeyEvent.ACTION_DOWN,
+                /* code= */ keyCode,
+                /* repeat= */ 0,
+                /* metaState= */ modifiers);
+        mController.onKeyEvent(keyEvent, /* policyFlags= */ 0);
+    }
+
     private MotionEvent getFakeMotionDownEvent() {
         return MotionEvent.obtain(
                 /* downTime= */ 0,
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 06958b8..1627f68 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -25,6 +25,7 @@
 import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
 import static android.app.ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE;
 import static android.app.ActivityManagerInternal.ALLOW_PROFILES_OR_NON_FULL;
+import static android.app.KeyguardManager.LOCK_ON_USER_SWITCH_CALLBACK;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader;
 
@@ -115,7 +116,6 @@
 import com.android.server.pm.UserManagerService;
 import com.android.server.pm.UserTypeDetails;
 import com.android.server.pm.UserTypeFactory;
-import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.WindowManagerService;
 
 import com.google.common.collect.Range;
@@ -1563,11 +1563,11 @@
         // and the thread is still alive
         assertTrue(threadStartUser.isAlive());
 
-        // mock send the keyguard shown event
-        ArgumentCaptor<ActivityTaskManagerInternal.ScreenObserver> captor = ArgumentCaptor.forClass(
-                ActivityTaskManagerInternal.ScreenObserver.class);
-        verify(mInjector.mActivityTaskManagerInternal).registerScreenObserver(captor.capture());
-        captor.getValue().onKeyguardStateChanged(true);
+        // mock the binder response for the user switch completion
+        ArgumentCaptor<Bundle> captor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mInjector.mWindowManagerMock).lockNow(captor.capture());
+        IRemoteCallback.Stub.asInterface(captor.getValue().getBinder(
+                LOCK_ON_USER_SWITCH_CALLBACK)).sendResult(null);
 
         // verify the switch now moves on...
         Thread.sleep(1000);
@@ -1757,7 +1757,6 @@
         private final IStorageManager mStorageManagerMock;
         private final UserManagerInternal mUserManagerInternalMock;
         private final WindowManagerService mWindowManagerMock;
-        private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
         private final PowerManagerInternal mPowerManagerInternal;
         private final AlarmManagerInternal mAlarmManagerInternal;
         private final KeyguardManager mKeyguardManagerMock;
@@ -1779,7 +1778,6 @@
             mUserManagerMock = mock(UserManagerService.class);
             mUserManagerInternalMock = mock(UserManagerInternal.class);
             mWindowManagerMock = mock(WindowManagerService.class);
-            mActivityTaskManagerInternal = mock(ActivityTaskManagerInternal.class);
             mStorageManagerMock = mock(IStorageManager.class);
             mPowerManagerInternal = mock(PowerManagerInternal.class);
             mAlarmManagerInternal = mock(AlarmManagerInternal.class);
@@ -1843,11 +1841,6 @@
         }
 
         @Override
-        ActivityTaskManagerInternal getActivityTaskManagerInternal() {
-            return mActivityTaskManagerInternal;
-        }
-
-        @Override
         PowerManagerInternal getPowerManagerInternal() {
             return mPowerManagerInternal;
         }
diff --git a/services/tests/servicestests/src/com/android/server/audio/VolumeHelperTest.java b/services/tests/servicestests/src/com/android/server/audio/VolumeHelperTest.java
index 0bbae24..2d81f72 100644
--- a/services/tests/servicestests/src/com/android/server/audio/VolumeHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/VolumeHelperTest.java
@@ -117,6 +117,12 @@
     /** Choose a default stream volume value which does not depend on min/max. */
     private static final int DEFAULT_STREAM_VOLUME = 2;
 
+    /**
+     * The default ringer mode affected stream value since the ringer mode delegate is not used
+     * for unit testing.
+     */
+    private static final int DEFAULT_RINGER_MODE_AFFECTED_STREAMS = 0x1a6;
+
     @Rule
     public final MockitoRule mockito = MockitoJUnit.rule();
 
@@ -186,6 +192,10 @@
         public void setMuteAffectedStreams(int muteAffectedStreams) {
             mMuteAffectedStreams = muteAffectedStreams;
         }
+
+        public void setRingerModeAffectedStreams(int ringerModeAffectedStreams) {
+            mRingerModeAffectedStreams = ringerModeAffectedStreams;
+        }
     }
 
     private static class TestDeviceVolumeBehaviorDispatcherStub
@@ -550,6 +560,48 @@
         assertEquals(RINGER_MODE_VIBRATE, mAudioService.getRingerModeInternal());
     }
 
+    @Test
+    public void setStreamVolume_doesNotUnmuteStreamAffectedByRingerMode() throws Exception {
+        assumeFalse("Skipping ringer mode test on automotive", mIsAutomotive);
+        mAudioService.setRingerModeAffectedStreams(DEFAULT_RINGER_MODE_AFFECTED_STREAMS);
+        mAudioService.setRingerModeInternal(RINGER_MODE_VIBRATE, mContext.getOpPackageName());
+
+        mAudioService.setStreamVolume(STREAM_NOTIFICATION, /*index=*/1, /*flags=*/0,
+                mContext.getOpPackageName());
+        mTestLooper.dispatchAll();
+
+        assertEquals(0, mAudioService.getStreamVolume(STREAM_NOTIFICATION));
+    }
+
+    @Test
+    public void adjustUnmuteStreamVolume_doesNotUnmuteStreamAffectedByRingerMode()
+            throws Exception {
+        assumeFalse("Skipping ringer mode test on automotive", mIsAutomotive);
+        mAudioService.setRingerModeAffectedStreams(DEFAULT_RINGER_MODE_AFFECTED_STREAMS);
+        mAudioService.setRingerModeInternal(RINGER_MODE_VIBRATE, mContext.getOpPackageName());
+
+        mAudioService.adjustStreamVolume(STREAM_NOTIFICATION, ADJUST_UNMUTE, /*flags=*/0,
+                mContext.getOpPackageName());
+        mTestLooper.dispatchAll();
+
+        assertEquals(0, mAudioService.getStreamVolume(STREAM_NOTIFICATION));
+    }
+
+    @Test
+    public void adjustRaiseStreamVolume_doesNotUnmuteStreamAffectedByRingerMode()
+            throws Exception {
+        assumeFalse("Skipping ringer mode test on automotive", mIsAutomotive);
+        mAudioService.setRingerModeAffectedStreams(DEFAULT_RINGER_MODE_AFFECTED_STREAMS);
+        mAudioService.setRingerModeInternal(RINGER_MODE_VIBRATE, mContext.getOpPackageName());
+
+        mAudioService.adjustStreamVolume(STREAM_NOTIFICATION, ADJUST_RAISE, /*flags=*/0,
+                mContext.getOpPackageName());
+        mTestLooper.dispatchAll();
+
+        assertEquals(0, mAudioService.getStreamVolume(STREAM_NOTIFICATION));
+    }
+
+
     // --------------------- Permission tests ---------------------
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
index 6d86301..fcde405 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
@@ -16,12 +16,15 @@
 
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 import static com.android.server.hdmi.Constants.ADDR_TV;
 import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.Mockito.spy;
 
 import android.annotation.RequiresPermission;
@@ -60,6 +63,9 @@
 
     @Before
     public void setUp() throws Exception {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
 
         FakeAudioFramework audioFramework = new FakeAudioFramework();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
index a5f7bb1..9a6a24c 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
@@ -15,11 +15,14 @@
  */
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.Mockito.spy;
 
 import android.annotation.RequiresPermission;
@@ -59,6 +62,9 @@
 
     @Before
     public void setUp() throws Exception {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
 
         FakeAudioFramework audioFramework = new FakeAudioFramework();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
index 857ee1a..ee2f176 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
@@ -15,11 +15,14 @@
  */
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.Mockito.spy;
 
 import android.annotation.RequiresPermission;
@@ -64,6 +67,9 @@
 
     @Before
     public void setUp() throws Exception {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         MockitoAnnotations.initMocks(this);
 
         mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java
index 2296911..40f9dbc 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java
@@ -16,12 +16,15 @@
 
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
 import static com.android.server.hdmi.Constants.ADDR_TV;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
@@ -73,6 +76,9 @@
 
     @Before
     public void setUp() throws Exception {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         MockitoAnnotations.initMocks(this);
 
         mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java
index 47cfa42..461e98b 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromPlaybackTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
 import static android.hardware.hdmi.HdmiControlManager.POWER_STATUS_ON;
 import static android.hardware.hdmi.HdmiControlManager.POWER_STATUS_STANDBY;
 import static android.hardware.hdmi.HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON;
@@ -30,6 +31,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
+
 import android.annotation.RequiresPermission;
 import android.content.Context;
 import android.content.Intent;
@@ -94,6 +97,9 @@
 
     @Before
     public void setUp() {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         MockitoAnnotations.initMocks(this);
 
         Context context = InstrumentationRegistry.getTargetContext();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java
index 792faab..a4c71bd 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
 import static android.hardware.hdmi.HdmiControlManager.POWER_STATUS_ON;
 import static android.hardware.hdmi.HdmiControlManager.POWER_STATUS_STANDBY;
 import static android.hardware.hdmi.HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON;
@@ -30,6 +31,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
+
 import android.annotation.RequiresPermission;
 import android.content.Context;
 import android.content.Intent;
@@ -106,6 +109,9 @@
 
     @Before
     public void setUp() {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         Context context = InstrumentationRegistry.getTargetContext();
         mMyLooper = mTestLooper.getLooper();
 
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
index 30dac9f..0e9f219 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
@@ -15,12 +15,15 @@
  */
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.SystemService.PHASE_BOOT_COMPLETED;
 import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
 import static com.android.server.hdmi.Constants.ADDR_TV;
 import static com.android.server.hdmi.Constants.PATH_RELATIONSHIP_ANCESTOR;
 import static com.android.server.hdmi.HdmiControlService.WAKE_UP_SCREEN_ON;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -92,6 +95,9 @@
 
     @Before
     public void setUp() throws RemoteException {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         mHdmiCecAtomWriterSpy = spy(new HdmiCecAtomWriter());
 
         mLooper = mTestLooper.getLooper();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTvTest.java
index e1e101f..a0e21ed 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTvTest.java
@@ -15,10 +15,13 @@
  */
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_EARC_PENDING;
 import static com.android.server.hdmi.Constants.HDMI_EARC_STATUS_UNKNOWN;
 import static com.android.server.hdmi.HdmiControlService.WAKE_UP_SCREEN_ON;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -78,6 +81,9 @@
 
     @Before
     public void setUp() throws RemoteException {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         mHdmiCecAtomWriterSpy = spy(new HdmiCecAtomWriter());
 
         mLooper = mTestLooper.getLooper();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
index d8c58a8..e660267 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
@@ -15,10 +15,13 @@
  */
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static junit.framework.Assert.assertTrue;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -65,6 +68,9 @@
 
     @Before
     public void setUp() throws Exception {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         MockitoAnnotations.initMocks(this);
         mContext = FakeHdmiCecConfig.buildContext(InstrumentationRegistry.getTargetContext());
     }
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index 4f55111..314fe05 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
 import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
@@ -26,6 +28,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
+
 import android.annotation.RequiresPermission;
 import android.content.Context;
 import android.content.Intent;
@@ -85,6 +89,9 @@
 
     @Before
     public void setUp() {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         Context context = InstrumentationRegistry.getTargetContext();
         mMyLooper = mTestLooper.getLooper();
         mLocalDeviceTypes.add(HdmiDeviceInfo.DEVICE_PLAYBACK);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index cfdf176..d600e16 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 import static com.android.server.hdmi.Constants.ABORT_UNRECOGNIZED_OPCODE;
 import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
@@ -29,6 +31,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
+
 import android.annotation.RequiresPermission;
 import android.content.Context;
 import android.content.Intent;
@@ -97,6 +101,9 @@
             new FakePowerManagerInternalWrapper();
     @Before
     public void setUp() {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         MockitoAnnotations.initMocks(this);
 
         Context context = InstrumentationRegistry.getTargetContext();
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 5be4490..f74e2ac 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 import static com.android.server.hdmi.Constants.ABORT_UNRECOGNIZED_OPCODE;
 import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
@@ -29,8 +31,8 @@
 import static com.android.server.hdmi.HdmiControlService.STANDBY_SCREEN_OFF;
 import static com.android.server.hdmi.HdmiControlService.WAKE_UP_SCREEN_ON;
 import static com.android.server.hdmi.RequestActiveSourceAction.TIMEOUT_WAIT_FOR_TV_ASSERT_ACTIVE_SOURCE_MS;
-import static com.android.server.hdmi.RoutingControlAction.TIMEOUT_ROUTING_INFORMATION_MS;
 import static com.android.server.hdmi.RequestSadAction.RETRY_COUNTER_MAX;
+import static com.android.server.hdmi.RoutingControlAction.TIMEOUT_ROUTING_INFORMATION_MS;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -38,6 +40,7 @@
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.eq;
@@ -167,6 +170,9 @@
 
     @Before
     public void setUp() {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         Context context = InstrumentationRegistry.getTargetContext();
         mMyLooper = mTestLooper.getLooper();
 
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
index 6577e09..587f437 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
 import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
 import static com.android.server.hdmi.HdmiCecMessageValidator.ERROR_DESTINATION;
@@ -27,6 +29,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
+
 import android.os.test.TestLooper;
 import android.platform.test.annotations.Presubmit;
 
@@ -53,6 +57,9 @@
 
     @Before
     public void setUp() throws Exception {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         FakeAudioFramework audioFramework = new FakeAudioFramework();
 
         HdmiControlService mHdmiControlService = new HdmiControlService(
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java
index 4f7f381..b1460b3 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecNetworkTest.java
@@ -17,10 +17,13 @@
 package com.android.server.hdmi;
 
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
 import static android.hardware.hdmi.DeviceFeatures.FEATURE_SUPPORTED;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
+
 import android.content.Context;
 import android.hardware.hdmi.DeviceFeatures;
 import android.hardware.hdmi.HdmiControlManager;
@@ -66,6 +69,9 @@
 
     @Before
     public void setUp() throws Exception {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         mContext = InstrumentationRegistry.getTargetContext();
 
         FakeAudioFramework audioFramework = new FakeAudioFramework();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java
index 3361e7f3..c48e4b6 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java
@@ -15,10 +15,13 @@
  */
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.Mockito.spy;
 
 import android.annotation.RequiresPermission;
@@ -63,6 +66,9 @@
 
     @Before
     public void setUp() throws Exception {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         Context contextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
         Looper myLooper = mTestLooper.getLooper();
 
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index 126a658..4eb3c15 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -15,6 +15,7 @@
  */
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
 import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM;
 import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_PLAYBACK;
 import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_TV;
@@ -38,6 +39,7 @@
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.TestCase.assertEquals;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -111,6 +113,9 @@
 
     @Before
     public void setUp() throws Exception {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
 
         HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTvTest.java
index eed9975..d283064 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTvTest.java
@@ -16,12 +16,15 @@
 
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
 import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_TV;
 
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
+
 import android.content.Context;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiDeviceInfo;
@@ -60,6 +63,9 @@
 
     @Before
     public void setUp() throws Exception {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         Context context = InstrumentationRegistry.getTargetContext();
         mMyLooper = mTestLooper.getLooper();
 
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiEarcLocalDeviceTxTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiEarcLocalDeviceTxTest.java
index 185f90f..98d2dfb 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiEarcLocalDeviceTxTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiEarcLocalDeviceTxTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
 import static android.media.AudioProfile.AUDIO_ENCAPSULATION_TYPE_NONE;
 
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
@@ -25,6 +26,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
@@ -84,6 +86,9 @@
 
     @Before
     public void setUp() {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         MockitoAnnotations.initMocks(this);
 
         Context context = InstrumentationRegistry.getTargetContext();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java
index 974f64d..76d4b56 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
 import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
@@ -23,6 +25,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.Mockito.spy;
 
 import android.annotation.RequiresPermission;
@@ -64,6 +67,9 @@
 
     @Before
     public void setUp() throws Exception {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
 
         FakeAudioFramework audioFramework = new FakeAudioFramework();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java
index 4cf2937..02e63f4 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/RequestSadActionTest.java
@@ -16,12 +16,16 @@
 
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
 import static com.android.server.hdmi.RequestSadAction.RETRY_COUNTER_MAX;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
+
 import android.annotation.RequiresPermission;
 import android.content.Context;
 import android.content.Intent;
@@ -95,6 +99,9 @@
 
     @Before
     public void setUp() {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         Context context = InstrumentationRegistry.getTargetContext();
         mMyLooper = mTestLooper.getLooper();
 
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionPlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionPlaybackTest.java
index 67a3f2a..fa1d326 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionPlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionPlaybackTest.java
@@ -16,11 +16,15 @@
 
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 import static com.android.server.hdmi.ResendCecCommandAction.SEND_COMMAND_RETRY_MS;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
+
 import android.annotation.RequiresPermission;
 import android.content.Context;
 import android.content.Intent;
@@ -58,6 +62,9 @@
 
     @Before
     public void setUp() throws Exception {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         Context context = InstrumentationRegistry.getTargetContext();
         FakeAudioFramework audioFramework = new FakeAudioFramework();
 
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionTvTest.java
index 047a04c..2f68bab 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ResendCecCommandActionTvTest.java
@@ -16,11 +16,15 @@
 
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 import static com.android.server.hdmi.ResendCecCommandAction.SEND_COMMAND_RETRY_MS;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
+
 import android.annotation.RequiresPermission;
 import android.content.Context;
 import android.content.Intent;
@@ -56,6 +60,9 @@
 
     @Before
     public void setUp() throws Exception {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         Context context = InstrumentationRegistry.getTargetContext();
         FakeAudioFramework audioFramework = new FakeAudioFramework();
 
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java
index 1019db4..912392f 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/RoutingControlActionTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
 import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
@@ -29,6 +31,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
+
 import android.annotation.RequiresPermission;
 import android.content.Context;
 import android.content.Intent;
@@ -143,6 +147,9 @@
 
     @Before
     public void setUp() {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         Context context = InstrumentationRegistry.getTargetContext();
         mMyLooper = mTestLooper.getLooper();
 
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryActionTest.java
index e4297ef..a1a5ffe 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SetAudioVolumeLevelDiscoveryActionTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.hdmi;
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
 import static android.hardware.hdmi.DeviceFeatures.FEATURE_NOT_SUPPORTED;
 import static android.hardware.hdmi.DeviceFeatures.FEATURE_SUPPORTED;
 import static android.hardware.hdmi.DeviceFeatures.FEATURE_SUPPORT_UNKNOWN;
@@ -24,6 +25,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doNothing;
@@ -79,6 +81,9 @@
      */
     @Before
     public void setUp() throws RemoteException {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         mContextSpy = spy(new ContextWrapper(
                 InstrumentationRegistry.getInstrumentation().getTargetContext()));
 
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java
index effea5a..c358e1d 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioAutoInitiationActionTest.java
@@ -17,12 +17,15 @@
 package com.android.server.hdmi;
 
 
+import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
+
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
 import static com.android.server.hdmi.SystemAudioAutoInitiationAction.RETRIES_ON_TIMEOUT;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.Mockito.spy;
 
 import android.annotation.RequiresPermission;
@@ -65,6 +68,9 @@
 
     @Before
     public void setUp() throws Exception {
+        assumeTrue("Test requires FEATURE_HDMI_CEC",
+                InstrumentationRegistry.getTargetContext().getPackageManager()
+                        .hasSystemFeature(FEATURE_HDMI_CEC));
         mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
 
         Looper myLooper = mTestLooper.getLooper();
diff --git a/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEndpointTest.java b/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEndpointTest.java
new file mode 100644
index 0000000..2e489a8
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEndpointTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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 static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.hardware.contexthub.HubEndpointInfo;
+import android.hardware.contexthub.HubEndpointInfo.HubEndpointIdentifier;
+import android.hardware.contexthub.IContextHubEndpoint;
+import android.hardware.contexthub.IContextHubEndpointCallback;
+import android.hardware.contexthub.IEndpointCommunication;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.platform.test.annotations.Postsubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.Collections;
+
+@RunWith(AndroidJUnit4.class)
+@Postsubmit
+// TODO(b/378944402): Enable test in presubmit
+public class ContextHubEndpointTest {
+    private static final int SESSION_ID_RANGE = ContextHubEndpointManager.SERVICE_SESSION_RANGE;
+    private static final int MIN_SESSION_ID = 0;
+    private static final int MAX_SESSION_ID = MIN_SESSION_ID + SESSION_ID_RANGE - 1;
+
+    private static final String ENDPOINT_NAME = "Example test endpoint";
+    private static final int ENDPOINT_ID = 1;
+    private static final String ENDPOINT_PACKAGE_NAME = "com.android.server.location.contexthub";
+
+    private ContextHubClientManager mClientManager;
+    private ContextHubEndpointManager mEndpointManager;
+    private HubInfoRegistry mHubInfoRegistry;
+    private ContextHubTransactionManager mTransactionManager;
+    private Context mContext;
+    @Mock private IEndpointCommunication mMockEndpointCommunications;
+    @Mock private IContextHubWrapper mMockContextHubWrapper;
+    @Mock private IContextHubEndpointCallback mMockCallback;
+    @Rule public final MockitoRule mockito = MockitoJUnit.rule();
+
+    @Before
+    public void setUp() throws RemoteException, InstantiationException {
+        when(mMockContextHubWrapper.getHubs()).thenReturn(Collections.emptyList());
+        when(mMockContextHubWrapper.getEndpoints()).thenReturn(Collections.emptyList());
+        when(mMockContextHubWrapper.registerEndpointHub(any(), any()))
+                .thenReturn(mMockEndpointCommunications);
+        when(mMockEndpointCommunications.requestSessionIdRange(SESSION_ID_RANGE))
+                .thenReturn(new int[] {MIN_SESSION_ID, MAX_SESSION_ID});
+        when(mMockCallback.asBinder()).thenReturn(new Binder());
+
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        mHubInfoRegistry = new HubInfoRegistry(mContext, mMockContextHubWrapper);
+        mClientManager = new ContextHubClientManager(mContext, mMockContextHubWrapper);
+        mTransactionManager =
+                new ContextHubTransactionManager(
+                        mMockContextHubWrapper, mClientManager, new NanoAppStateManager());
+        mEndpointManager =
+                new ContextHubEndpointManager(
+                        mContext, mMockContextHubWrapper, mHubInfoRegistry, mTransactionManager);
+        mEndpointManager.init();
+    }
+
+    @Test
+    public void testRegisterEndpoint() throws RemoteException {
+        // Register an endpoint and confirm we can get a valid IContextHubEndoint reference
+        HubEndpointInfo info =
+                new HubEndpointInfo(
+                        ENDPOINT_NAME, ENDPOINT_ID, ENDPOINT_PACKAGE_NAME, Collections.emptyList());
+        IContextHubEndpoint endpoint =
+                mEndpointManager.registerEndpoint(
+                        info, mMockCallback, ENDPOINT_PACKAGE_NAME, /* attributionTag= */ null);
+        assertThat(mEndpointManager.getNumRegisteredClients()).isEqualTo(1);
+        assertThat(endpoint).isNotNull();
+        HubEndpointInfo assignedInfo = endpoint.getAssignedHubEndpointInfo();
+        assertThat(assignedInfo).isNotNull();
+        HubEndpointIdentifier assignedIdentifier = assignedInfo.getIdentifier();
+        assertThat(assignedIdentifier).isNotNull();
+
+        // Unregister the endpoint and confirm proper clean-up
+        mEndpointManager.unregisterEndpoint(assignedIdentifier.getEndpoint());
+        assertThat(mEndpointManager.getNumRegisteredClients()).isEqualTo(0);
+    }
+
+    @Test
+    public void testReserveSessionId() {
+        assertThat(mEndpointManager.getNumAvailableSessions()).isEqualTo(SESSION_ID_RANGE);
+
+        int sessionId = mEndpointManager.reserveSessionId();
+        assertThat(sessionId).isAtLeast(MIN_SESSION_ID);
+        assertThat(sessionId).isAtMost(MAX_SESSION_ID);
+        assertThat(mEndpointManager.getNumAvailableSessions()).isEqualTo(SESSION_ID_RANGE - 1);
+
+        mEndpointManager.returnSessionId(sessionId);
+        assertThat(mEndpointManager.getNumAvailableSessions()).isEqualTo(SESSION_ID_RANGE);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/memory/OWNERS b/services/tests/servicestests/src/com/android/server/memory/OWNERS
new file mode 100644
index 0000000..4df08c1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/memory/OWNERS
@@ -0,0 +1,3 @@
+include /MEMORY_OWNERS
+
+per-file ZramMaintenanceTest.kt = kawasin@google.com
diff --git a/services/tests/servicestests/src/com/android/server/memory/ZramMaintenanceTest.kt b/services/tests/servicestests/src/com/android/server/memory/ZramMaintenanceTest.kt
new file mode 100644
index 0000000..1f59f45
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/memory/ZramMaintenanceTest.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.server.memory
+
+import android.app.job.JobInfo
+import android.app.job.JobParameters
+import android.app.job.JobScheduler
+import android.os.IMmd
+import android.os.PersistableBundle
+import android.os.RemoteException
+import android.testing.TestableContext
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+
+import com.google.common.truth.Truth.assertThat
+
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.any
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoAnnotations
+
+private fun generateJobParameters(jobId: Int, extras: PersistableBundle): JobParameters {
+    return JobParameters(
+        null, "", jobId, extras, null, null, 0, false, false, false, null, null, null
+    )
+}
+
+@SmallTest
+@RunWith(JUnit4::class)
+class ZramMaintenanceTest {
+    private val context = TestableContext(InstrumentationRegistry.getInstrumentation().context)
+
+    @Captor
+    private lateinit var jobInfoCaptor: ArgumentCaptor<JobInfo>
+
+    @Mock
+    private lateinit var mockJobScheduler: JobScheduler
+
+    @Mock
+    private lateinit var mockMmd: IMmd
+
+    @Before
+    @Throws(RemoteException::class)
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        context.addMockSystemService(JobScheduler::class.java, mockJobScheduler)
+    }
+
+    @Test
+    fun startZramMaintenance() {
+        ZramMaintenance.startZramMaintenance(context)
+
+        verify(mockJobScheduler, times(1)).schedule(jobInfoCaptor.capture())
+        val job = jobInfoCaptor.value
+        assertThat(job.id).isEqualTo(ZramMaintenance.JOB_ID)
+        assertThat(job.extras.getBoolean(ZramMaintenance.KEY_CHECK_STATUS)).isTrue()
+    }
+
+    @Test
+    fun startJobForFirstTime() {
+        val extras = PersistableBundle()
+        extras.putBoolean(ZramMaintenance.KEY_CHECK_STATUS, true)
+        val params = generateJobParameters(
+            ZramMaintenance.JOB_ID,
+            extras,
+        )
+        `when`(mockMmd.isZramMaintenanceSupported()).thenReturn(true)
+
+        ZramMaintenance.startJob(context, params, mockMmd)
+
+        verify(mockMmd, times(1)).isZramMaintenanceSupported()
+        verify(mockMmd, times(1)).doZramMaintenanceAsync()
+        verify(mockJobScheduler, times(1)).schedule(jobInfoCaptor.capture())
+        val nextJob = jobInfoCaptor.value
+        assertThat(nextJob.id).isEqualTo(ZramMaintenance.JOB_ID)
+        assertThat(nextJob.extras.getBoolean(ZramMaintenance.KEY_CHECK_STATUS)).isFalse()
+    }
+
+    @Test
+    fun startJobWithoutCheckStatus() {
+        val extras = PersistableBundle()
+        extras.putBoolean(ZramMaintenance.KEY_CHECK_STATUS, false)
+        val params = generateJobParameters(
+            ZramMaintenance.JOB_ID,
+            extras,
+        )
+
+        ZramMaintenance.startJob(context, params, mockMmd)
+
+        verify(mockMmd, never()).isZramMaintenanceSupported()
+        verify(mockMmd, times(1)).doZramMaintenanceAsync()
+        verify(mockJobScheduler, times(1)).schedule(jobInfoCaptor.capture())
+        val nextJob = jobInfoCaptor.value
+        assertThat(nextJob.id).isEqualTo(ZramMaintenance.JOB_ID)
+        assertThat(nextJob.extras.getBoolean(ZramMaintenance.KEY_CHECK_STATUS)).isFalse()
+    }
+
+    @Test
+    fun startJobZramIsDisabled() {
+        val extras = PersistableBundle()
+        extras.putBoolean(ZramMaintenance.KEY_CHECK_STATUS, true)
+        val params = generateJobParameters(
+            ZramMaintenance.JOB_ID,
+            extras,
+        )
+        `when`(mockMmd.isZramMaintenanceSupported()).thenReturn(false)
+
+        ZramMaintenance.startJob(context, params, mockMmd)
+
+        verify(mockMmd, times(1)).isZramMaintenanceSupported()
+        verify(mockMmd, never()).doZramMaintenanceAsync()
+        verify(mockJobScheduler, never()).schedule(any())
+    }
+
+    @Test
+    fun startJobMmdIsNotReadyYet() {
+        val extras = PersistableBundle()
+        extras.putBoolean(ZramMaintenance.KEY_CHECK_STATUS, true)
+        val params = generateJobParameters(
+            ZramMaintenance.JOB_ID,
+            extras,
+        )
+
+        ZramMaintenance.startJob(context, params, null)
+
+        verify(mockJobScheduler, times(1)).schedule(jobInfoCaptor.capture())
+        val nextJob = jobInfoCaptor.value
+        assertThat(nextJob.id).isEqualTo(ZramMaintenance.JOB_ID)
+        assertThat(nextJob.extras.getBoolean(ZramMaintenance.KEY_CHECK_STATUS)).isTrue()
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/supervision/SupervisionServiceTest.kt b/services/tests/servicestests/src/com/android/server/supervision/SupervisionServiceTest.kt
index b150b14..da02278 100644
--- a/services/tests/servicestests/src/com/android/server/supervision/SupervisionServiceTest.kt
+++ b/services/tests/servicestests/src/com/android/server/supervision/SupervisionServiceTest.kt
@@ -161,6 +161,18 @@
 
     @Test
     @RequiresFlagsEnabled(Flags.FLAG_ENABLE_SYNC_WITH_DPM)
+    fun profileOwnerChanged_supervisionAppIsNotProfileOwner_doesNotDisableSupervision() {
+        service.mInternal.setSupervisionEnabledForUser(USER_ID, true)
+        whenever(mockDpmInternal.getProfileOwnerAsUser(USER_ID))
+            .thenReturn(ComponentName("other.package", "MainActivity"))
+
+        broadcastProfileOwnerChanged(USER_ID)
+
+        assertThat(service.isSupervisionEnabledForUser(USER_ID)).isTrue()
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_SYNC_WITH_DPM)
     fun profileOwnerChanged_supervisionAppIsNotProfileOwner_doesNotEnableSupervision() {
         whenever(mockDpmInternal.getProfileOwnerAsUser(USER_ID))
             .thenReturn(ComponentName("other.package", "MainActivity"))
@@ -258,7 +270,7 @@
 
     private companion object {
         const val USER_ID = 100
-        val APP_UID = USER_ID * UserHandle.PER_USER_RANGE
+        const val APP_UID = USER_ID * UserHandle.PER_USER_RANGE
     }
 }
 
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 fa733e8..4a977be 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -96,12 +96,12 @@
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
 import platform.test.runner.parameterized.Parameters;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @SmallTest
 @SuppressLint("GuardedBy") // It's ok for this test to access guarded methods from the class.
 @RunWith(ParameterizedAndroidJunit4.class)
@@ -2671,7 +2671,7 @@
             r.updateNotificationChannel(channel);
         }
         mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel,
-                notificationList);
+                notificationList, summaryByGroup);
 
         // Check that all notifications are moved to the silent section group
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
@@ -2735,7 +2735,7 @@
             }
         }
         mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel1,
-                notificationList);
+                notificationList, summaryByGroup);
 
         // Check that the override group key was cleared
         for (NotificationRecord record: notificationList) {
@@ -2812,7 +2812,7 @@
             }
         }
         mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel1,
-                notificationList);
+                notificationList, summaryByGroup);
 
         // Check that the override group key was cleared
         for (NotificationRecord record: notificationList) {
@@ -2864,7 +2864,7 @@
         // Classify/bundle child notifications
         final NotificationChannel socialChannel = new NotificationChannel(
                 NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
-                IMPORTANCE_DEFAULT);
+                IMPORTANCE_LOW);
         final String expectedGroupKey_social = GroupHelper.getFullAggregateGroupKey(pkg,
                 AGGREGATE_GROUP_KEY + "SocialSection", UserHandle.SYSTEM.getIdentifier());
         final NotificationAttributes expectedSummaryAttr_social = new NotificationAttributes(
@@ -2872,7 +2872,7 @@
                 NotificationChannel.SOCIAL_MEDIA_ID);
         final NotificationChannel newsChannel = new NotificationChannel(
                 NotificationChannel.NEWS_ID, NotificationChannel.NEWS_ID,
-                IMPORTANCE_DEFAULT);
+                IMPORTANCE_LOW);
         final String expectedGroupKey_news = GroupHelper.getFullAggregateGroupKey(pkg,
                 AGGREGATE_GROUP_KEY + "NewsSection", UserHandle.SYSTEM.getIdentifier());
         final NotificationAttributes expectedSummaryAttr_news = new NotificationAttributes(
@@ -2944,7 +2944,7 @@
         // Classify/bundle child notifications
         final NotificationChannel socialChannel = new NotificationChannel(
                 NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
-                IMPORTANCE_DEFAULT);
+                IMPORTANCE_LOW);
         for (NotificationRecord record: notificationList) {
             if (record.getChannel().getId().equals(channel1.getId())
                     && record.getNotification().isGroupChild()) {
@@ -2999,7 +2999,7 @@
         // Classify/bundle child notifications
         final NotificationChannel socialChannel = new NotificationChannel(
                 NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
-                IMPORTANCE_DEFAULT);
+                IMPORTANCE_LOW);
         final String expectedGroupKey_social = GroupHelper.getFullAggregateGroupKey(pkg,
                 AGGREGATE_GROUP_KEY + "SocialSection", UserHandle.SYSTEM.getIdentifier());
         final NotificationAttributes expectedSummaryAttr_social = new NotificationAttributes(
@@ -3095,7 +3095,7 @@
         reset(mCallback);
         final NotificationChannel socialChannel = new NotificationChannel(
                 NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
-                IMPORTANCE_DEFAULT);
+                IMPORTANCE_LOW);
         final String expectedGroupKey_social = GroupHelper.getFullAggregateGroupKey(pkg,
                 AGGREGATE_GROUP_KEY + "SocialSection", UserHandle.SYSTEM.getIdentifier());
         final NotificationAttributes expectedSummaryAttr_social = new NotificationAttributes(
@@ -3149,7 +3149,7 @@
         // adjustments applied while enqueued will use NotificationAdjustmentExtractor.
         final NotificationChannel socialChannel = new NotificationChannel(
                 NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
-                IMPORTANCE_DEFAULT);
+                IMPORTANCE_LOW);
         final String expectedGroupKey_social = GroupHelper.getFullAggregateGroupKey(pkg,
                 AGGREGATE_GROUP_KEY + "SocialSection", UserHandle.SYSTEM.getIdentifier());
         final NotificationAttributes expectedSummaryAttr_social = new NotificationAttributes(
@@ -3209,7 +3209,7 @@
         // Classify/bundle all child notifications: original group & summary is removed
         final NotificationChannel socialChannel = new NotificationChannel(
                 NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
-                IMPORTANCE_DEFAULT);
+                IMPORTANCE_LOW);
         for (NotificationRecord record: notificationList) {
             if (record.getOriginalGroupKey().contains("testGrp")
                     && record.getNotification().isGroupChild()) {
@@ -3297,7 +3297,7 @@
         // Classify/bundle child notifications: all except one, to keep the original group
         final NotificationChannel socialChannel = new NotificationChannel(
                 NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
-                IMPORTANCE_DEFAULT);
+                IMPORTANCE_LOW);
         final String expectedGroupKey_social = GroupHelper.getFullAggregateGroupKey(pkg,
                 AGGREGATE_GROUP_KEY + "SocialSection", UserHandle.SYSTEM.getIdentifier());
         final NotificationAttributes expectedSummaryAttr_social = new NotificationAttributes(
@@ -3378,6 +3378,314 @@
     }
 
     @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            FLAG_NOTIFICATION_REGROUP_ON_CLASSIFICATION,
+            FLAG_NOTIFICATION_CLASSIFICATION})
+    public void testUnbundleByImportanceNotification_originalSummaryExists() {
+        // Check that unbundled notifications are moved to the original section and original group
+        // when the original summary is still present
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+
+        final int summaryId = 0;
+        final int numChildren = AUTOGROUP_AT_COUNT + 1;
+        // Post a regular/valid group: summary + notifications
+        NotificationRecord summary = getNotificationRecord(pkg, summaryId,
+                String.valueOf(summaryId), UserHandle.SYSTEM, "testGrp", true);
+        notificationList.add(summary);
+        summaryByGroup.put(summary.getGroupKey(), summary);
+        final String originalAppGroupKey = summary.getGroupKey();
+        final NotificationChannel originalChannel = summary.getChannel();
+        for (int i = 0; i < numChildren; i++) {
+            NotificationRecord child = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42),
+                    UserHandle.SYSTEM, "testGrp", false);
+            notificationList.add(child);
+            mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+        }
+
+        // Classify/bundle child notifications: all except one, to keep the original group
+        final NotificationChannel socialChannel = new NotificationChannel(
+                NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
+                IMPORTANCE_LOW);
+        final String expectedGroupKey_social = GroupHelper.getFullAggregateGroupKey(pkg,
+                AGGREGATE_GROUP_KEY + "SocialSection", UserHandle.SYSTEM.getIdentifier());
+        final NotificationAttributes expectedSummaryAttr_social = new NotificationAttributes(
+                BASE_FLAGS, mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+                NotificationChannel.SOCIAL_MEDIA_ID);
+        int numChildrenBundled = 0;
+        for (NotificationRecord record: notificationList) {
+            if (record.getOriginalGroupKey().contains("testGrp")
+                    && record.getNotification().isGroupChild()) {
+                record.updateNotificationChannel(socialChannel);
+                mGroupHelper.onChannelUpdated(record);
+                numChildrenBundled++;
+                if (numChildrenBundled == AUTOGROUP_AT_COUNT) {
+                    break;
+                }
+            }
+        }
+
+        // Check that 1 autogroup summaries were created for the social section
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_social), anyInt(), eq(expectedSummaryAttr_social));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_social), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).removeAppProvidedSummaryOnClassification(
+                anyString(), eq(originalAppGroupKey));
+
+        // Adjust group key for grouped notifications
+        for (NotificationRecord record: notificationList) {
+            if (record.getOriginalGroupKey().contains("testGrp")
+                    && NotificationChannel.SYSTEM_RESERVED_IDS.contains(
+                        record.getChannel().getId())) {
+                record.setOverrideGroupKey(expectedGroupKey_social);
+            }
+        }
+
+        // Add 1 ungrouped notification in the original section
+        NotificationRecord ungroupedNotification = getNotificationRecord(pkg, 4242,
+                String.valueOf(4242), UserHandle.SYSTEM);
+        notificationList.add(ungroupedNotification);
+        mGroupHelper.onNotificationPosted(ungroupedNotification, false);
+
+        // Unbundle the bundled notifications by changing the social channel importance to alerting
+        // => social section summary is destroyed
+        // and notifications are moved back to the original group
+        reset(mCallback);
+        socialChannel.setImportance(IMPORTANCE_DEFAULT);
+        for (NotificationRecord record: notificationList) {
+            if (record.getNotification().isGroupChild()
+                    && record.getOriginalGroupKey().contains("testGrp")
+                    && NotificationChannel.SYSTEM_RESERVED_IDS.contains(
+                        record.getChannel().getId())) {
+                record.updateNotificationChannel(socialChannel);
+            }
+        }
+        mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, socialChannel,
+                notificationList, summaryByGroup);
+
+        // Check that the autogroup summary for the social section was removed
+        // and that no new autogroup summaries were created
+        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+                anyString(), anyInt(), any());
+        verify(mCallback, never()).addAutoGroup(anyString(), anyString(), anyBoolean());
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey_social));
+
+        for (NotificationRecord record: notificationList) {
+            if (record.getNotification().isGroupChild()
+                    && record.getOriginalGroupKey().contains("testGrp")) {
+                assertThat(record.getSbn().getOverrideGroupKey()).isNull();
+                assertThat(GroupHelper.getSection(record).mName).isEqualTo("AlertingSection");
+            }
+        }
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            FLAG_NOTIFICATION_REGROUP_ON_CLASSIFICATION,
+            FLAG_NOTIFICATION_CLASSIFICATION})
+    public void testUnbundleByImportanceNotification_originalSummaryRemoved() {
+        // Check that unbundled notifications are moved to the original section and autogrouped
+        // when the original summary is not present
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+
+        final int summaryId = 0;
+        final int numChildren = AUTOGROUP_AT_COUNT + 1;
+        // Post a regular/valid group: summary + notifications
+        NotificationRecord summary = getNotificationRecord(pkg, summaryId,
+                String.valueOf(summaryId), UserHandle.SYSTEM, "testGrp", true);
+        notificationList.add(summary);
+        summaryByGroup.put(summary.getGroupKey(), summary);
+        final String originalAppGroupKey = summary.getGroupKey();
+        final NotificationChannel originalChannel = summary.getChannel();
+        for (int i = 0; i < numChildren; i++) {
+            NotificationRecord child = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42),
+                    UserHandle.SYSTEM, "testGrp", false);
+            notificationList.add(child);
+            mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+        }
+
+        // Classify/bundle child notifications: all except one, to keep the original group
+        final NotificationChannel socialChannel = new NotificationChannel(
+                NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
+                IMPORTANCE_LOW);
+        final String expectedGroupKey_social = GroupHelper.getFullAggregateGroupKey(pkg,
+                AGGREGATE_GROUP_KEY + "SocialSection", UserHandle.SYSTEM.getIdentifier());
+        final NotificationAttributes expectedSummaryAttr_social = new NotificationAttributes(
+                BASE_FLAGS, mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+                NotificationChannel.SOCIAL_MEDIA_ID);
+        int numChildrenBundled = 0;
+        for (NotificationRecord record: notificationList) {
+            if (record.getOriginalGroupKey().contains("testGrp")
+                    && record.getNotification().isGroupChild()) {
+                record.updateNotificationChannel(socialChannel);
+                mGroupHelper.onChannelUpdated(record);
+                numChildrenBundled++;
+                if (numChildrenBundled == AUTOGROUP_AT_COUNT) {
+                    break;
+                }
+            }
+        }
+
+        // Check that 1 autogroup summaries were created for the social section
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_social), anyInt(), eq(expectedSummaryAttr_social));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_social), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).removeAppProvidedSummaryOnClassification(
+                anyString(), eq(originalAppGroupKey));
+
+        // Adjust group key
+        for (NotificationRecord record: notificationList) {
+            if (record.getOriginalGroupKey().contains("testGrp")
+                    && NotificationChannel.SYSTEM_RESERVED_IDS.contains(
+                        record.getChannel().getId())) {
+                record.setOverrideGroupKey(expectedGroupKey_social);
+            }
+        }
+
+        // Remove original summary
+        notificationList.remove(summary);
+        summaryByGroup.remove(summary.getGroupKey());
+
+        // Add 1 ungrouped notification in the original section
+        NotificationRecord ungroupedNotification = getNotificationRecord(pkg, 4242,
+                String.valueOf(4242), UserHandle.SYSTEM);
+        notificationList.add(ungroupedNotification);
+        mGroupHelper.onNotificationPosted(ungroupedNotification, false);
+
+        // Unbundle the bundled notifications by changing the social channel importance to alerting
+        // => social section summary is destroyed
+        // and notifications are moved back to the alerting section and autogrouped
+        reset(mCallback);
+        socialChannel.setImportance(IMPORTANCE_DEFAULT);
+        for (NotificationRecord record: notificationList) {
+            if (record.getNotification().isGroupChild()
+                    && record.getOriginalGroupKey().contains("testGrp")
+                    && NotificationChannel.SYSTEM_RESERVED_IDS.contains(
+                        record.getChannel().getId())) {
+                record.updateNotificationChannel(socialChannel);
+            }
+        }
+        mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, socialChannel,
+                notificationList, summaryByGroup);
+
+        // Check that the autogroup summary for the social section was removed
+        // and that a new autogroup was created in the alerting section
+        final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
+                AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_alerting), anyInt(), any());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT + 1)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_alerting), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey_social));
+        verify(mCallback, never()).removeAppProvidedSummaryOnClassification(anyString(),
+                anyString());
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            FLAG_NOTIFICATION_CLASSIFICATION,
+            FLAG_NOTIFICATION_REGROUP_ON_CLASSIFICATION})
+    public void testClassifyWithAlertingImportance_doesNotBundle() {
+        // Check that classified notifications are autogrouped when channel importance
+        // is updated DEFAULT to LOW
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+
+        final int summaryId = 0;
+        final int numChildren = AUTOGROUP_AT_COUNT + 1;
+        // Post a regular/valid group: summary + notifications
+        NotificationRecord summary = getNotificationRecord(pkg, summaryId,
+                String.valueOf(summaryId), UserHandle.SYSTEM, "testGrp", true);
+        notificationList.add(summary);
+        summaryByGroup.put(summary.getGroupKey(), summary);
+        final String originalAppGroupKey = summary.getGroupKey();
+        final NotificationChannel originalChannel = summary.getChannel();
+        for (int i = 0; i < numChildren; i++) {
+            NotificationRecord child = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42),
+                    UserHandle.SYSTEM, "testGrp", false);
+            notificationList.add(child);
+            mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+        }
+
+        // Classify child notifications to Alerting bundle channel => do not "bundle"
+        final NotificationChannel socialChannel = new NotificationChannel(
+                NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
+                IMPORTANCE_DEFAULT);
+        int numChildrenBundled = 0;
+        for (NotificationRecord record: notificationList) {
+            if (record.getOriginalGroupKey().contains("testGrp")
+                    && record.getNotification().isGroupChild()) {
+                record.updateNotificationChannel(socialChannel);
+                mGroupHelper.onChannelUpdated(record);
+                numChildrenBundled++;
+                if (numChildrenBundled == AUTOGROUP_AT_COUNT) {
+                    break;
+                }
+            }
+        }
+
+        // Check that no autogroup summaries were created for the social section
+        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+                anyString(), anyInt(), any());
+        verify(mCallback, never()).addAutoGroup(anyString(), anyString(), anyBoolean());
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+        verify(mCallback, never()).removeAppProvidedSummaryOnClassification(anyString(),
+                anyString());
+
+        // Change importance to LOW => autogroup notifications in bundle section
+        reset(mCallback);
+        final String expectedGroupKey_social = GroupHelper.getFullAggregateGroupKey(pkg,
+                AGGREGATE_GROUP_KEY + "SocialSection", UserHandle.SYSTEM.getIdentifier());
+        final NotificationAttributes expectedSummaryAttr_social = new NotificationAttributes(
+                BASE_FLAGS, mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+                NotificationChannel.SOCIAL_MEDIA_ID);
+        socialChannel.setImportance(IMPORTANCE_LOW);
+        for (NotificationRecord record: notificationList) {
+            if (record.getNotification().isGroupChild()
+                    && record.getOriginalGroupKey().contains("testGrp")
+                    && NotificationChannel.SYSTEM_RESERVED_IDS.contains(
+                    record.getChannel().getId())) {
+                record.updateNotificationChannel(socialChannel);
+            }
+        }
+        mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, socialChannel,
+                notificationList, summaryByGroup);
+
+        // Check that 1 autogroup summaries were created for the social section
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_social), anyInt(), eq(expectedSummaryAttr_social));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_social), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).removeAppProvidedSummaryOnClassification(
+                anyString(), eq(originalAppGroupKey));
+    }
+
+    @Test
     @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testMoveAggregateGroups_updateChannel_groupsUngrouped() {
         final String pkg = "package";
@@ -3432,7 +3740,7 @@
             r.updateNotificationChannel(channel);
         }
         mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel,
-                notificationList);
+                notificationList, summaryByGroup);
 
         // Check that all notifications are moved to the silent section group
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
@@ -3489,7 +3797,7 @@
             }
         }
         mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel1,
-                notificationList);
+                notificationList, new ArrayMap<>());
 
         // Check that channel1's notifications are moved to the silent section & autogroup all
         NotificationAttributes expectedSummaryAttr = new NotificationAttributes(BASE_FLAGS,
@@ -3940,14 +4248,14 @@
         // Check that special categories are grouped in their own sections
         final NotificationChannel promoChannel = new NotificationChannel(
                 NotificationChannel.PROMOTIONS_ID, NotificationChannel.PROMOTIONS_ID,
-                IMPORTANCE_DEFAULT);
+                IMPORTANCE_LOW);
         final NotificationRecord notification_promotion = getNotificationRecord(mPkg, 0, "", mUser,
                 "", false, promoChannel);
         assertThat(GroupHelper.getSection(notification_promotion).mName).isEqualTo(
                 "PromotionsSection");
 
         final NotificationChannel newsChannel = new NotificationChannel(NotificationChannel.NEWS_ID,
-                NotificationChannel.NEWS_ID, IMPORTANCE_DEFAULT);
+                NotificationChannel.NEWS_ID, IMPORTANCE_LOW);
         final NotificationRecord notification_news = getNotificationRecord(mPkg, 0, "", mUser,
                 "", false, newsChannel);
         assertThat(GroupHelper.getSection(notification_news).mName).isEqualTo(
@@ -3955,18 +4263,49 @@
 
         final NotificationChannel socialChannel = new NotificationChannel(
                 NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
-                IMPORTANCE_DEFAULT);
+                IMPORTANCE_LOW);
         final NotificationRecord notification_social = getNotificationRecord(mPkg, 0, "", mUser,
                 "", false, socialChannel);
         assertThat(GroupHelper.getSection(notification_social).mName).isEqualTo(
                 "SocialSection");
 
         final NotificationChannel recsChannel = new NotificationChannel(NotificationChannel.RECS_ID,
-                NotificationChannel.RECS_ID, IMPORTANCE_DEFAULT);
+                NotificationChannel.RECS_ID, IMPORTANCE_LOW);
         final NotificationRecord notification_recs = getNotificationRecord(mPkg, 0, "", mUser,
                 "", false, recsChannel);
         assertThat(GroupHelper.getSection(notification_recs).mName).isEqualTo(
                 "RecsSection");
+
+        // Check that bundle categories with importance > IMPORTANCE_LOW are grouped into Alerting
+        final NotificationChannel promoChannelAlerting = new NotificationChannel(
+                NotificationChannel.PROMOTIONS_ID, NotificationChannel.PROMOTIONS_ID,
+                IMPORTANCE_DEFAULT);
+        final NotificationRecord notification_promotion_alerting = getNotificationRecord(mPkg, 0,
+                "", mUser, "", false, promoChannelAlerting);
+        assertThat(GroupHelper.getSection(notification_promotion_alerting).mName).isEqualTo(
+                "AlertingSection");
+
+        final NotificationChannel newsChannelAlerting = new NotificationChannel(
+                NotificationChannel.NEWS_ID, NotificationChannel.NEWS_ID, IMPORTANCE_DEFAULT);
+        final NotificationRecord notification_news_alerting = getNotificationRecord(mPkg, 0, "",
+                mUser, "", false, newsChannelAlerting);
+        assertThat(GroupHelper.getSection(notification_news_alerting).mName).isEqualTo(
+                "AlertingSection");
+
+        final NotificationChannel socialChannelAlerting = new NotificationChannel(
+                NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
+                IMPORTANCE_DEFAULT);
+        final NotificationRecord notification_social_alerting = getNotificationRecord(mPkg, 0, "",
+                mUser, "", false, socialChannelAlerting);
+        assertThat(GroupHelper.getSection(notification_social_alerting).mName).isEqualTo(
+                "AlertingSection");
+
+        final NotificationChannel recsChannelAlerting = new NotificationChannel(
+                NotificationChannel.RECS_ID, NotificationChannel.RECS_ID, IMPORTANCE_DEFAULT);
+        final NotificationRecord notification_recs_alerting = getNotificationRecord(mPkg, 0, "",
+                mUser, "", false, recsChannelAlerting);
+        assertThat(GroupHelper.getSection(notification_recs_alerting).mName).isEqualTo(
+                "AlertingSection");
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
index 19b90b6..076e3e9 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
@@ -22,6 +22,7 @@
 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 com.android.server.notification.NotificationManagerService.DEFAULT_ALLOWED_ADJUSTMENTS;
 
@@ -611,7 +612,8 @@
 
         ManagedServices.ManagedServiceInfo info =
                 mAssistants.new ManagedServiceInfo(null, mCn, userId, false, null, 35, 2345256);
-        mAssistants.setAdjustmentTypeSupportedState(info, Adjustment.KEY_NOT_CONVERSATION, false);
+        mAssistants.setAdjustmentTypeSupportedState(
+                info.userid, Adjustment.KEY_NOT_CONVERSATION, false);
 
         assertThat(mAssistants.getUnsupportedAdjustments(userId)).contains(
                 Adjustment.KEY_NOT_CONVERSATION);
@@ -632,7 +634,8 @@
 
         ManagedServices.ManagedServiceInfo info =
                 mAssistants.new ManagedServiceInfo(null, mCn, userId, false, null, 35, 2345256);
-        mAssistants.setAdjustmentTypeSupportedState(info, Adjustment.KEY_NOT_CONVERSATION, false);
+        mAssistants.setAdjustmentTypeSupportedState(
+                info.userid, Adjustment.KEY_NOT_CONVERSATION, false);
 
         writeXmlAndReload(USER_ALL);
 
@@ -654,7 +657,6 @@
         assertNotNull(current);
 
         writeXmlAndReload(USER_ALL);
-
         assertThat(mAssistants.getUnsupportedAdjustments(userId).size()).isEqualTo(0);
     }
 
@@ -707,26 +709,29 @@
     @Test
     @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
     public void testSetAssistantAdjustmentKeyTypeState_allow() {
-        assertThat(mAssistants.getAllowedClassificationTypes()).asList()
-                .containsExactly(TYPE_PROMOTION);
+        mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_CONTENT_RECOMMENDATION, false);
+        assertThat(mAssistants.getAllowedClassificationTypes())
+                .asList().doesNotContain(TYPE_CONTENT_RECOMMENDATION);
 
         mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_CONTENT_RECOMMENDATION, true);
 
         assertThat(mAssistants.getAllowedClassificationTypes()).asList()
-                .containsExactlyElementsIn(List.of(TYPE_PROMOTION, TYPE_CONTENT_RECOMMENDATION));
+                .contains(TYPE_CONTENT_RECOMMENDATION);
     }
 
     @Test
     @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
     public void testSetAssistantAdjustmentKeyTypeState_disallow() {
         mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_PROMOTION, false);
-        assertThat(mAssistants.getAllowedClassificationTypes()).isEmpty();
+        assertThat(mAssistants.getAllowedClassificationTypes())
+                .asList().doesNotContain(TYPE_PROMOTION);
     }
 
     @Test
     @EnableFlags(Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
     public void testDisallowAdjustmentKeyType_readWriteXml() throws Exception {
         mAssistants.loadDefaultsFromConfig(true);
+        mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_SOCIAL_MEDIA, false);
         mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_PROMOTION, false);
         mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_NEWS, true);
         mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_CONTENT_RECOMMENDATION, true);
@@ -745,7 +750,8 @@
         writeXmlAndReload(USER_ALL);
 
         assertThat(mAssistants.getAllowedClassificationTypes()).asList()
-                .containsExactly(TYPE_PROMOTION);
+                .containsExactlyElementsIn(List.of(TYPE_PROMOTION, TYPE_NEWS, TYPE_SOCIAL_MEDIA,
+                        TYPE_CONTENT_RECOMMENDATION));
     }
 
     @Test
@@ -757,18 +763,22 @@
         String allowedPackage = "allowed.package";
 
         assertThat(mAssistants.isAdjustmentAllowedForPackage(key, allowedPackage)).isTrue();
+        assertThat(mAssistants.getAdjustmentDeniedPackages(key)).isEmpty();
 
         // Set type adjustment disallowed for this package
         mAssistants.setAdjustmentSupportedForPackage(key, allowedPackage, false);
 
         // Then the package is marked as denied
         assertThat(mAssistants.isAdjustmentAllowedForPackage(key, allowedPackage)).isFalse();
+        assertThat(mAssistants.getAdjustmentDeniedPackages(key)).asList()
+                .containsExactly(allowedPackage);
 
         // Set type adjustment allowed again
         mAssistants.setAdjustmentSupportedForPackage(key, allowedPackage, true);
 
         // Then the package is marked as allowed again
         assertThat(mAssistants.isAdjustmentAllowedForPackage(key, allowedPackage)).isTrue();
+        assertThat(mAssistants.getAdjustmentDeniedPackages(key)).isEmpty();
     }
 
     @Test
@@ -789,6 +799,8 @@
         assertThat(mAssistants.isAdjustmentAllowedForPackage(key, deniedPkg1)).isFalse();
         assertThat(mAssistants.isAdjustmentAllowedForPackage(key, deniedPkg2)).isFalse();
         assertThat(mAssistants.isAdjustmentAllowedForPackage(key, deniedPkg3)).isFalse();
+        assertThat(mAssistants.getAdjustmentDeniedPackages(key)).asList()
+                .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg2, deniedPkg3));
 
         // And when we re-allow one of them,
         mAssistants.setAdjustmentSupportedForPackage(key, deniedPkg2, true);
@@ -797,6 +809,8 @@
         assertThat(mAssistants.isAdjustmentAllowedForPackage(key, deniedPkg1)).isFalse();
         assertThat(mAssistants.isAdjustmentAllowedForPackage(key, deniedPkg2)).isTrue();
         assertThat(mAssistants.isAdjustmentAllowedForPackage(key, deniedPkg3)).isFalse();
+        assertThat(mAssistants.getAdjustmentDeniedPackages(key)).asList()
+                .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg3));
     }
 
     @Test
@@ -860,8 +874,9 @@
                 mAssistants.new ManagedServiceInfo(null, mCn, userId, false, null, 35, 2345256);
 
         // Ensure bundling is enabled
-        mAssistants.setAdjustmentTypeSupportedState(info, KEY_TYPE, true);
+        mAssistants.setAdjustmentTypeSupportedState(info.userid, KEY_TYPE, true);
         // Enable these specific bundle types
+        mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_SOCIAL_MEDIA, false);
         mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_PROMOTION, false);
         mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_NEWS, true);
         mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_CONTENT_RECOMMENDATION, true);
@@ -894,7 +909,7 @@
                 .isEqualTo(NotificationProtoEnums.TYPE_CONTENT_RECOMMENDATION);
 
         // Disable the top-level bundling setting
-        mAssistants.setAdjustmentTypeSupportedState(info, KEY_TYPE, false);
+        mAssistants.setAdjustmentTypeSupportedState(info.userid, KEY_TYPE, false);
         // Enable these specific bundle types
         mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_PROMOTION, true);
         mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_NEWS, false);
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 f8c8a1d..3aa9544 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -2884,7 +2884,7 @@
         waitForIdle();
 
         verify(mGroupHelper, times(1)).onChannelUpdated(eq(Process.myUserHandle().getIdentifier()),
-                eq(mPkg), eq(mTestNotificationChannel), any());
+                eq(mPkg), eq(mTestNotificationChannel), any(), any());
     }
 
     @Test
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 832ca51..e42e10c 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -18,7 +18,6 @@
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.MODE_DEFAULT;
 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
-import static android.app.Flags.FLAG_MODES_UI;
 import static android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI;
 import static android.app.Notification.VISIBILITY_PRIVATE;
 import static android.app.Notification.VISIBILITY_SECRET;
@@ -158,6 +157,7 @@
 
 import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
 import com.android.internal.config.sysui.TestableFlagResolver;
+import com.android.internal.notification.NotificationChannelGroupsHelper;
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
 import com.android.os.AtomsProto;
@@ -258,9 +258,9 @@
     @Parameters(name = "{0}")
     public static List<FlagsParameterization> getParams() {
         return FlagsParameterization.allCombinationsOf(
-                android.app.Flags.FLAG_API_RICH_ONGOING,
-                FLAG_NOTIFICATION_CLASSIFICATION, FLAG_NOTIFICATION_CLASSIFICATION_UI,
-                FLAG_MODES_UI, android.app.Flags.FLAG_NM_BINDER_PERF_CACHE_CHANNELS);
+                android.app.Flags.FLAG_UI_RICH_ONGOING,
+                FLAG_NOTIFICATION_CLASSIFICATION_UI,
+                android.app.Flags.FLAG_NM_BINDER_PERF_CACHE_CHANNELS);
     }
 
     public PreferencesHelperTest(FlagsParameterization flags) {
@@ -661,6 +661,7 @@
 
         mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
         if (android.app.Flags.uiRichOngoing()) {
+            mHelper.setCanBePromoted(PKG_N_MR1, UID_N_MR1, false, true);
             mHelper.setCanBePromoted(PKG_N_MR1, UID_N_MR1, true, true);
         }
 
@@ -690,7 +691,8 @@
         }
 
         List<NotificationChannelGroup> actualGroups = mXmlHelper.getNotificationChannelGroups(
-                PKG_N_MR1, UID_N_MR1, false, true, false, true, null).getList();
+                PKG_N_MR1, UID_N_MR1,
+                NotificationChannelGroupsHelper.Params.forAllChannels(false)).getList();
         boolean foundNcg = false;
         for (NotificationChannelGroup actual : actualGroups) {
             if (ncg.getId().equals(actual.getId())) {
@@ -774,7 +776,8 @@
                 mXmlHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3.getId(), false));
 
         List<NotificationChannelGroup> actualGroups = mXmlHelper.getNotificationChannelGroups(
-                PKG_N_MR1, UID_N_MR1, false, true, false, true, null).getList();
+                PKG_N_MR1, UID_N_MR1,
+                NotificationChannelGroupsHelper.Params.forAllChannels(false)).getList();
         boolean foundNcg = false;
         for (NotificationChannelGroup actual : actualGroups) {
             if (ncg.getId().equals(actual.getId())) {
@@ -3426,8 +3429,8 @@
         mHelper.onPackagesChanged(true, USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
                 UID_N_MR1});
 
-        assertEquals(0, mHelper.getNotificationChannelGroups(
-                PKG_N_MR1, UID_N_MR1, true, true, false, true, null).getList().size());
+        assertEquals(0, mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1,
+                NotificationChannelGroupsHelper.Params.forAllChannels(true)).getList().size());
     }
 
     @Test
@@ -3566,8 +3569,8 @@
         mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel3, true, false,
                 UID_N_MR1, false);
 
-        List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
-                PKG_N_MR1, UID_N_MR1, true, true, false, true, null).getList();
+        List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(PKG_N_MR1,
+                UID_N_MR1, NotificationChannelGroupsHelper.Params.forAllChannels(true)).getList();
         assertEquals(3, actual.size());
         for (NotificationChannelGroup group : actual) {
             if (group.getId() == null) {
@@ -3601,15 +3604,15 @@
         channel1.setGroup(ncg.getId());
         mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
                 UID_N_MR1, false);
-        mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1, true, true, false, true, null)
-                .getList();
+        mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1,
+                NotificationChannelGroupsHelper.Params.forAllChannels(true)).getList();
 
         channel1.setImportance(IMPORTANCE_LOW);
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true,
                 UID_N_MR1, false);
 
-        List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
-                PKG_N_MR1, UID_N_MR1, true, true, false, true, null).getList();
+        List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(PKG_N_MR1,
+                UID_N_MR1, NotificationChannelGroupsHelper.Params.forAllChannels(true)).getList();
 
         assertEquals(2, actual.size());
         for (NotificationChannelGroup group : actual) {
@@ -3634,8 +3637,8 @@
         mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false,
                 UID_N_MR1, false);
 
-        List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
-                PKG_N_MR1, UID_N_MR1, false, false, true, true, null).getList();
+        List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(PKG_N_MR1,
+                UID_N_MR1, NotificationChannelGroupsHelper.Params.forAllGroups()).getList();
 
         assertEquals(2, actual.size());
         for (NotificationChannelGroup group : actual) {
@@ -3900,11 +3903,11 @@
         notExpected.add(PKG_P + " (" + UID_P + ") importance=");  // no importance for PKG_P
 
         for (String exp : expected) {
-            assertTrue(actual.contains(exp));
+            assertThat(actual).contains(exp);
         }
 
         for (String notExp : notExpected) {
-            assertFalse(actual.contains(notExp));
+            assertThat(actual).doesNotContain(notExp);
         }
     }
 
@@ -3917,14 +3920,21 @@
         mHelper.canShowBadge(PKG_P, UID_P);
 
         // get dump output
-        StringWriter sw = new StringWriter();
-        PrintWriter pw = new PrintWriter(sw);
-        mHelper.dump(pw, "", new NotificationManagerService.DumpFilter(), null);
-        pw.flush();
-        String actual = sw.toString();
+        String actual = dumpToString(mHelper);
 
         // nobody gets any importance
-        assertFalse(actual.contains("importance="));
+        assertThat(actual).doesNotContain("importance=");
+    }
+
+    @Test
+    public void testDumpString_includesDelegates() {
+        mHelper.setNotificationDelegate(PKG_P, UID_P, "the.delegate.package", 456);
+
+        String dump = dumpToString(mHelper);
+
+        assertThat(dump).contains(
+                "AppSettings: com.example.p (10003)\n"
+                + "    Delegate: the.delegate.package (456) enabled=true");
     }
 
     @Test
@@ -6440,8 +6450,9 @@
 
         Set<String> filter = ImmutableSet.of("id3");
 
-        NotificationChannelGroup actual = mHelper.getNotificationChannelGroups(
-                PKG_N_MR1, UID_N_MR1, false, true, false, true, filter).getList().get(0);
+        NotificationChannelGroup actual = mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1,
+                NotificationChannelGroupsHelper.Params.onlySpecifiedOrBlockedChannels(
+                        filter)).getList().get(0);
         assertEquals(2, actual.getChannels().size());
         assertEquals(1, actual.getChannels().stream().filter(c -> c.getId().equals("id3")).count());
         assertEquals(1, actual.getChannels().stream().filter(c -> c.getId().equals("id2")).count());
@@ -6468,8 +6479,9 @@
 
         Set<String> filter = ImmutableSet.of("id3");
 
-        NotificationChannelGroup actual = mHelper.getNotificationChannelGroups(
-                PKG_N_MR1, UID_N_MR1, false, true, false, false, filter).getList().get(0);
+        NotificationChannelGroup actual = mHelper.getNotificationChannelGroups(PKG_N_MR1, UID_N_MR1,
+                new NotificationChannelGroupsHelper.Params(false, true, false, false,
+                        filter)).getList().get(0);
         assertEquals(1, actual.getChannels().size());
         assertEquals(1, actual.getChannels().stream().filter(c -> c.getId().equals("id3")).count());
         assertEquals(0, actual.getChannels().stream().filter(c -> c.getId().equals("id2")).count());
@@ -6638,6 +6650,8 @@
     @Test
     @EnableFlags(android.app.Flags.FLAG_API_RICH_ONGOING)
     public void testSetCanBePromoted_allowlistNotOverrideUser() {
+        // default value is true. So we need to set it false to trigger the change.
+        mHelper.setCanBePromoted(PKG_P, UID_P, false, true);
         mHelper.setCanBePromoted(PKG_P, UID_P, true, true);
         assertThat(mHelper.canBePromoted(PKG_P, UID_P)).isTrue();
 
@@ -6841,6 +6855,15 @@
         assertThat(channels.getList().size()).isEqualTo(0);
     }
 
+    private static String dumpToString(PreferencesHelper helper) {
+        StringWriter sw = new StringWriter();
+        try (PrintWriter pw = new PrintWriter(sw)) {
+            helper.dump(pw, "", new NotificationManagerService.DumpFilter(), null);
+            pw.flush();
+            return sw.toString();
+        }
+    }
+
     // Test version of PreferencesHelper whose only functional difference is that it does not
     // interact with the real IpcDataCache, and instead tracks whether or not the cache has been
     // invalidated since creation or the last reset.
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 767c02b..b248218 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -109,7 +109,7 @@
 import com.android.server.LocalServices;
 import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
 import com.android.server.pm.BackgroundUserSoundNotifier;
-import com.android.server.pm.UserManagerService;
+import com.android.server.pm.UserManagerInternal;
 import com.android.server.vibrator.VibrationSession.Status;
 
 import org.junit.After;
@@ -898,7 +898,7 @@
 
     @Test
     public void vibrate_thenFgUserRequestsMute_getsCancelled() throws Throwable {
-        assumeTrue(UserManagerService.shouldShowNotificationForBackgroundUserSounds());
+        assumeTrue(UserManagerInternal.shouldShowNotificationForBackgroundUserSounds());
         mockVibrators(1);
         VibratorManagerService service = createSystemReadyService();
 
@@ -2760,7 +2760,7 @@
 
     @Test
     public void onExternalVibration_thenFgUserRequestsMute_doNotCancelVibration() throws Throwable {
-        assumeTrue(UserManagerService.shouldShowNotificationForBackgroundUserSounds());
+        assumeTrue(UserManagerInternal.shouldShowNotificationForBackgroundUserSounds());
         mockVibrators(1);
         mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL);
         VibratorManagerService service = createSystemReadyService();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
index 70f57eb..3c74ad0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
@@ -19,6 +19,7 @@
 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
@@ -44,20 +45,26 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.timeout;
 
+import android.annotation.NonNull;
 import android.app.ActivityOptions;
 import android.app.WaitResult;
+import android.app.WindowConfiguration;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.graphics.Rect;
 import android.os.Binder;
 import android.os.ConditionVariable;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
 import android.view.Display;
 
 import androidx.test.filters.MediumTest;
 
+import com.android.window.flags.Flags;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentMatchers;
@@ -424,4 +431,95 @@
         assertThat(activity.mLaunchCookie).isNull();
         verify(mAtm).moveTaskToFrontLocked(any(), eq(null), anyInt(), anyInt(), eq(safeOptions));
     }
+
+    @Test
+    public void testOpaque_leafTask_occludingActivity_isOpaque() {
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
+        activity.setOccludesParent(true);
+        final TaskFragment tf = activity.getTaskFragment();
+
+        assertThat(mSupervisor.mOpaqueContainerHelper.isOpaque(tf)).isTrue();
+    }
+
+    @Test
+    public void testOpaque_leafTask_nonOccludingActivity_isTranslucent() {
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
+        activity.setOccludesParent(false);
+        final TaskFragment tf = activity.getTaskFragment();
+
+        assertThat(mSupervisor.mOpaqueContainerHelper.isOpaque(tf)).isFalse();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    public void testOpaque_rootTask_translucentFillingChild_isTranslucent() {
+        final Task rootTask = new TaskBuilder(mSupervisor).setOnTop(true).build();
+        createChildTaskFragment(/* parent */ rootTask,
+                WINDOWING_MODE_FREEFORM, /* opaque */ false, /* filling */ true);
+
+        assertThat(mSupervisor.mOpaqueContainerHelper.isOpaque(rootTask)).isFalse();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    public void testOpaque_rootTask_opaqueAndNotFillingChild_isTranslucent() {
+        final Task rootTask = new TaskBuilder(mSupervisor).setOnTop(true).build();
+        createChildTaskFragment(/* parent */ rootTask,
+                WINDOWING_MODE_FREEFORM, /* opaque */ true, /* filling */ false);
+
+        assertThat(mSupervisor.mOpaqueContainerHelper.isOpaque(rootTask)).isFalse();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    public void testOpaque_rootTask_opaqueAndFillingChild_isOpaque() {
+        final Task rootTask = new TaskBuilder(mSupervisor).setOnTop(true).build();
+        createChildTaskFragment(/* parent */ rootTask,
+                WINDOWING_MODE_FREEFORM, /* opaque */ true, /* filling */ true);
+
+        assertThat(mSupervisor.mOpaqueContainerHelper.isOpaque(rootTask)).isTrue();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    public void testOpaque_rootTask_nonFillingOpaqueAdjacentChildren_isOpaque() {
+        final Task rootTask = new TaskBuilder(mSupervisor).setOnTop(true).build();
+        final TaskFragment tf1 = createChildTaskFragment(/* parent */ rootTask,
+                WINDOWING_MODE_MULTI_WINDOW, /* opaque */ true, /* filling */ false);
+        final TaskFragment tf2 = createChildTaskFragment(/* parent */ rootTask,
+                WINDOWING_MODE_MULTI_WINDOW, /* opaque */ true, /* filling */ false);
+        tf1.setAdjacentTaskFragment(tf2);
+
+        assertThat(mSupervisor.mOpaqueContainerHelper.isOpaque(rootTask)).isTrue();
+    }
+
+    @Test
+    @EnableFlags({Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+            Flags.FLAG_ALLOW_MULTIPLE_ADJACENT_TASK_FRAGMENTS})
+    public void testOpaque_rootTask_nonFillingOpaqueAdjacentChildren_multipleAdjacent_isOpaque() {
+        final Task rootTask = new TaskBuilder(mSupervisor).setOnTop(true).build();
+        final TaskFragment tf1 = createChildTaskFragment(/* parent */ rootTask,
+                WINDOWING_MODE_MULTI_WINDOW, /* opaque */ true, /* filling */ false);
+        final TaskFragment tf2 = createChildTaskFragment(/* parent */ rootTask,
+                WINDOWING_MODE_MULTI_WINDOW, /* opaque */ true, /* filling */ false);
+        final TaskFragment tf3 = createChildTaskFragment(/* parent */ rootTask,
+                WINDOWING_MODE_MULTI_WINDOW, /* opaque */ true, /* filling */ false);
+        tf1.setAdjacentTaskFragments(new TaskFragment.AdjacentSet(tf1, tf2, tf3));
+
+        assertThat(mSupervisor.mOpaqueContainerHelper.isOpaque(rootTask)).isTrue();
+    }
+
+    @NonNull
+    private TaskFragment createChildTaskFragment(@NonNull Task parent,
+            @WindowConfiguration.WindowingMode int windowingMode,
+            boolean opaque,
+            boolean filling) {
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setCreateTask(true).setParentTask(parent).build();
+        activity.setOccludesParent(opaque);
+        final TaskFragment tf = activity.getTaskFragment();
+        tf.setWindowingMode(windowingMode);
+        tf.setBounds(filling ? new Rect() : new Rect(100, 100, 200, 200));
+        return tf;
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
deleted file mode 100644
index 169968c..0000000
--- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.os.IBinder;
-import android.platform.test.annotations.Presubmit;
-import android.view.Display;
-import android.view.IRemoteAnimationFinishedCallback;
-import android.view.IRemoteAnimationRunner;
-import android.view.RemoteAnimationAdapter;
-import android.view.RemoteAnimationDefinition;
-import android.view.RemoteAnimationTarget;
-import android.view.WindowManager;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests for change transitions
- *
- * Build/Install/Run:
- *  atest WmTests:AppChangeTransitionTests
- */
-@SmallTest
-@Presubmit
-@RunWith(WindowTestRunner.class)
-public class AppChangeTransitionTests extends WindowTestsBase {
-
-    private Task mTask;
-    private ActivityRecord mActivity;
-
-    public void setUpOnDisplay(DisplayContent dc) {
-        mActivity = createActivityRecord(dc, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD);
-        mTask = mActivity.getTask();
-
-        // Set a remote animator with snapshot disabled. Snapshots don't work in wmtests.
-        RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
-        RemoteAnimationAdapter adapter =
-                new RemoteAnimationAdapter(new TestRemoteAnimationRunner(), 10, 1, false);
-        definition.addRemoteAnimation(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE, adapter);
-        dc.registerRemoteAnimations(definition);
-    }
-
-    class TestRemoteAnimationRunner implements IRemoteAnimationRunner {
-        @Override
-        public void onAnimationStart(@WindowManager.TransitionOldType int transit,
-                RemoteAnimationTarget[] apps,
-                RemoteAnimationTarget[] wallpapers,
-                RemoteAnimationTarget[] nonApps,
-                IRemoteAnimationFinishedCallback finishedCallback) {
-            for (RemoteAnimationTarget target : apps) {
-                assertNotNull(target.startBounds);
-            }
-            try {
-                finishedCallback.onAnimationFinished();
-            } catch (Exception e) {
-                throw new RuntimeException("Something went wrong");
-            }
-        }
-
-        @Override
-        public void onAnimationCancelled() {
-        }
-
-        @Override
-        public IBinder asBinder() {
-            return null;
-        }
-    }
-
-    @Test
-    public void testModeChangeRemoteAnimatorNoSnapshot() {
-        // setup currently defaults to no snapshot.
-        setUpOnDisplay(mDisplayContent);
-
-        mTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
-        assertEquals(1, mDisplayContent.mChangingContainers.size());
-
-        // Verify we are in a change transition, but without a snapshot.
-        // Though, the test will actually have crashed by now if a snapshot is attempted.
-        assertNull(mTask.mSurfaceFreezer.mSnapshot);
-        assertTrue(mTask.isInChangeTransition());
-
-        waitUntilHandlersIdle();
-        mActivity.removeImmediately();
-    }
-
-    @Test
-    public void testCancelPendingChangeOnRemove() {
-        // setup currently defaults to no snapshot.
-        setUpOnDisplay(mDisplayContent);
-
-        mTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
-        assertEquals(1, mDisplayContent.mChangingContainers.size());
-        assertTrue(mTask.isInChangeTransition());
-
-        // Removing the app-token from the display should clean-up the
-        // the change leash.
-        mDisplayContent.removeAppToken(mActivity.token);
-        assertEquals(0, mDisplayContent.mChangingContainers.size());
-        assertFalse(mTask.isInChangeTransition());
-
-        waitUntilHandlersIdle();
-        mActivity.removeImmediately();
-    }
-
-    @Test
-    public void testNoChangeOnOldDisplayWhenMoveDisplay() {
-        mDisplayContent.getDefaultTaskDisplayArea().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
-        final DisplayContent dc1 = createNewDisplay(Display.STATE_ON);
-        dc1.getDefaultTaskDisplayArea().setWindowingMode(WINDOWING_MODE_FREEFORM);
-        setUpOnDisplay(dc1);
-
-        assertEquals(WINDOWING_MODE_FREEFORM, mTask.getWindowingMode());
-
-        // Reparenting to a display with different windowing mode may trigger
-        // a change transition internally, but it should be cleaned-up once
-        // the display change is complete.
-        mTask.reparent(mDisplayContent.getDefaultTaskDisplayArea(), true);
-
-        assertEquals(WINDOWING_MODE_FULLSCREEN, mTask.getWindowingMode());
-
-        // Make sure the change transition is not the old display
-        assertFalse(dc1.mChangingContainers.contains(mTask));
-
-        waitUntilHandlersIdle();
-        mActivity.removeImmediately();
-    }
-
-    @Test
-    public void testCancelPendingChangeOnHide() {
-        // setup currently defaults to no snapshot.
-        setUpOnDisplay(mDisplayContent);
-
-        mTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
-        assertEquals(1, mDisplayContent.mChangingContainers.size());
-        assertTrue(mTask.isInChangeTransition());
-
-        // Changing visibility should cancel the change transition and become closing
-        mActivity.setVisibility(false);
-        assertEquals(0, mDisplayContent.mChangingContainers.size());
-        assertFalse(mTask.isInChangeTransition());
-
-        waitUntilHandlersIdle();
-        mActivity.removeImmediately();
-    }
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index 03d9042..8553fbd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -409,7 +409,6 @@
         task.getBounds(taskBounds);
         taskFragment.setBounds(0, 0, taskBounds.right / 2, taskBounds.bottom);
         spyOn(taskFragment);
-        mockSurfaceFreezerSnapshot(taskFragment.mSurfaceFreezer);
 
         assertTrue(mDc.mChangingContainers.isEmpty());
         assertFalse(mDc.mAppTransition.isTransitionSet());
@@ -422,7 +421,6 @@
         verify(taskFragment).initializeChangeTransition(activity.getBounds(), activityLeash);
         assertTrue(mDc.mChangingContainers.contains(taskFragment));
         assertTrue(mDc.mAppTransition.containsTransitRequest(TRANSIT_CHANGE));
-        assertEquals(startBounds, taskFragment.mSurfaceFreezer.mFreezeBounds);
     }
 
     @Test
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 716f864..5607252 100644
--- a/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java
@@ -158,7 +158,7 @@
     public void testIsCameraRunningAndWindowingModeEligible_notFreeformWindowing_returnsFalse() {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT, WINDOWING_MODE_FULLSCREEN);
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         assertFalse(mCameraCompatFreeformPolicy.isCameraRunningAndWindowingModeEligible(mActivity));
     }
@@ -169,7 +169,7 @@
     public void testIsCameraRunningAndWindowingModeEligible_optInFreeformCameraRunning_true() {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         assertTrue(mCameraCompatFreeformPolicy.isCameraRunningAndWindowingModeEligible(mActivity));
     }
@@ -179,7 +179,7 @@
     public void testIsFreeformLetterboxingForCameraAllowed_overrideDisabled_returnsFalse() {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         assertFalse(mCameraCompatFreeformPolicy.isFreeformLetterboxingForCameraAllowed(mActivity));
     }
@@ -199,7 +199,7 @@
     public void testIsFreeformLetterboxingForCameraAllowed_notFreeformWindowing_returnsFalse() {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT, WINDOWING_MODE_FULLSCREEN);
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         assertFalse(mCameraCompatFreeformPolicy.isFreeformLetterboxingForCameraAllowed(mActivity));
     }
@@ -210,7 +210,7 @@
     public void testIsFreeformLetterboxingForCameraAllowed_optInFreeformCameraRunning_true() {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         assertTrue(mCameraCompatFreeformPolicy.isFreeformLetterboxingForCameraAllowed(mActivity));
     }
@@ -222,7 +222,7 @@
         configureActivity(SCREEN_ORIENTATION_PORTRAIT, WINDOWING_MODE_FULLSCREEN);
         doReturn(false).when(mActivity).inFreeformWindowingMode();
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         assertNotInCameraCompatMode();
     }
@@ -250,7 +250,8 @@
     public void testCameraConnected_deviceInPortrait_portraitCameraCompatMode() throws Exception {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
         setDisplayRotation(ROTATION_0);
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         assertInCameraCompatMode(CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT);
         assertActivityRefreshRequested(/* refreshRequested */ false);
@@ -262,7 +263,8 @@
     public void testCameraConnected_deviceInLandscape_portraitCameraCompatMode() throws Exception {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
         setDisplayRotation(ROTATION_270);
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         assertInCameraCompatMode(CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE);
         assertActivityRefreshRequested(/* refreshRequested */ false);
@@ -274,7 +276,8 @@
     public void testCameraConnected_deviceInPortrait_landscapeCameraCompatMode() throws Exception {
         configureActivity(SCREEN_ORIENTATION_LANDSCAPE);
         setDisplayRotation(ROTATION_0);
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         assertInCameraCompatMode(CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT);
         assertActivityRefreshRequested(/* refreshRequested */ false);
@@ -286,7 +289,8 @@
     public void testCameraConnected_deviceInLandscape_landscapeCameraCompatMode() throws Exception {
         configureActivity(SCREEN_ORIENTATION_LANDSCAPE);
         setDisplayRotation(ROTATION_270);
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         assertInCameraCompatMode(CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE);
         assertActivityRefreshRequested(/* refreshRequested */ false);
@@ -299,12 +303,12 @@
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
         setDisplayRotation(ROTATION_270);
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
         callOnActivityConfigurationChanging(mActivity, /* letterboxNew= */ true,
                 /* lastLetterbox= */ false);
         assertActivityRefreshRequested(/* refreshRequested */ true);
-        mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1);
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraClosed(CAMERA_ID_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
         // Activity is letterboxed from the previous configuration change.
         callOnActivityConfigurationChanging(mActivity, /* letterboxNew= */ true,
                 /* lastLetterbox= */ true);
@@ -319,7 +323,7 @@
     public void testCameraOpenedForDifferentPackage_notInCameraCompatMode() {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_2);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_2);
 
         assertNotInCameraCompatMode();
     }
@@ -329,7 +333,7 @@
     public void testShouldApplyCameraCompatFreeformTreatment_overrideNotEnabled_returnsFalse() {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         assertFalse(mCameraCompatFreeformPolicy.isTreatmentEnabledForActivity(mActivity,
                 /* checkOrientation */ true));
@@ -341,7 +345,7 @@
     public void testShouldApplyCameraCompatFreeformTreatment_enabledByOverride_returnsTrue() {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         assertTrue(mActivity.info
                 .isChangeEnabled(OVERRIDE_CAMERA_COMPAT_ENABLE_FREEFORM_WINDOWING_TREATMENT));
@@ -356,7 +360,7 @@
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
         Configuration oldConfiguration = createConfiguration(/* letterbox= */ false);
         Configuration newConfiguration = createConfiguration(/* letterbox= */ true);
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         assertTrue(mCameraCompatFreeformPolicy.shouldRefreshActivity(mActivity, newConfiguration,
                 oldConfiguration));
@@ -372,7 +376,7 @@
 
         oldConfiguration.windowConfiguration.setDisplayRotation(0);
         newConfiguration.windowConfiguration.setDisplayRotation(90);
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         assertTrue(mCameraCompatFreeformPolicy.shouldRefreshActivity(mActivity, newConfiguration,
                 oldConfiguration));
@@ -388,7 +392,7 @@
 
         oldConfiguration.windowConfiguration.setDisplayRotation(0);
         newConfiguration.windowConfiguration.setDisplayRotation(0);
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         assertFalse(mCameraCompatFreeformPolicy.shouldRefreshActivity(mActivity, newConfiguration,
                 oldConfiguration));
@@ -404,7 +408,7 @@
         doReturn(false).when(mActivity.mAppCompatController.getCameraOverrides())
                 .shouldRefreshActivityForCameraCompat();
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
         callOnActivityConfigurationChanging(mActivity);
 
         assertActivityRefreshRequested(/* refreshRequested */ false);
@@ -419,7 +423,7 @@
 
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
         callOnActivityConfigurationChanging(mActivity);
 
         assertActivityRefreshRequested(/* refreshRequested */ true, /* cycleThroughStop */ false);
@@ -434,7 +438,7 @@
         doReturn(true).when(mActivity.mAppCompatController.getCameraOverrides())
                 .shouldRefreshActivityViaPauseForCameraCompat();
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
         callOnActivityConfigurationChanging(mActivity);
 
         assertActivityRefreshRequested(/* refreshRequested */ true, /* cycleThroughStop */ false);
@@ -446,7 +450,7 @@
     public void testGetCameraCompatAspectRatio_activityNotInCameraCompat_returnsDefaultAspRatio() {
         configureActivity(SCREEN_ORIENTATION_FULL_USER);
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
         callOnActivityConfigurationChanging(mActivity);
 
         assertEquals(MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO,
@@ -462,7 +466,7 @@
         final float configAspectRatio = 1.5f;
         mWm.mAppCompatConfiguration.setCameraCompatAspectRatio(configAspectRatio);
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
         callOnActivityConfigurationChanging(mActivity);
 
         assertEquals(configAspectRatio,
@@ -480,7 +484,7 @@
         doReturn(true).when(mActivity.mAppCompatController.getCameraOverrides())
                 .isOverrideMinAspectRatioForCameraEnabled();
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
         callOnActivityConfigurationChanging(mActivity);
 
         assertEquals(MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO,
@@ -496,7 +500,7 @@
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
         setDisplayRotation(ROTATION_270);
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         // This is a portrait rotation for a device with portrait natural orientation (most common,
         // currently the only one supported).
@@ -511,7 +515,7 @@
         configureActivity(SCREEN_ORIENTATION_LANDSCAPE);
         setDisplayRotation(ROTATION_0);
 
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         // This is a landscape rotation for a device with portrait natural orientation (most common,
         // currently the only one supported).
@@ -616,6 +620,16 @@
                 .inFreeformWindowingMode();
     }
 
+    private void onCameraOpened(@NonNull String cameraId, @NonNull String packageName) {
+        mCameraAvailabilityCallback.onCameraOpened(cameraId, packageName);
+        waitHandlerIdle(mDisplayContent.mWmService.mH);
+    }
+
+    private void onCameraClosed(@NonNull String cameraId) {
+        mCameraAvailabilityCallback.onCameraClosed(cameraId);
+        waitHandlerIdle(mDisplayContent.mWmService.mH);
+    }
+
     private void assertInCameraCompatMode(@CameraCompatTaskInfo.FreeformCameraCompatMode int mode) {
         assertEquals(mode, mCameraCompatFreeformPolicy.getCameraCompatMode(mActivity));
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java
index cdb51fc..fdde3b3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java
@@ -1345,7 +1345,7 @@
     private void setupDesktopModeLaunchParamsModifier(boolean isDesktopModeSupported,
             boolean enforceDeviceRestrictions) {
         doReturn(isDesktopModeSupported)
-                .when(() -> DesktopModeHelper.isDesktopModeSupported(any()));
+                .when(() -> DesktopModeHelper.isDeviceEligibleForDesktopMode(any()));
         doReturn(enforceDeviceRestrictions)
                 .when(DesktopModeHelper::shouldEnforceDeviceRestrictions);
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
index 5265b44..67a95de 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
@@ -39,6 +39,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 
+import android.annotation.NonNull;
 import android.app.ActivityOptions;
 import android.content.ComponentName;
 import android.content.pm.ActivityInfo.WindowLayout;
@@ -293,7 +294,7 @@
         final int beforeWindowMode = task.getWindowingMode();
         assertNotEquals(windowingMode, beforeWindowMode);
 
-        mController.layoutTask(task, null /* windowLayout */);
+        layoutTask(task);
 
         final int afterWindowMode = task.getWindowingMode();
         assertEquals(afterWindowMode, beforeWindowMode);
@@ -317,7 +318,7 @@
 
         assertNotEquals(expected, task.getBounds());
 
-        mController.layoutTask(task, null /* windowLayout */);
+        layoutTask(task);
 
         // Task will make adjustments to requested bounds. We only need to guarantee that the
         // reuqested bounds are expected.
@@ -342,7 +343,7 @@
 
         assertNotEquals(expected, task.getBounds());
 
-        mController.layoutTask(task, null /* windowLayout */);
+        layoutTask(task);
 
         assertEquals(expected, task.getRequestedOverrideBounds());
     }
@@ -365,7 +366,7 @@
 
         assertNotEquals(expected, task.getBounds());
 
-        mController.layoutTask(task, null /* windowLayout */);
+        layoutTask(task);
 
         assertNotEquals(expected, task.getBounds());
         assertEquals(expected, task.mLastNonFullscreenBounds);
@@ -467,4 +468,9 @@
     private TestDisplayContent createNewDisplayContent() {
         return addNewDisplayContentAt(DisplayContent.POSITION_TOP);
     }
+
+    private void layoutTask(@NonNull Task task) {
+        mController.layoutTask(task, null /* layout */, null /* activity */, null /* source */,
+                null /* options */);
+    }
 }
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 c3aa289..dba463a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -4461,46 +4461,7 @@
         // are aligned to the top of the parentAppBounds
         assertEquals(new Rect(0, notchHeight, 1000, 1200), appBounds);
         assertEquals(new Rect(0, 0, 1000, 1200), bounds);
-    }
 
-    @Test
-    @DisableCompatChanges({ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED})
-    public void testInFreeform_boundsSandboxedToAppBounds() {
-        final int dw = 2800;
-        final int dh = 1400;
-        final int notchHeight = 100;
-        final DisplayContent display = new TestDisplayContent.Builder(mAtm, dw, dh)
-                .setNotch(notchHeight)
-                .build();
-        setUpApp(display);
-        prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
-
-        mTask.mDisplayContent.getDefaultTaskDisplayArea()
-                .setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
-        mTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
-        Rect appBounds = new Rect(0, 0, 1000, 500);
-        Rect bounds = new Rect(0, 0, 1000, 600);
-        mTask.getWindowConfiguration().setAppBounds(appBounds);
-        mTask.getWindowConfiguration().setBounds(bounds);
-        mActivity.onConfigurationChanged(mTask.getConfiguration());
-
-        // Bounds are sandboxed to appBounds in freeform.
-        assertDownScaled();
-        assertEquals(mActivity.getWindowConfiguration().getAppBounds(),
-                mActivity.getWindowConfiguration().getBounds());
-
-        // Exit freeform.
-        mTask.mDisplayContent.getDefaultTaskDisplayArea()
-                .setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
-        mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
-        mTask.getWindowConfiguration().setBounds(new Rect(0, 0, dw, dh));
-        mActivity.onConfigurationChanged(mTask.getConfiguration());
-        assertFitted();
-        appBounds = mActivity.getWindowConfiguration().getAppBounds();
-        bounds = mActivity.getWindowConfiguration().getBounds();
-        // Bounds are not sandboxed to appBounds.
-        assertNotEquals(appBounds, bounds);
-        assertEquals(notchHeight, appBounds.top - bounds.top);
     }
 
     @Test
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 0d97724..ee8d730 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -152,7 +152,6 @@
                 ACTIVITY_TYPE_STANDARD);
         task.setBoundsUnchecked(new Rect(0, 0, 1000, 1000));
         mTaskFragment = createTaskFragmentWithEmbeddedActivity(task, mOrganizer);
-        mockSurfaceFreezerSnapshot(mTaskFragment.mSurfaceFreezer);
         final Rect startBounds = new Rect(0, 0, 500, 1000);
         final Rect endBounds = new Rect(500, 0, 1000, 1000);
         mTaskFragment.setRelativeEmbeddedBounds(startBounds);
@@ -179,44 +178,6 @@
     }
 
     @Test
-    public void testStartChangeTransition_resetSurface() {
-        final Task task = createTask(mDisplayContent, WINDOWING_MODE_MULTI_WINDOW,
-                ACTIVITY_TYPE_STANDARD);
-        task.setBoundsUnchecked(new Rect(0, 0, 1000, 1000));
-        mTaskFragment = createTaskFragmentWithEmbeddedActivity(task, mOrganizer);
-        doReturn(mTransaction).when(mTaskFragment).getSyncTransaction();
-        doReturn(mTransaction).when(mTaskFragment).getPendingTransaction();
-        mLeash = mTaskFragment.getSurfaceControl();
-        mockSurfaceFreezerSnapshot(mTaskFragment.mSurfaceFreezer);
-        final Rect startBounds = new Rect(0, 0, 1000, 1000);
-        final Rect endBounds = new Rect(500, 500, 1000, 1000);
-        mTaskFragment.setRelativeEmbeddedBounds(startBounds);
-        mTaskFragment.recomputeConfiguration();
-        doReturn(true).when(mTaskFragment).isVisible();
-        doReturn(true).when(mTaskFragment).isVisibleRequested();
-
-        clearInvocations(mTransaction);
-        final Rect relStartBounds = new Rect(mTaskFragment.getRelativeEmbeddedBounds());
-        mTaskFragment.deferOrganizedTaskFragmentSurfaceUpdate();
-        mTaskFragment.setRelativeEmbeddedBounds(endBounds);
-        mTaskFragment.recomputeConfiguration();
-        assertTrue(mTaskFragment.shouldStartChangeTransition(startBounds, relStartBounds));
-        mTaskFragment.initializeChangeTransition(startBounds);
-        mTaskFragment.continueOrganizedTaskFragmentSurfaceUpdate();
-
-        // Surface reset when prepare transition.
-        verify(mTransaction).setPosition(mLeash, 0, 0);
-        verify(mTransaction).setWindowCrop(mLeash, 0, 0);
-
-        clearInvocations(mTransaction);
-        mTaskFragment.mSurfaceFreezer.unfreeze(mTransaction);
-
-        // Update surface after animation.
-        verify(mTransaction).setPosition(mLeash, 500, 500);
-        verify(mTransaction).setWindowCrop(mLeash, 500, 500);
-    }
-
-    @Test
     public void testStartChangeTransition_doNotFreezeWhenOnlyMoved() {
         final Rect startBounds = new Rect(0, 0, 1000, 1000);
         final Rect endBounds = new Rect(startBounds);
@@ -235,7 +196,6 @@
 
     @Test
     public void testNotOkToAnimate_doNotStartChangeTransition() {
-        mockSurfaceFreezerSnapshot(mTaskFragment.mSurfaceFreezer);
         final Rect startBounds = new Rect(0, 0, 1000, 1000);
         final Rect endBounds = new Rect(500, 500, 1000, 1000);
         mTaskFragment.setRelativeEmbeddedBounds(startBounds);
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 cc447a1..0014465 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -32,7 +32,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_OLD_TASK_CLOSE;
-import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CHANGE;
 import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
@@ -64,7 +63,6 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -1014,30 +1012,6 @@
     }
 
     @Test
-    public void testOnDisplayChanged_cleanupChanging() {
-        final Task task = createTask(mDisplayContent);
-        addLocalInsets(task);
-        spyOn(task.mSurfaceFreezer);
-        mDisplayContent.mChangingContainers.add(task);
-
-        // Don't remove the changing transition of this window when it is still the old display.
-        // This happens on display info changed.
-        task.onDisplayChanged(mDisplayContent);
-
-        assertTrue(task.mLocalInsetsSources.size() == 1);
-        assertTrue(mDisplayContent.mChangingContainers.contains(task));
-        verify(task.mSurfaceFreezer, never()).unfreeze(any());
-
-        // Remove the changing transition of this window when it is moved or reparented from the old
-        // display.
-        final DisplayContent newDc = createNewDisplay();
-        task.onDisplayChanged(newDc);
-
-        assertFalse(mDisplayContent.mChangingContainers.contains(task));
-        verify(task.mSurfaceFreezer).unfreeze(any());
-    }
-
-    @Test
     public void testHandleCompleteDeferredRemoval() {
         final DisplayContent displayContent = createNewDisplay();
         // Do not reparent activity to default display when removing the display.
@@ -1290,157 +1264,17 @@
         final WindowContainer container = new WindowContainer(mWm);
         container.mSurfaceControl = mock(SurfaceControl.class);
         final SurfaceAnimator surfaceAnimator = container.mSurfaceAnimator;
-        final SurfaceFreezer surfaceFreezer = container.mSurfaceFreezer;
         final SurfaceControl relativeParent = mock(SurfaceControl.class);
         final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
         spyOn(container);
         spyOn(surfaceAnimator);
-        spyOn(surfaceFreezer);
         doReturn(t).when(container).getSyncTransaction();
 
         container.setLayer(t, 1);
         container.setRelativeLayer(t, relativeParent, 2);
 
-        // Set through surfaceAnimator if surfaceFreezer doesn't have leash.
         verify(surfaceAnimator).setLayer(t, 1);
         verify(surfaceAnimator).setRelativeLayer(t, relativeParent, 2);
-        verify(surfaceFreezer, never()).setLayer(any(), anyInt());
-        verify(surfaceFreezer, never()).setRelativeLayer(any(), any(), anyInt());
-
-        clearInvocations(surfaceAnimator);
-        clearInvocations(surfaceFreezer);
-        doReturn(true).when(surfaceFreezer).hasLeash();
-
-        container.setLayer(t, 1);
-        container.setRelativeLayer(t, relativeParent, 2);
-
-        // Set through surfaceFreezer if surfaceFreezer has leash.
-        verify(surfaceFreezer).setLayer(t, 1);
-        verify(surfaceFreezer).setRelativeLayer(t, relativeParent, 2);
-        verify(surfaceAnimator, never()).setLayer(any(), anyInt());
-        verify(surfaceAnimator, never()).setRelativeLayer(any(), any(), anyInt());
-    }
-
-    @Test
-    public void testStartChangeTransitionWhenPreviousIsNotFinished() {
-        final WindowContainer container = createTaskFragmentWithActivity(
-                createTask(mDisplayContent));
-        container.mSurfaceControl = mock(SurfaceControl.class);
-        final SurfaceAnimator surfaceAnimator = container.mSurfaceAnimator;
-        final SurfaceFreezer surfaceFreezer = container.mSurfaceFreezer;
-        final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
-        spyOn(container);
-        spyOn(surfaceAnimator);
-        mockSurfaceFreezerSnapshot(surfaceFreezer);
-        doReturn(t).when(container).getPendingTransaction();
-        doReturn(t).when(container).getSyncTransaction();
-
-        // Leash and snapshot created for change transition.
-        container.initializeChangeTransition(new Rect(0, 0, 1000, 2000));
-
-        assertNotNull(surfaceFreezer.mLeash);
-        assertNotNull(surfaceFreezer.mSnapshot);
-        assertEquals(surfaceFreezer.mLeash, container.getAnimationLeash());
-
-        // Start animation: surfaceAnimator take over the leash and snapshot from surfaceFreezer.
-        container.applyAnimationUnchecked(null /* lp */, true /* enter */,
-                TRANSIT_OLD_TASK_FRAGMENT_CHANGE, false /* isVoiceInteraction */,
-                null /* sources */);
-
-        assertNull(surfaceFreezer.mLeash);
-        assertNull(surfaceFreezer.mSnapshot);
-        assertNotNull(surfaceAnimator.mLeash);
-        assertNotNull(surfaceAnimator.mSnapshot);
-        final SurfaceControl prevLeash = surfaceAnimator.mLeash;
-        final SurfaceFreezer.Snapshot prevSnapshot = surfaceAnimator.mSnapshot;
-
-        // Prepare another change transition.
-        container.initializeChangeTransition(new Rect(0, 0, 1000, 2000));
-
-        assertNotNull(surfaceFreezer.mLeash);
-        assertNotNull(surfaceFreezer.mSnapshot);
-        assertEquals(surfaceFreezer.mLeash, container.getAnimationLeash());
-        assertNotEquals(prevLeash, container.getAnimationLeash());
-
-        // Start another animation before the previous one is finished, it should reset the previous
-        // one, but not change the current one.
-        container.applyAnimationUnchecked(null /* lp */, true /* enter */,
-                TRANSIT_OLD_TASK_FRAGMENT_CHANGE, false /* isVoiceInteraction */,
-                null /* sources */);
-
-        verify(container, never()).onAnimationLeashLost(any());
-        verify(surfaceFreezer, never()).unfreeze(any());
-        assertNotNull(surfaceAnimator.mLeash);
-        assertNotNull(surfaceAnimator.mSnapshot);
-        assertEquals(surfaceAnimator.mLeash, container.getAnimationLeash());
-        assertNotEquals(prevLeash, surfaceAnimator.mLeash);
-        assertNotEquals(prevSnapshot, surfaceAnimator.mSnapshot);
-
-        // Clean up after animation finished.
-        surfaceAnimator.mInnerAnimationFinishedCallback.onAnimationFinished(
-                ANIMATION_TYPE_APP_TRANSITION, surfaceAnimator.getAnimation());
-
-        verify(container).onAnimationLeashLost(any());
-        assertNull(surfaceAnimator.mLeash);
-        assertNull(surfaceAnimator.mSnapshot);
-    }
-
-    @Test
-    public void testUnfreezeWindow_removeWindowFromChanging() {
-        final WindowContainer container = createTaskFragmentWithActivity(
-                createTask(mDisplayContent));
-        mockSurfaceFreezerSnapshot(container.mSurfaceFreezer);
-        final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
-
-        container.initializeChangeTransition(new Rect(0, 0, 1000, 2000));
-
-        assertTrue(mDisplayContent.mChangingContainers.contains(container));
-
-        container.mSurfaceFreezer.unfreeze(t);
-
-        assertFalse(mDisplayContent.mChangingContainers.contains(container));
-    }
-
-    @Test
-    public void testFailToTaskSnapshot_unfreezeWindow() {
-        final WindowContainer container = createTaskFragmentWithActivity(
-                createTask(mDisplayContent));
-        final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
-        spyOn(container.mSurfaceFreezer);
-
-        container.initializeChangeTransition(new Rect(0, 0, 1000, 2000));
-
-        verify(container.mSurfaceFreezer).freeze(any(), any(), any(), any());
-        verify(container.mSurfaceFreezer).unfreeze(any());
-        assertTrue(mDisplayContent.mChangingContainers.isEmpty());
-    }
-
-    @Test
-    public void testRemoveUnstartedFreezeSurfaceWhenFreezeAgain() {
-        final WindowContainer container = createTaskFragmentWithActivity(
-                createTask(mDisplayContent));
-        container.mSurfaceControl = mock(SurfaceControl.class);
-        final SurfaceFreezer surfaceFreezer = container.mSurfaceFreezer;
-        mockSurfaceFreezerSnapshot(surfaceFreezer);
-        final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
-        spyOn(container);
-        doReturn(t).when(container).getPendingTransaction();
-        doReturn(t).when(container).getSyncTransaction();
-
-        // Leash and snapshot created for change transition.
-        container.initializeChangeTransition(new Rect(0, 0, 1000, 2000));
-
-        assertNotNull(surfaceFreezer.mLeash);
-        assertNotNull(surfaceFreezer.mSnapshot);
-
-        final SurfaceControl prevLeash = surfaceFreezer.mLeash;
-        final SurfaceFreezer.Snapshot prevSnapshot = surfaceFreezer.mSnapshot;
-        spyOn(prevSnapshot);
-
-        container.initializeChangeTransition(new Rect(0, 0, 1500, 2500));
-
-        verify(t).remove(prevLeash);
-        verify(prevSnapshot).destroy(t);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTransactionTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTransactionTests.java
index 369600c..dcb6862 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTransactionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTransactionTests.java
@@ -18,20 +18,30 @@
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY;
+import static android.window.WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID;
+import static android.window.WindowContainerTransaction.HierarchyOp.REACHABILITY_EVENT_X;
+import static android.window.WindowContainerTransaction.HierarchyOp.REACHABILITY_EVENT_Y;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.times;
 
 import android.content.Intent;
+import android.os.Binder;
+import android.os.Bundle;
 import android.platform.test.annotations.Presubmit;
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
+import android.window.WindowContainerTransaction.HierarchyOp;
 
 import androidx.annotation.NonNull;
 import androidx.test.filters.SmallTest;
@@ -223,6 +233,31 @@
                 < tda.mChildren.indexOf(desktopOrganizer.mTasks.get(2).getRootTask()));
     }
 
+    @Test
+    public void testAppCompat_setReachabilityOffsets() {
+        final Task task = createTask(/* taskId */ 37);
+        final WindowContainerToken containerToken = task.getTaskInfo().token;
+        spyOn(containerToken);
+        final Binder asBinder = new Binder();
+        doReturn(asBinder).when(containerToken).asBinder();
+        final WindowContainerTransaction wct = new WindowContainerTransaction();
+        wct.setReachabilityOffset(containerToken, /* taskId */ task.mTaskId, 10, 20);
+
+        final List<HierarchyOp> hierarchyOps = wct.getHierarchyOps().stream()
+                .filter(op -> op.getType() == HIERARCHY_OP_TYPE_APP_COMPAT_REACHABILITY)
+                .toList();
+
+        assertEquals(1, hierarchyOps.size());
+        final HierarchyOp appCompatOp = hierarchyOps.getFirst();
+        assertNotNull(appCompatOp);
+        final Bundle appCompatOptions = appCompatOp.getAppCompatOptions();
+
+        assertEquals(task.mTaskId, appCompatOptions.getInt(LAUNCH_KEY_TASK_ID));
+        assertEquals(10, appCompatOptions.getInt(REACHABILITY_EVENT_X));
+        assertEquals(20, appCompatOptions.getInt(REACHABILITY_EVENT_Y));
+        assertSame(asBinder, appCompatOp.getContainer());
+    }
+
     private Task createTask(int taskId) {
         return new Task.Builder(mAtm)
                 .setTaskId(taskId)
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 2c390c5..b16f528 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -78,7 +78,6 @@
 import android.content.res.Configuration;
 import android.graphics.Insets;
 import android.graphics.Rect;
-import android.hardware.HardwareBuffer;
 import android.hardware.display.DisplayManager;
 import android.os.Binder;
 import android.os.Build;
@@ -113,7 +112,6 @@
 import android.window.ClientWindowFrames;
 import android.window.ITaskFragmentOrganizer;
 import android.window.ITransitionPlayer;
-import android.window.ScreenCapture;
 import android.window.StartingWindowInfo;
 import android.window.StartingWindowRemovalInfo;
 import android.window.TaskFragmentOrganizer;
@@ -1112,21 +1110,6 @@
                 displayContent -> displayContent.mMinSizeOfResizeableTaskDp = 1);
     }
 
-    /** Mocks the behavior of taking a snapshot. */
-    void mockSurfaceFreezerSnapshot(SurfaceFreezer surfaceFreezer) {
-        final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
-                mock(ScreenCapture.ScreenshotHardwareBuffer.class);
-        final HardwareBuffer hardwareBuffer = mock(HardwareBuffer.class);
-        spyOn(surfaceFreezer);
-        doReturn(screenshotBuffer).when(surfaceFreezer)
-                .createSnapshotBufferInner(any(), any());
-        doReturn(null).when(surfaceFreezer)
-                .createFromHardwareBufferInner(any());
-        doReturn(hardwareBuffer).when(screenshotBuffer).getHardwareBuffer();
-        doReturn(100).when(hardwareBuffer).getWidth();
-        doReturn(100).when(hardwareBuffer).getHeight();
-    }
-
     static ComponentName getUniqueComponentName() {
         return getUniqueComponentName(DEFAULT_COMPONENT_PACKAGE_NAME);
     }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 7e7a531..cd1c485 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -2747,8 +2747,7 @@
                     isManagedProfileVisible = true;
                 }
             }
-            final ScreenCapture.ScreenshotHardwareBuffer shb =
-                    mWmInternal.takeAssistScreenshot(/* windowTypesToExclude= */ Set.of());
+            final ScreenCapture.ScreenshotHardwareBuffer shb = mWmInternal.takeAssistScreenshot();
             final Bitmap bm = shb != null ? shb.asBitmap() : null;
             // Now that everything is fetched, putting it in the launchIntent.
             if (bm != null) {
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 4d9df46..6fb3bcb 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -416,4 +416,9 @@
     boolean hasForegroundServiceDelegation(in PhoneAccountHandle phoneAccountHandle,
                                                        String callingPackage);
     void setMetricsTestMode(boolean enabled);
+
+    /**
+     * @see TelecomServiceImpl#waitForAudioToUpdate
+     */
+     void waitForAudioToUpdate(boolean expectActive);
 }
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index d164c88..4b175c1 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -618,9 +618,9 @@
     @Deprecated
     public int getMcc() {
         try {
-            return mMcc == null ? 0 : Integer.parseInt(mMcc);
+            return TextUtils.isEmpty(mMcc) ? 0 : Integer.parseInt(mMcc);
         } catch (NumberFormatException e) {
-            Log.w(SubscriptionInfo.class.getSimpleName(), "MCC string is not a number");
+            Log.w(SubscriptionInfo.class.getSimpleName(), "MCC string is not a number: " + mMcc);
             return 0;
         }
     }
@@ -633,9 +633,9 @@
     @Deprecated
     public int getMnc() {
         try {
-            return mMnc == null ? 0 : Integer.parseInt(mMnc);
+            return TextUtils.isEmpty(mMnc) ? 0 : Integer.parseInt(mMnc);
         } catch (NumberFormatException e) {
-            Log.w(SubscriptionInfo.class.getSimpleName(), "MNC string is not a number");
+            Log.w(SubscriptionInfo.class.getSimpleName(), "MNC string is not a number: " + mMnc);
             return 0;
         }
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 73ea68b..504605d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -19432,7 +19432,6 @@
      * and integrity algorithms in use
      * @hide
      */
-    @FlaggedApi(Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY)
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     @SystemApi
     public void setNullCipherNotificationsEnabled(boolean enable) {
@@ -19459,7 +19458,6 @@
      * and integrity algorithms in use
      * @hide
      */
-    @FlaggedApi(Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY)
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @SystemApi
     public boolean isNullCipherNotificationsEnabled() {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
index 18f44dd..eebe49d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
@@ -18,13 +18,12 @@
 
 import android.app.Instrumentation
 import android.content.Intent
-import android.os.UserHandle
 import android.platform.test.annotations.Presubmit
-import android.provider.Settings
 import android.tools.flicker.junit.FlickerBuilderProvider
 import android.tools.flicker.legacy.FlickerBuilder
 import android.tools.flicker.legacy.LegacyFlickerTest
 import android.tools.traces.component.ComponentNameMatcher
+import android.tools.traces.executeShellCommand
 import android.util.Log
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.launcher3.tapl.LauncherInstrumentation
@@ -47,11 +46,8 @@
 ) {
     init {
         tapl.setExpectedRotationCheckEnabled(true)
-        Settings.System.putIntForUser(
-            instrumentation.targetContext.contentResolver,
-            Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY,
-            0,
-            UserHandle.USER_CURRENT_OR_SELF
+        executeShellCommand(
+            "settings put system hide_rotation_lock_toggle_for_accessibility 1"
         )
     }
 
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
index 9e9d014..55d6fd9 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
@@ -87,14 +87,18 @@
         wmHelper: WindowManagerStateHelper,
         device: UiDevice,
         motionEventHelper: MotionEventHelper = MotionEventHelper(getInstrumentation(), TOUCH),
+        shouldUseDragToDesktop: Boolean = false,
     ) {
         innerHelper.launchViaIntent(wmHelper)
-        if (!isInDesktopWindowingMode(wmHelper)) {
+        if (isInDesktopWindowingMode(wmHelper)) return
+        if (shouldUseDragToDesktop) {
             enterDesktopModeWithDrag(
                 wmHelper = wmHelper,
                 device = device,
                 motionEventHelper = motionEventHelper
             )
+        } else {
+            enterDesktopModeFromAppHandleMenu(wmHelper, device)
         }
     }
 
diff --git a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
index 36db955..37bdf6b 100644
--- a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
@@ -1111,9 +1111,9 @@
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
             ),
             TestData(
-                "FULLSCREEN -> Maximizes a task to fit the screen",
+                "FULLSCREEN -> Turns a task into fullscreen",
                 intArrayOf(KeyEvent.KEYCODE_FULLSCREEN),
-                KeyGestureEvent.KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW,
+                KeyGestureEvent.KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION,
                 intArrayOf(KeyEvent.KEYCODE_FULLSCREEN),
                 0,
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
diff --git a/tests/utils/testutils/java/android/os/test/TestLooper.java b/tests/utils/testutils/java/android/os/test/TestLooper.java
index 61fa7b5..83d22d9 100644
--- a/tests/utils/testutils/java/android/os/test/TestLooper.java
+++ b/tests/utils/testutils/java/android/os/test/TestLooper.java
@@ -18,24 +18,18 @@
 
 import static org.junit.Assert.assertTrue;
 
-import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.os.Looper;
 import android.os.Message;
 import android.os.MessageQueue;
 import android.os.SystemClock;
-import android.os.TestLooperManager;
 import android.util.Log;
 
-import androidx.test.InstrumentationRegistry;
-
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.util.ArrayDeque;
-import java.util.Queue;
 import java.util.concurrent.Executor;
 
 /**
@@ -50,9 +44,7 @@
  *     The Robolectric class also allows advancing time.
  */
 public class TestLooper {
-    private final Looper mLooper;
-    private final TestLooperManager mTestLooperManager;
-    private final Clock mClock;
+    protected final Looper mLooper;
 
     private static final Constructor<Looper> LOOPER_CONSTRUCTOR;
     private static final Field THREAD_LOCAL_LOOPER_FIELD;
@@ -62,14 +54,9 @@
     private static final Method MESSAGE_MARK_IN_USE_METHOD;
     private static final String TAG = "TestLooper";
 
-    private AutoDispatchThread mAutoDispatchThread;
+    private final Clock mClock;
 
-    /**
-     * Baklava introduces new {@link TestLooperManager} APIs that we can use instead of reflection.
-     */
-    private static boolean isAtLeastBaklava() {
-        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA;
-    }
+    private AutoDispatchThread mAutoDispatchThread;
 
     static {
         try {
@@ -77,22 +64,14 @@
             LOOPER_CONSTRUCTOR.setAccessible(true);
             THREAD_LOCAL_LOOPER_FIELD = Looper.class.getDeclaredField("sThreadLocal");
             THREAD_LOCAL_LOOPER_FIELD.setAccessible(true);
-
-            if (isAtLeastBaklava()) {
-                MESSAGE_QUEUE_MESSAGES_FIELD = null;
-                MESSAGE_NEXT_FIELD = null;
-                MESSAGE_WHEN_FIELD = null;
-                MESSAGE_MARK_IN_USE_METHOD = null;
-            } else {
-                MESSAGE_QUEUE_MESSAGES_FIELD = MessageQueue.class.getDeclaredField("mMessages");
-                MESSAGE_QUEUE_MESSAGES_FIELD.setAccessible(true);
-                MESSAGE_NEXT_FIELD = Message.class.getDeclaredField("next");
-                MESSAGE_NEXT_FIELD.setAccessible(true);
-                MESSAGE_WHEN_FIELD = Message.class.getDeclaredField("when");
-                MESSAGE_WHEN_FIELD.setAccessible(true);
-                MESSAGE_MARK_IN_USE_METHOD = Message.class.getDeclaredMethod("markInUse");
-                MESSAGE_MARK_IN_USE_METHOD.setAccessible(true);
-            }
+            MESSAGE_QUEUE_MESSAGES_FIELD = MessageQueue.class.getDeclaredField("mMessages");
+            MESSAGE_QUEUE_MESSAGES_FIELD.setAccessible(true);
+            MESSAGE_NEXT_FIELD = Message.class.getDeclaredField("next");
+            MESSAGE_NEXT_FIELD.setAccessible(true);
+            MESSAGE_WHEN_FIELD = Message.class.getDeclaredField("when");
+            MESSAGE_WHEN_FIELD.setAccessible(true);
+            MESSAGE_MARK_IN_USE_METHOD = Message.class.getDeclaredMethod("markInUse");
+            MESSAGE_MARK_IN_USE_METHOD.setAccessible(true);
         } catch (NoSuchFieldException | NoSuchMethodException e) {
             throw new RuntimeException("Failed to initialize TestLooper", e);
         }
@@ -127,13 +106,6 @@
             throw new RuntimeException("Reflection error constructing or accessing looper", e);
         }
 
-        if (isAtLeastBaklava()) {
-            mTestLooperManager =
-                InstrumentationRegistry.getInstrumentation().acquireLooperManager(mLooper);
-        } else {
-            mTestLooperManager = null;
-        }
-
         mClock = clock;
     }
 
@@ -145,72 +117,19 @@
         return new HandlerExecutor(new Handler(getLooper()));
     }
 
-    private Message getMessageLinkedListLegacy() {
+    private Message getMessageLinkedList() {
         try {
             MessageQueue queue = mLooper.getQueue();
             return (Message) MESSAGE_QUEUE_MESSAGES_FIELD.get(queue);
         } catch (IllegalAccessException e) {
             throw new RuntimeException("Access failed in TestLooper: get - MessageQueue.mMessages",
-                e);
+                    e);
         }
     }
 
     public void moveTimeForward(long milliSeconds) {
-        if (isAtLeastBaklava()) {
-            moveTimeForwardBaklava(milliSeconds);
-        } else {
-            moveTimeForwardLegacy(milliSeconds);
-        }
-    }
-
-    private void moveTimeForwardBaklava(long milliSeconds) {
-        // Drain all Messages from the queue.
-        Queue<Message> messages = new ArrayDeque<>();
-        while (true) {
-            Message message = mTestLooperManager.poll();
-            if (message == null) {
-                break;
-            }
-
-            // Adjust the Message's delivery time.
-            long newWhen = message.when - milliSeconds;
-            if (newWhen < 0) {
-                newWhen = 0;
-            }
-            message.when = newWhen;
-            messages.add(message);
-        }
-
-        // Repost all Messages back to the queuewith a new time.
-        while (true) {
-            Message message = messages.poll();
-            if (message == null) {
-                break;
-            }
-
-            Runnable callback = message.getCallback();
-            Handler handler = message.getTarget();
-            long when = message.getWhen();
-
-            // The Message cannot be re-enqueued because it is marked in use.
-            // Make a copy of the Message and recycle the original.
-            // This resets {@link Message#isInUse()} but retains all other content.
-            {
-                Message newMessage = Message.obtain();
-                newMessage.copyFrom(message);
-                newMessage.setCallback(callback);
-                mTestLooperManager.recycle(message);
-                message = newMessage;
-            }
-
-            // Send the Message back to its Handler to be re-enqueued.
-            handler.sendMessageAtTime(message, when);
-        }
-    }
-
-    private void moveTimeForwardLegacy(long milliSeconds) {
         try {
-            Message msg = getMessageLinkedListLegacy();
+            Message msg = getMessageLinkedList();
             while (msg != null) {
                 long updatedWhen = msg.getWhen() - milliSeconds;
                 if (updatedWhen < 0) {
@@ -228,12 +147,12 @@
         return mClock.uptimeMillis();
     }
 
-    private Message messageQueueNextLegacy() {
+    private Message messageQueueNext() {
         try {
             long now = currentTime();
 
             Message prevMsg = null;
-            Message msg = getMessageLinkedListLegacy();
+            Message msg = getMessageLinkedList();
             if (msg != null && msg.getTarget() == null) {
                 // Stalled by a barrier. Find the next asynchronous message in
                 // the queue.
@@ -266,46 +185,18 @@
     /**
      * @return true if there are pending messages in the message queue
      */
-    public boolean isIdle() {
-        if (isAtLeastBaklava()) {
-            return isIdleBaklava();
-        } else {
-            return isIdleLegacy();
-        }
-    }
+    public synchronized boolean isIdle() {
+        Message messageList = getMessageLinkedList();
 
-    private boolean isIdleBaklava() {
-        Long when = mTestLooperManager.peekWhen();
-        return when != null && currentTime() >= when;
-    }
-
-    private synchronized boolean isIdleLegacy() {
-        Message messageList = getMessageLinkedListLegacy();
         return messageList != null && currentTime() >= messageList.getWhen();
     }
 
     /**
      * @return the next message in the Looper's message queue or null if there is none
      */
-    public Message nextMessage() {
-        if (isAtLeastBaklava()) {
-            return nextMessageBaklava();
-        } else {
-            return nextMessageLegacy();
-        }
-    }
-
-    private Message nextMessageBaklava() {
+    public synchronized Message nextMessage() {
         if (isIdle()) {
-            return mTestLooperManager.poll();
-        } else {
-            return null;
-        }
-    }
-
-    private synchronized Message nextMessageLegacy() {
-        if (isIdle()) {
-            return messageQueueNextLegacy();
+            return messageQueueNext();
         } else {
             return null;
         }
@@ -315,26 +206,9 @@
      * Dispatch the next message in the queue
      * Asserts that there is a message in the queue
      */
-    public void dispatchNext() {
-        if (isAtLeastBaklava()) {
-            dispatchNextBaklava();
-        } else {
-            dispatchNextLegacy();
-        }
-    }
-
-    private void dispatchNextBaklava() {
+    public synchronized void dispatchNext() {
         assertTrue(isIdle());
-        Message msg = mTestLooperManager.poll();
-        if (msg == null) {
-            return;
-        }
-        msg.getTarget().dispatchMessage(msg);
-    }
-
-    private synchronized void dispatchNextLegacy() {
-        assertTrue(isIdle());
-        Message msg = messageQueueNextLegacy();
+        Message msg = messageQueueNext();
         if (msg == null) {
             return;
         }
diff --git a/tools/localedata/extract_icu_data.py b/tools/localedata/extract_icu_data.py
index ec53127..899cd7f 100755
--- a/tools/localedata/extract_icu_data.py
+++ b/tools/localedata/extract_icu_data.py
@@ -180,7 +180,14 @@
 
 def dump_representative_locales(representative_locales):
     """Dump the set of representative locales."""
-    print()
+    print('''
+/*
+ * TODO: Consider turning the below switch statement into binary search
+ *      to save the disk space when the table is larger in the future.
+ *      Disassembled code shows that the jump table emitted by clang can be
+ *      4x larger than the data in disk size, but it depends on the optimization option.
+ *      However, a switch statement will benefit from the future of compiler improvement.
+ */''')
     print('bool isLocaleRepresentative(uint32_t language_and_region, const char* script) {')
     print('    const uint64_t packed_locale =')
     print('            ((static_cast<uint64_t>(language_and_region)) << 32u) |')