Merge "Replace user switching events with UserTracker" into tm-qpr-dev
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index c17fbf1..dd95540 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -2523,6 +2523,10 @@
         IAccessibilityServiceConnection connection =
                 AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId);
         if (mInfo != null && connection != null) {
+            if (!mInfo.isWithinParcelableSize()) {
+                throw new IllegalStateException(
+                        "Cannot update service info: size is larger than safe parcelable limits.");
+            }
             try {
                 connection.setServiceInfo(mInfo);
                 mInfo = null;
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 530de0f..0cbcdb5 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -40,6 +40,7 @@
 import android.graphics.drawable.Drawable;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.Build;
+import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
@@ -1128,6 +1129,15 @@
         return 0;
     }
 
+    /** @hide */
+    public final boolean isWithinParcelableSize() {
+        final Parcel parcel = Parcel.obtain();
+        writeToParcel(parcel, 0);
+        final boolean result = parcel.dataSize() <= IBinder.MAX_IPC_SIZE;
+        parcel.recycle();
+        return result;
+    }
+
     public void writeToParcel(Parcel parcel, int flagz) {
         parcel.writeInt(eventTypes);
         parcel.writeStringArray(packageNames);
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index f6d27ad..37a90de 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -317,7 +317,10 @@
 
     /**
      * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
-     * This broadcast is only sent to registered receivers.
+     *
+     * <p>This broadcast is only sent to registered receivers and (starting from
+     * {@link Build.VERSION_CODES#Q}) receivers in packages that have been granted Do Not
+     * Disturb access (see {@link #isNotificationPolicyAccessGranted()}).
      *
      * @hide
      */
@@ -337,7 +340,10 @@
 
     /**
      * Intent that is broadcast when the state of getNotificationPolicy() changes.
-     * This broadcast is only sent to registered receivers.
+     *
+     * <p>This broadcast is only sent to registered receivers and (starting from
+     * {@link Build.VERSION_CODES#Q}) receivers in packages that have been granted Do Not
+     * Disturb access (see {@link #isNotificationPolicyAccessGranted()}).
      */
     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_NOTIFICATION_POLICY_CHANGED
@@ -345,7 +351,10 @@
 
     /**
      * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
-     * This broadcast is only sent to registered receivers.
+     *
+     * <p>This broadcast is only sent to registered receivers and (starting from
+     * {@link Build.VERSION_CODES#Q}) receivers in packages that have been granted Do Not
+     * Disturb access (see {@link #isNotificationPolicyAccessGranted()}).
      */
     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_INTERRUPTION_FILTER_CHANGED
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 3daee1f..809dc3c4 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -5741,14 +5741,13 @@
 
     /**
      * Optional argument to be used with {@link #ACTION_CHOOSER}.
-     * A {@link android.app.PendingIntent} to be sent when the user wants to do payload reselection
-     * in the sharesheet.
-     * A reselection action allows the user to return to the source app to change the content being
-     * shared.
+     * A {@link android.app.PendingIntent} to be sent when the user wants to modify the content that
+     * they're sharing. This can be used to allow the user to return to the source app to, for
+     * example, select different media.
      * @hide
      */
-    public static final String EXTRA_CHOOSER_PAYLOAD_RESELECTION_ACTION =
-            "android.intent.extra.CHOOSER_PAYLOAD_RESELECTION_ACTION";
+    public static final String EXTRA_CHOOSER_MODIFY_SHARE_ACTION =
+            "android.intent.extra.CHOOSER_MODIFY_SHARE_ACTION";
 
     /**
      * An {@code ArrayList} of {@code String} annotations describing content for
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 14d0a56..9d624b6 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -3517,7 +3517,7 @@
      * <p>An array of mandatory stream combinations which are applicable when device support the
      * 10-bit output capability
      * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT }
-     * This is an app-readable conversion of the maximum resolution mandatory stream combination
+     * This is an app-readable conversion of the 10 bit output mandatory stream combination
      * {@link android.hardware.camera2.CameraDevice#createCaptureSession tables}.</p>
      * <p>The array of
      * {@link android.hardware.camera2.params.MandatoryStreamCombination combinations} is
@@ -3542,8 +3542,8 @@
     /**
      * <p>An array of mandatory stream combinations which are applicable when device lists
      * {@code PREVIEW_STABILIZATION} in {@link CameraCharacteristics#CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES android.control.availableVideoStabilizationModes}.
-     * This is an app-readable conversion of the maximum resolution mandatory stream combination
-     * {@link android.hardware.camera2.CameraDevice#createCaptureSession tables}.</p>
+     * This is an app-readable conversion of the preview stabilization mandatory stream
+     * combination {@link android.hardware.camera2.CameraDevice#createCaptureSession tables}.</p>
      * <p>The array of
      * {@link android.hardware.camera2.params.MandatoryStreamCombination combinations} is
      * generated according to the documented
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index c67a560..7055c9c 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -1000,24 +1000,25 @@
      * camera's crop region is set to maximum size, the FOV of the physical streams for the
      * ultrawide lens will be the same as the logical stream, by making the crop region
      * smaller than its active array size to compensate for the smaller focal length.</p>
-     * <p>There are two ways for the application to capture RAW images from a logical camera
-     * with RAW capability:</p>
+     * <p>For a logical camera, typically the underlying physical cameras have different RAW
+     * capabilities (such as resolution or CFA pattern). There are two ways for the
+     * application to capture RAW images from the logical camera:</p>
      * <ul>
-     * <li>Because the underlying physical cameras may have different RAW capabilities (such
-     * as resolution or CFA pattern), to maintain backward compatibility, when a RAW stream
-     * is configured, the camera device makes sure the default active physical camera remains
-     * active and does not switch to other physical cameras. (One exception is that, if the
-     * logical camera consists of identical image sensors and advertises multiple focalLength
-     * due to different lenses, the camera device may generate RAW images from different
-     * physical cameras based on the focalLength being set by the application.) This
-     * backward-compatible approach usually results in loss of optical zoom, to telephoto
-     * lens or to ultrawide lens.</li>
-     * <li>Alternatively, to take advantage of the full zoomRatio range of the logical camera,
-     * the application should use {@link android.hardware.camera2.MultiResolutionImageReader }
-     * to capture RAW images from the currently active physical camera. Because different
-     * physical camera may have different RAW characteristics, the application needs to use
-     * the characteristics and result metadata of the active physical camera for the
-     * relevant RAW metadata.</li>
+     * <li>If the logical camera has RAW capability, the application can create and use RAW
+     * streams in the same way as before. In case a RAW stream is configured, to maintain
+     * backward compatibility, the camera device makes sure the default active physical
+     * camera remains active and does not switch to other physical cameras. (One exception
+     * is that, if the logical camera consists of identical image sensors and advertises
+     * multiple focalLength due to different lenses, the camera device may generate RAW
+     * images from different physical cameras based on the focalLength being set by the
+     * application.) This backward-compatible approach usually results in loss of optical
+     * zoom, to telephoto lens or to ultrawide lens.</li>
+     * <li>Alternatively, if supported by the device,
+     * {@link android.hardware.camera2.MultiResolutionImageReader }
+     * can be used to capture RAW images from one of the underlying physical cameras (
+     * depending on current zoom level). Because different physical cameras may have
+     * different RAW characteristics, the application needs to use the characteristics
+     * and result metadata of the active physical camera for the relevant RAW metadata.</li>
      * </ul>
      * <p>The capture request and result metadata tags required for backward compatible camera
      * functionalities will be solely based on the logical camera capability. On the other
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ce29c73..10e1633 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9922,7 +9922,7 @@
 
         /**
          * If active unlock triggers on unlock intents, then also request active unlock on
-         * these wake-up reasons. See PowerManager.WakeReason for value mappings.
+         * these wake-up reasons. See {@link PowerManager.WakeReason} for value mappings.
          * WakeReasons should be separated by a pipe. For example: "0|3" or "0". If this
          * setting should be disabled, then this should be set to an empty string. A null value
          * will use the system default value (WAKE_REASON_UNFOLD_DEVICE).
@@ -9932,6 +9932,17 @@
                 "active_unlock_wakeups_considered_unlock_intents";
 
         /**
+         * If active unlock triggers and succeeds on these wakeups, force dismiss keyguard on
+         * these wake reasons. See {@link PowerManager#WakeReason} for value mappings.
+         * WakeReasons should be separated by a pipe. For example: "0|3" or "0". If this
+         * setting should be disabled, then this should be set to an empty string. A null value
+         * will use the system default value (WAKE_REASON_UNFOLD_DEVICE).
+         * @hide
+         */
+        public static final String ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD =
+                "active_unlock_wakeups_to_force_dismiss_keyguard";
+
+        /**
          * Whether the assist gesture should be enabled.
          *
          * @hide
diff --git a/core/java/android/service/dreams/DreamActivity.java b/core/java/android/service/dreams/DreamActivity.java
index a2fa139..a389223 100644
--- a/core/java/android/service/dreams/DreamActivity.java
+++ b/core/java/android/service/dreams/DreamActivity.java
@@ -58,11 +58,13 @@
             setTitle(title);
         }
 
-        final Bundle extras = getIntent().getExtras();
-        mCallback = (DreamService.DreamActivityCallbacks) extras.getBinder(EXTRA_CALLBACK);
-
-        if (mCallback != null) {
+        final Object callback = getIntent().getExtras().getBinder(EXTRA_CALLBACK);
+        if (callback instanceof DreamService.DreamActivityCallbacks) {
+            mCallback = (DreamService.DreamActivityCallbacks) callback;
             mCallback.onActivityCreated(this);
+        } else {
+            mCallback = null;
+            finishAndRemoveTask();
         }
     }
 
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index e285b1c..9d8c963 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -953,7 +953,7 @@
 
     private static Uri safeUri(TypedXmlPullParser parser, String att) {
         final String val = parser.getAttributeValue(null, att);
-        if (TextUtils.isEmpty(val)) return null;
+        if (val == null) return null;
         return Uri.parse(val);
     }
 
diff --git a/core/java/android/service/quickaccesswallet/OWNERS b/core/java/android/service/quickaccesswallet/OWNERS
new file mode 100644
index 0000000..232ee02
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 802986
+asc@google.com
+juliacr@google.com
+steell@google.com
diff --git a/core/java/android/service/quickaccesswallet/WalletCard.java b/core/java/android/service/quickaccesswallet/WalletCard.java
index 7aacb9b..e234755 100644
--- a/core/java/android/service/quickaccesswallet/WalletCard.java
+++ b/core/java/android/service/quickaccesswallet/WalletCard.java
@@ -36,7 +36,7 @@
  * card, library card, transit pass, etc. Cards are identified by a String identifier and contain a
  * card type, card image, card image content description, and a {@link PendingIntent} to be used if
  * the user clicks on the card. Cards may be displayed with an icon and label, though these are
- * optional. Valuable cards will also have a second image that will be displayed when the card is
+ * optional. Non-payment cards will also have a second image that will be displayed when the card is
  * tapped.
  */
 
@@ -56,11 +56,11 @@
     public static final int CARD_TYPE_PAYMENT = 1;
 
     /**
-     * Valuable cards refer to any cards that are not used for cash-equivalent payment.
-     * This includes event tickets, flights, offers, loyalty cards, gift cards and transit tickets.
+     * Non-payment cards refer to any cards that are not used for cash-equivalent payment, including
+     * event tickets, flights, offers, loyalty cards, gift cards and transit tickets.
      * @hide
      */
-    public static final int CARD_TYPE_VALUABLE = 2;
+    public static final int CARD_TYPE_NON_PAYMENT = 2;
 
     private final String mCardId;
     private final int mCardType;
@@ -69,7 +69,7 @@
     private final PendingIntent mPendingIntent;
     private final Icon mCardIcon;
     private final CharSequence mCardLabel;
-    private final Icon mValuableCardSecondaryImage;
+    private final Icon mNonPaymentCardSecondaryImage;
 
     private WalletCard(Builder builder) {
         this.mCardId = builder.mCardId;
@@ -79,7 +79,7 @@
         this.mPendingIntent = builder.mPendingIntent;
         this.mCardIcon = builder.mCardIcon;
         this.mCardLabel = builder.mCardLabel;
-        this.mValuableCardSecondaryImage = builder.mValuableCardSecondaryImage;
+        this.mNonPaymentCardSecondaryImage = builder.mNonPaymentCardSecondaryImage;
     }
 
     /**
@@ -89,7 +89,7 @@
     @IntDef(prefix = {"CARD_TYPE_"}, value = {
             CARD_TYPE_UNKNOWN,
             CARD_TYPE_PAYMENT,
-            CARD_TYPE_VALUABLE
+            CARD_TYPE_NON_PAYMENT
     })
     public @interface CardType {
     }
@@ -108,7 +108,7 @@
         PendingIntent.writePendingIntentOrNullToParcel(mPendingIntent, dest);
         writeIconIfNonNull(mCardIcon, dest, flags);
         TextUtils.writeToParcel(mCardLabel, dest, flags);
-        writeIconIfNonNull(mValuableCardSecondaryImage, dest, flags);
+        writeIconIfNonNull(mNonPaymentCardSecondaryImage, dest, flags);
 
     }
 
@@ -131,14 +131,14 @@
         PendingIntent pendingIntent = PendingIntent.readPendingIntentOrNullFromParcel(source);
         Icon cardIcon = source.readByte() == 0 ? null : Icon.CREATOR.createFromParcel(source);
         CharSequence cardLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
-        Icon valuableCardSecondaryImage = source.readByte() == 0 ? null :
+        Icon nonPaymentCardSecondaryImage = source.readByte() == 0 ? null :
                 Icon.CREATOR.createFromParcel(source);
         Builder builder = new Builder(cardId, cardType, cardImage, contentDesc, pendingIntent)
                 .setCardIcon(cardIcon)
                 .setCardLabel(cardLabel);
 
-        return cardType == CARD_TYPE_VALUABLE
-                ? builder.setValuableCardSecondaryImage(valuableCardSecondaryImage).build() :
+        return cardType == CARD_TYPE_NON_PAYMENT
+                ? builder.setNonPaymentCardSecondaryImage(nonPaymentCardSecondaryImage).build() :
                  builder.build();
     }
 
@@ -229,13 +229,13 @@
     }
 
     /**
-    * Visual representation of the card when it is tapped. Includes a barcode to scan the card in
-     * addition to the information in the primary image.
+     * Visual representation of the card when it is tapped. May include additional information
+     *  unique to the card, such as a barcode or number. Only valid for CARD_TYPE_NON_PAYMENT.
      * @hide
-    */
+     */
     @Nullable
-    public Icon getValuableCardSecondaryImage() {
-        return mValuableCardSecondaryImage;
+    public Icon getNonPaymentCardSecondaryImage() {
+        return mNonPaymentCardSecondaryImage;
     }
 
     /**
@@ -251,7 +251,7 @@
         private PendingIntent mPendingIntent;
         private Icon mCardIcon;
         private CharSequence mCardLabel;
-        private Icon mValuableCardSecondaryImage;
+        private Icon mNonPaymentCardSecondaryImage;
 
         /**
          * @param cardId             The card id must be non-null and unique within the list of
@@ -259,7 +259,7 @@
          *                           </b> this card ID should <b>not</b> contain PII (Personally
          *                           Identifiable Information, such as username or email address).
          * @param cardType           Integer representing the card type. The card type must be
-         *                           non-null. If not provided, it defaults to unknown.
+         *                           non-null.
          * @param cardImage          The visual representation of the card. If the card image Icon
          *                           is a bitmap, it should have a width of {@link
          *                           GetWalletCardsRequest#getCardWidthPx()} and a height of {@link
@@ -294,7 +294,7 @@
         }
 
         /**
-         * Called when a card type is not provided.
+         * Called when a card type is not provided, in which case it defaults to CARD_TYPE_UNKNOWN.
          */
         public Builder(@NonNull String cardId,
                 @NonNull Icon cardImage,
@@ -336,15 +336,16 @@
         }
 
         /**
-         * Visual representation of the card when it is tapped. Includes a barcode to scan the card
-         * in addition to the information in the primary image.
+         * Visual representation of the card when it is tapped. May include additional information
+         *  unique to the card, such as a barcode or number. Only valid for CARD_TYPE_NON_PAYMENT.
          * @hide
          */
         @NonNull
-        public Builder setValuableCardSecondaryImage(@Nullable Icon valuableCardSecondaryImage) {
-            Preconditions.checkState(mCardType == CARD_TYPE_VALUABLE,
-                    "This field can only be set on valuable cards");
-            mValuableCardSecondaryImage = valuableCardSecondaryImage;
+        public Builder
+                setNonPaymentCardSecondaryImage(@Nullable Icon nonPaymentCardSecondaryImage) {
+            Preconditions.checkState(mCardType == CARD_TYPE_NON_PAYMENT,
+                    "This field can only be set on non-payment cards");
+            mNonPaymentCardSecondaryImage = nonPaymentCardSecondaryImage;
             return this;
         }
 
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index e27af17..d53ad17 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -61,6 +61,7 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
@@ -180,6 +181,9 @@
     private final ArrayList<Engine> mActiveEngines
             = new ArrayList<Engine>();
 
+    private Handler mBackgroundHandler;
+    private HandlerThread mBackgroundThread;
+
     static final class WallpaperCommand {
         String action;
         int x;
@@ -198,14 +202,6 @@
      */
     public class Engine {
         IWallpaperEngineWrapper mIWallpaperEngine;
-        final ArraySet<RectF> mLocalColorAreas = new ArraySet<>(4);
-        final ArraySet<RectF> mLocalColorsToAdd = new ArraySet<>(4);
-
-        // 2D matrix [x][y] to represent a page of a portion of a window
-        EngineWindowPage[] mWindowPages = new EngineWindowPage[0];
-        Bitmap mLastScreenshot;
-        int mLastWindowPage = -1;
-        private boolean mResetWindowPages;
 
         // Copies from mIWallpaperEngine.
         HandlerCaller mCaller;
@@ -267,11 +263,27 @@
 
         final Object mLock = new Object();
         boolean mOffsetMessageEnqueued;
+
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
         float mPendingXOffset;
         float mPendingYOffset;
         float mPendingXOffsetStep;
         float mPendingYOffsetStep;
+
+        /**
+         * local color extraction related fields
+         * to be used by the background thread only (except the atomic boolean)
+         */
+        final ArraySet<RectF> mLocalColorAreas = new ArraySet<>(4);
+        final ArraySet<RectF> mLocalColorsToAdd = new ArraySet<>(4);
+        private long mLastProcessLocalColorsTimestamp;
+        private AtomicBoolean mProcessLocalColorsPending = new AtomicBoolean(false);
+        private int mPixelCopyCount = 0;
+        // 2D matrix [x][y] to represent a page of a portion of a window
+        EngineWindowPage[] mWindowPages = new EngineWindowPage[0];
+        Bitmap mLastScreenshot;
+        private boolean mResetWindowPages;
+
         boolean mPendingSync;
         MotionEvent mPendingMove;
         boolean mIsInAmbientMode;
@@ -280,12 +292,8 @@
         private long mLastColorInvalidation;
         private final Runnable mNotifyColorsChanged = this::notifyColorsChanged;
 
-        // used to throttle processLocalColors
-        private long mLastProcessLocalColorsTimestamp;
-        private AtomicBoolean mProcessLocalColorsPending = new AtomicBoolean(false);
         private final Supplier<Long> mClockFunction;
         private final Handler mHandler;
-
         private Display mDisplay;
         private Context mDisplayContext;
         private int mDisplayState;
@@ -825,7 +833,7 @@
                             + "was not established.");
                 }
                 mResetWindowPages = true;
-                processLocalColors(mPendingXOffset, mPendingXOffsetStep);
+                processLocalColors();
             } catch (RemoteException e) {
                 Log.w(TAG, "Can't notify system because wallpaper connection was lost.", e);
             }
@@ -1364,7 +1372,7 @@
                             resetWindowPages();
                             mSession.finishDrawing(mWindow, null /* postDrawTransaction */,
                                                    Integer.MAX_VALUE);
-                            processLocalColors(mPendingXOffset, mPendingXOffsetStep);
+                            processLocalColors();
                         }
                         reposition();
                         reportEngineShown(shouldWaitForEngineShown());
@@ -1509,7 +1517,7 @@
             if (!mDestroyed) {
                 mVisible = visible;
                 reportVisibility();
-                if (mReportedVisible) processLocalColors(mPendingXOffset, mPendingXOffsetStep);
+                if (mReportedVisible) processLocalColors();
             } else {
                 AnimationHandler.requestAnimatorsEnabled(visible, this);
             }
@@ -1593,31 +1601,41 @@
             }
 
             // setup local color extraction data
-            processLocalColors(xOffset, xOffsetStep);
+            processLocalColors();
         }
 
         /**
          * Thread-safe util to call {@link #processLocalColorsInternal} with a minimum interval of
          * {@link #PROCESS_LOCAL_COLORS_INTERVAL_MS} between two calls.
          */
-        private void processLocalColors(float xOffset, float xOffsetStep) {
+        private void processLocalColors() {
             if (mProcessLocalColorsPending.compareAndSet(false, true)) {
                 final long now = mClockFunction.get();
                 final long timeSinceLastColorProcess = now - mLastProcessLocalColorsTimestamp;
                 final long timeToWait = Math.max(0,
                         PROCESS_LOCAL_COLORS_INTERVAL_MS - timeSinceLastColorProcess);
 
-                mHandler.postDelayed(() -> {
+                mBackgroundHandler.postDelayed(() -> {
                     mLastProcessLocalColorsTimestamp = now + timeToWait;
                     mProcessLocalColorsPending.set(false);
-                    processLocalColorsInternal(xOffset, xOffsetStep);
+                    processLocalColorsInternal();
                 }, timeToWait);
             }
         }
 
-        private void processLocalColorsInternal(float xOffset, float xOffsetStep) {
+        private void processLocalColorsInternal() {
             // implemented by the wallpaper
             if (supportsLocalColorExtraction()) return;
+            assertBackgroundThread();
+            float xOffset;
+            float xOffsetStep;
+            float wallpaperDimAmount;
+            synchronized (mLock) {
+                xOffset = mPendingXOffset;
+                xOffsetStep = mPendingXOffsetStep;
+                wallpaperDimAmount = mWallpaperDimAmount;
+            }
+
             if (DEBUG) {
                 Log.d(TAG, "processLocalColors " + xOffset + " of step "
                         + xOffsetStep);
@@ -1680,7 +1698,7 @@
                 xPage = mWindowPages.length - 1;
             }
             current = mWindowPages[xPage];
-            updatePage(current, xPage, xPages, finalXOffsetStep);
+            updatePage(current, xPage, xPages, wallpaperDimAmount);
             Trace.endSection();
         }
 
@@ -1700,16 +1718,23 @@
             }
         }
 
+        /**
+         * Must be called with the surface lock held.
+         * Must not be called if the surface is not valid.
+         * Will unlock the surface when done using it.
+         */
         void updatePage(EngineWindowPage currentPage, int pageIndx, int numPages,
-                float xOffsetStep) {
+                float wallpaperDimAmount) {
+
+            assertBackgroundThread();
+
             // in case the clock is zero, we start with negative time
             long current = SystemClock.elapsedRealtime() - DEFAULT_UPDATE_SCREENSHOT_DURATION;
             long lapsed = current - currentPage.getLastUpdateTime();
             // Always update the page when the last update time is <= 0
             // This is important especially when the device first boots
-            if (lapsed < DEFAULT_UPDATE_SCREENSHOT_DURATION) {
-                return;
-            }
+            if (lapsed < DEFAULT_UPDATE_SCREENSHOT_DURATION) return;
+
             Surface surface = mSurfaceHolder.getSurface();
             if (!surface.isValid()) return;
             boolean widthIsLarger = mSurfaceSize.x > mSurfaceSize.y;
@@ -1725,33 +1750,42 @@
             Bitmap screenShot = Bitmap.createBitmap(width, height,
                     Bitmap.Config.ARGB_8888);
             final Bitmap finalScreenShot = screenShot;
-            Trace.beginSection("WallpaperService#pixelCopy");
-            PixelCopy.request(surface, screenShot, (res) -> {
-                Trace.endSection();
-                if (DEBUG) Log.d(TAG, "result of pixel copy is " + res);
-                if (res != PixelCopy.SUCCESS) {
-                    Bitmap lastBitmap = currentPage.getBitmap();
-                    // assign the last bitmap taken for now
-                    currentPage.setBitmap(mLastScreenshot);
-                    Bitmap lastScreenshot = mLastScreenshot;
-                    if (lastScreenshot != null && !lastScreenshot.isRecycled()
-                            && !Objects.equals(lastBitmap, lastScreenshot)) {
-                        updatePageColors(currentPage, pageIndx, numPages, xOffsetStep);
+            final String pixelCopySectionName = "WallpaperService#pixelCopy";
+            final int pixelCopyCount = mPixelCopyCount++;
+            Trace.beginAsyncSection(pixelCopySectionName, pixelCopyCount);
+            try {
+                PixelCopy.request(surface, screenShot, (res) -> {
+                    Trace.endAsyncSection(pixelCopySectionName, pixelCopyCount);
+                    if (DEBUG) Log.d(TAG, "result of pixel copy is " + res);
+                    if (res != PixelCopy.SUCCESS) {
+                        Bitmap lastBitmap = currentPage.getBitmap();
+                        // assign the last bitmap taken for now
+                        currentPage.setBitmap(mLastScreenshot);
+                        Bitmap lastScreenshot = mLastScreenshot;
+                        if (lastScreenshot != null && !lastScreenshot.isRecycled()
+                                && !Objects.equals(lastBitmap, lastScreenshot)) {
+                            updatePageColors(currentPage, pageIndx, numPages, wallpaperDimAmount);
+                        }
+                    } else {
+                        mLastScreenshot = finalScreenShot;
+                        // going to hold this lock for a while
+                        currentPage.setBitmap(finalScreenShot);
+                        currentPage.setLastUpdateTime(current);
+                        updatePageColors(currentPage, pageIndx, numPages, wallpaperDimAmount);
                     }
-                } else {
-                    mLastScreenshot = finalScreenShot;
-                    // going to hold this lock for a while
-                    currentPage.setBitmap(finalScreenShot);
-                    currentPage.setLastUpdateTime(current);
-                    updatePageColors(currentPage, pageIndx, numPages, xOffsetStep);
-                }
-            }, mHandler);
-
+                }, mBackgroundHandler);
+            } catch (IllegalArgumentException e) {
+                // this can potentially happen if the surface is invalidated right between the
+                // surface.isValid() check and the PixelCopy operation.
+                // in this case, stop: we'll compute colors on the next processLocalColors call.
+                Log.i(TAG, "Cancelling processLocalColors: exception caught during PixelCopy");
+            }
         }
         // locked by the passed page
-        private void updatePageColors(EngineWindowPage page, int pageIndx, int numPages,
-                float xOffsetStep) {
+        private void updatePageColors(
+                EngineWindowPage page, int pageIndx, int numPages, float wallpaperDimAmount) {
             if (page.getBitmap() == null) return;
+            assertBackgroundThread();
             Trace.beginSection("WallpaperService#updatePageColors");
             if (DEBUG) {
                 Log.d(TAG, "updatePageColorsLocked for page " + pageIndx + " with areas "
@@ -1773,7 +1807,7 @@
                     Log.e(TAG, "Error creating page local color bitmap", e);
                     continue;
                 }
-                WallpaperColors color = WallpaperColors.fromBitmap(target, mWallpaperDimAmount);
+                WallpaperColors color = WallpaperColors.fromBitmap(target, wallpaperDimAmount);
                 target.recycle();
                 WallpaperColors currentColor = page.getColors(area);
 
@@ -1790,17 +1824,26 @@
                                 + " local color callback for area" + area + " for page " + pageIndx
                                 + " of " + numPages);
                     }
-                    try {
-                        mConnection.onLocalWallpaperColorsChanged(area, color,
-                                mDisplayContext.getDisplayId());
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Error calling Connection.onLocalWallpaperColorsChanged", e);
-                    }
+                    mHandler.post(() -> {
+                        try {
+                            mConnection.onLocalWallpaperColorsChanged(area, color,
+                                    mDisplayContext.getDisplayId());
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "Error calling Connection.onLocalWallpaperColorsChanged", e);
+                        }
+                    });
                 }
             }
             Trace.endSection();
         }
 
+        private void assertBackgroundThread() {
+            if (!mBackgroundHandler.getLooper().isCurrentThread()) {
+                throw new IllegalStateException(
+                        "ProcessLocalColors should be called from the background thread");
+            }
+        }
+
         private RectF generateSubRect(RectF in, int pageInx, int numPages) {
             float minLeft = (float) (pageInx) / (float) (numPages);
             float maxRight = (float) (pageInx + 1) / (float) (numPages);
@@ -1825,7 +1868,6 @@
             if (supportsLocalColorExtraction()) return;
             if (!mResetWindowPages) return;
             mResetWindowPages = false;
-            mLastWindowPage = -1;
             for (int i = 0; i < mWindowPages.length; i++) {
                 mWindowPages[i].setLastUpdateTime(0L);
             }
@@ -1851,12 +1893,10 @@
             if (DEBUG) {
                 Log.d(TAG, "addLocalColorsAreas adding local color areas " + regions);
             }
-            mHandler.post(() -> {
+            mBackgroundHandler.post(() -> {
                 mLocalColorsToAdd.addAll(regions);
-                processLocalColors(mPendingXOffset, mPendingYOffset);
+                processLocalColors();
             });
-
-
         }
 
         /**
@@ -1866,7 +1906,7 @@
          */
         public void removeLocalColorsAreas(@NonNull List<RectF> regions) {
             if (supportsLocalColorExtraction()) return;
-            mHandler.post(() -> {
+            mBackgroundHandler.post(() -> {
                 float step = mPendingXOffsetStep;
                 mLocalColorsToAdd.removeAll(regions);
                 mLocalColorAreas.removeAll(regions);
@@ -2497,6 +2537,9 @@
     @Override
     public void onCreate() {
         Trace.beginSection("WPMS.onCreate");
+        mBackgroundThread = new HandlerThread("DefaultWallpaperLocalColorExtractor");
+        mBackgroundThread.start();
+        mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
         super.onCreate();
         Trace.endSection();
     }
@@ -2509,6 +2552,7 @@
             mActiveEngines.get(i).detach();
         }
         mActiveEngines.clear();
+        mBackgroundThread.quitSafely();
         Trace.endSection();
     }
 
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 6fed26c..3a0e09d 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -81,6 +81,7 @@
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.text.format.DateUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
@@ -201,6 +202,7 @@
     public static final int RESET_REASON_ADB_COMMAND = 2;
     public static final int RESET_REASON_FULL_CHARGE = 3;
     public static final int RESET_REASON_MEASURED_ENERGY_BUCKETS_CHANGE = 4;
+    public static final int RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION = 5;
 
     protected Clock mClock;
 
@@ -387,6 +389,89 @@
         }
     }
 
+    /** Provide BatteryStatsImpl configuration choices */
+    public static class BatteryStatsConfig {
+        static final int RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG = 1 << 0;
+        static final int RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG = 1 << 1;
+
+        private final int mFlags;
+
+        private BatteryStatsConfig(Builder builder) {
+            int flags = 0;
+            if (builder.mResetOnUnplugHighBatteryLevel) {
+                flags |= RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG;
+            }
+            if (builder.mResetOnUnplugAfterSignificantCharge) {
+                flags |= RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG;
+            }
+            mFlags = flags;
+        }
+
+        /**
+         * Returns whether a BatteryStats reset should occur on unplug when the battery level is
+         * high.
+         */
+        boolean shouldResetOnUnplugHighBatteryLevel() {
+            return (mFlags & RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG)
+                    == RESET_ON_UNPLUG_HIGH_BATTERY_LEVEL_FLAG;
+        }
+
+        /**
+         * Returns whether a BatteryStats reset should occur on unplug if the battery charge a
+         * significant amount since it has been plugged in.
+         */
+        boolean shouldResetOnUnplugAfterSignificantCharge() {
+            return (mFlags & RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG)
+                    == RESET_ON_UNPLUG_AFTER_SIGNIFICANT_CHARGE_FLAG;
+        }
+
+        /**
+         * Builder for BatteryStatsConfig
+         */
+        public static class Builder {
+            private boolean mResetOnUnplugHighBatteryLevel;
+            private boolean mResetOnUnplugAfterSignificantCharge;
+            public Builder() {
+                mResetOnUnplugHighBatteryLevel = true;
+                mResetOnUnplugAfterSignificantCharge = true;
+            }
+
+            /**
+             * Build the BatteryStatsConfig.
+             */
+            public BatteryStatsConfig build() {
+                return new BatteryStatsConfig(this);
+            }
+
+            /**
+             * Set whether a BatteryStats reset should occur on unplug when the battery level is
+             * high.
+             */
+            public Builder setResetOnUnplugHighBatteryLevel(boolean reset) {
+                mResetOnUnplugHighBatteryLevel = reset;
+                return this;
+            }
+
+            /**
+             * Set whether a BatteryStats reset should occur on unplug if the battery charge a
+             * significant amount since it has been plugged in.
+             */
+            public Builder setResetOnUnplugAfterSignificantCharge(boolean reset) {
+                mResetOnUnplugAfterSignificantCharge = reset;
+                return this;
+            }
+        }
+
+    }
+
+    /** Handles calls to AlarmManager */
+    public interface AlarmInterface {
+        /** Schedule an RTC alarm */
+        void schedule(long rtcTimeMs, long windowLengthMs);
+        /** Cancel the previously scheduled alarm */
+        void cancel();
+    }
+
     private final PlatformIdleStateCallback mPlatformIdleStateCallback;
 
     private final Runnable mDeferSetCharging = new Runnable() {
@@ -717,6 +802,7 @@
     protected boolean mHaveBatteryLevel = false;
     protected boolean mRecordingHistory = false;
     int mNumHistoryItems;
+    private long mBatteryPluggedInRealTimeMs = 0;
 
     private static final int HISTORY_TAG_INDEX_LIMIT = 0x7ffe;
     private static final int MAX_HISTORY_TAG_STRING_LENGTH = 1024;
@@ -1459,6 +1545,13 @@
     @GuardedBy("this")
     protected final Constants mConstants;
 
+    @VisibleForTesting
+    @GuardedBy("this")
+    protected BatteryStatsConfig mBatteryStatsConfig = new BatteryStatsConfig.Builder().build();
+
+    @VisibleForTesting
+    protected AlarmInterface mLongPlugInAlarmInterface = null;
+
     /*
      * Holds a SamplingTimer associated with each Resource Power Manager state and voter,
      * recording their times when on-battery (regardless of screen state).
@@ -1625,12 +1718,13 @@
     public BatteryStatsImpl(Clock clock, File historyDirectory) {
         init(clock);
         mStartClockTimeMs = clock.currentTimeMillis();
-        mCheckinFile = null;
         mDailyFile = null;
         if (historyDirectory == null) {
+            mCheckinFile = null;
             mStatsFile = null;
             mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer);
         } else {
+            mCheckinFile = new AtomicFile(new File(historyDirectory, "batterystats-checkin.bin"));
             mStatsFile = new AtomicFile(new File(historyDirectory, "batterystats.bin"));
             mBatteryStatsHistory = new BatteryStatsHistory(this, historyDirectory, mHistoryBuffer);
         }
@@ -12548,6 +12642,27 @@
     }
 
     /**
+     * Injects BatteryStatsConfig
+     */
+    public void setBatteryStatsConfig(BatteryStatsConfig config) {
+        synchronized (this) {
+            mBatteryStatsConfig = config;
+        }
+    }
+
+    /**
+     * Injects a LongPlugInAlarmHandler
+     */
+    public void setLongPlugInAlarmInterface(AlarmInterface longPlugInAlarmInterface) {
+        synchronized (this) {
+            mLongPlugInAlarmInterface = longPlugInAlarmInterface;
+            if (!mOnBattery) {
+                scheduleNextResetWhilePluggedInCheck();
+            }
+        }
+    }
+
+    /**
      * Starts tracking CPU time-in-state for threads of the system server process,
      * keeping a separate account of threads receiving incoming binder calls.
      */
@@ -13019,12 +13134,12 @@
     }
 
     @GuardedBy("this")
-    public void resetAllStatsCmdLocked() {
+    public void resetAllStatsAndHistoryLocked(int reason) {
         final long mSecUptime = mClock.uptimeMillis();
         long uptimeUs = mSecUptime * 1000;
         long mSecRealtime = mClock.elapsedRealtime();
         long realtimeUs = mSecRealtime * 1000;
-        resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_ADB_COMMAND);
+        resetAllStatsLocked(mSecUptime, mSecRealtime, reason);
         mDischargeStartLevel = mHistoryCur.batteryLevel;
         pullPendingStateUpdatesLocked();
         addHistoryRecordLocked(mSecRealtime, mSecUptime);
@@ -15498,6 +15613,73 @@
     }
 
     /**
+     * Might reset battery stats if conditions are met. Assumed the device is currently plugged in.
+     */
+    @GuardedBy("this")
+    public void maybeResetWhilePluggedInLocked() {
+        final long elapsedRealtimeMs = mClock.elapsedRealtime();
+        if (shouldResetWhilePluggedInLocked(elapsedRealtimeMs)) {
+            Slog.i(TAG,
+                    "Resetting due to long plug in duration. elapsed time = " + elapsedRealtimeMs
+                            + " ms, last plug in time = " + mBatteryPluggedInRealTimeMs
+                            + " ms, last reset time = " + mRealtimeStartUs / 1000);
+            resetAllStatsAndHistoryLocked(RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION);
+        }
+
+        scheduleNextResetWhilePluggedInCheck();
+    }
+
+    @GuardedBy("this")
+    private void scheduleNextResetWhilePluggedInCheck() {
+        if (mLongPlugInAlarmInterface != null) {
+            final long timeoutMs = mClock.currentTimeMillis()
+                    + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS
+                    * DateUtils.HOUR_IN_MILLIS;
+            Calendar nextAlarm = Calendar.getInstance();
+            nextAlarm.setTimeInMillis(timeoutMs);
+
+            // Find the 2 AM the same day as the end of the minimum duration.
+            // This logic does not handle a Daylight Savings transition, or a timezone change
+            // while the alarm has been set. The need to reset after a long period while plugged
+            // in is not strict enough to warrant a well architected out solution.
+            nextAlarm.set(Calendar.MILLISECOND, 0);
+            nextAlarm.set(Calendar.SECOND, 0);
+            nextAlarm.set(Calendar.MINUTE, 0);
+            nextAlarm.set(Calendar.HOUR_OF_DAY, 2);
+            long nextTimeMs = nextAlarm.getTimeInMillis();
+            if (nextTimeMs < timeoutMs) {
+                // The 2AM on the day of the timeout, move on the next day.
+                nextTimeMs += DateUtils.DAY_IN_MILLIS;
+            }
+            mLongPlugInAlarmInterface.schedule(nextTimeMs, DateUtils.HOUR_IN_MILLIS);
+        }
+    }
+
+
+    @GuardedBy("this")
+    private boolean shouldResetWhilePluggedInLocked(long elapsedRealtimeMs) {
+        if (mNoAutoReset) return false;
+        if (!mSystemReady) return false;
+
+        final long pluggedInThresholdMs = mBatteryPluggedInRealTimeMs
+                + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS
+                * DateUtils.HOUR_IN_MILLIS;
+        if (elapsedRealtimeMs >= pluggedInThresholdMs) {
+            // The device has been plugged in for a long time.
+            final long resetThresholdMs = mRealtimeStartUs / 1000
+                    + mConstants.RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS
+                    * DateUtils.HOUR_IN_MILLIS;
+            if (elapsedRealtimeMs >= resetThresholdMs) {
+                // And it has been a long time since the last reset.
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+
+    /**
      * Notifies BatteryStatsImpl that the system server is ready.
      */
     public void onSystemReady() {
@@ -15505,6 +15687,32 @@
     }
 
     @GuardedBy("this")
+    private boolean shouldResetOnUnplugLocked(int batteryStatus, int batteryLevel) {
+        if (mNoAutoReset) return false;
+        if (!mSystemReady) return false;
+        if (mBatteryStatsConfig.shouldResetOnUnplugHighBatteryLevel()) {
+            // Allow resetting due to currently being at high battery level
+            if (batteryStatus == BatteryManager.BATTERY_STATUS_FULL) return true;
+            if (batteryLevel >= 90) return true;
+        }
+        if (mBatteryStatsConfig.shouldResetOnUnplugAfterSignificantCharge()) {
+            // Allow resetting after a significant charge (from a very low level to a now very
+            // high level).
+            if (mDischargePlugLevel < 20 && batteryLevel >= 80) return true;
+        }
+        if (getHighDischargeAmountSinceCharge() >= 200) {
+            // Reset the stats if battery got partially charged and discharged repeatedly without
+            // ever reaching the full charge.
+            // This reset is done in order to prevent stats sessions from going on forever.
+            // Exceedingly long battery sessions would lead to an overflow of
+            // data structures such as mWakeupReasonStats.
+            return true;
+        }
+
+        return false;
+    }
+
+    @GuardedBy("this")
     protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime,
             final boolean onBattery, final int oldStatus, final int level, final int chargeUah) {
         boolean doWrite = false;
@@ -15516,23 +15724,10 @@
         final long realtimeUs = mSecRealtime * 1000;
         final int screenState = mScreenState;
         if (onBattery) {
-            // We will reset our status if we are unplugging after the
-            // battery was last full, or the level is at 100, or
-            // we have gone through a significant charge (from a very low
-            // level to a now very high level).
-            // Also, we will reset the stats if battery got partially charged
-            // and discharged repeatedly without ever reaching the full charge.
-            // This reset is done in order to prevent stats sessions from going on forever.
-            // Exceedingly long battery sessions would lead to an overflow of
-            // data structures such as mWakeupReasonStats.
             boolean reset = false;
-            if (!mNoAutoReset && mSystemReady
-                    && (oldStatus == BatteryManager.BATTERY_STATUS_FULL
-                    || level >= 90
-                    || (mDischargeCurrentLevel < 20 && level >= 80)
-                    || getHighDischargeAmountSinceCharge() >= 200)) {
+            if (shouldResetOnUnplugLocked(oldStatus, level)) {
                 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus
-                        + " dischargeLevel=" + mDischargeCurrentLevel
+                        + " dischargeLevel=" + mDischargePlugLevel
                         + " lowAmount=" + getLowDischargeAmountSinceCharge()
                         + " highAmount=" + getHighDischargeAmountSinceCharge());
                 // Before we write, collect a snapshot of the final aggregated
@@ -15589,6 +15784,9 @@
             mInitStepMode = mCurStepMode;
             mModStepMode = 0;
             pullPendingStateUpdatesLocked();
+            if (mLongPlugInAlarmInterface != null) {
+                mLongPlugInAlarmInterface.cancel();
+            }
             mHistoryCur.batteryLevel = (byte)level;
             mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
@@ -15620,6 +15818,7 @@
             mLastChargingStateLevel = level;
             mOnBattery = mOnBatteryInternal = false;
             pullPendingStateUpdatesLocked();
+            mBatteryPluggedInRealTimeMs = mSecRealtime;
             mHistoryCur.batteryLevel = (byte)level;
             mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
@@ -15637,6 +15836,7 @@
             mMaxChargeStepLevel = level;
             mInitStepMode = mCurStepMode;
             mModStepMode = 0;
+            scheduleNextResetWhilePluggedInCheck();
         }
         if (doWrite || (mLastWriteTimeMs + (60 * 1000)) < mSecRealtime) {
             if (mStatsFile != null && mBatteryStatsHistory.getActiveFile() != null) {
@@ -16651,6 +16851,8 @@
         public static final String KEY_MAX_HISTORY_BUFFER_KB = "max_history_buffer_kb";
         public static final String KEY_BATTERY_CHARGED_DELAY_MS =
                 "battery_charged_delay_ms";
+        public static final String KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS =
+                "reset_while_plugged_in_minimum_duration_hours";
 
         private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true;
         private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 1_000;
@@ -16663,6 +16865,8 @@
         private static final int DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE = 64;
         private static final int DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB = 64; /*Kilo Bytes*/
         private static final int DEFAULT_BATTERY_CHARGED_DELAY_MS = 900000; /* 15 min */
+        // Little less than 2 days
+        private static final int DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = 47;
 
         public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME;
         /* Do not set default value for KERNEL_UID_READERS_THROTTLE_TIME. Need to trigger an
@@ -16678,6 +16882,8 @@
         public int MAX_HISTORY_FILES;
         public int MAX_HISTORY_BUFFER; /*Bytes*/
         public int BATTERY_CHARGED_DELAY_MS = DEFAULT_BATTERY_CHARGED_DELAY_MS;
+        public int RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS =
+                DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS;
 
         private ContentResolver mResolver;
         private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -16754,6 +16960,11 @@
                                 DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB
                                 : DEFAULT_MAX_HISTORY_BUFFER_KB)
                         * 1024;
+
+                RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS = mParser.getInt(
+                        KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS,
+                        DEFAULT_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS);
+
                 updateBatteryChargedDelayMsLocked();
             }
         }
@@ -16808,6 +17019,8 @@
             pw.println(MAX_HISTORY_BUFFER/1024);
             pw.print(KEY_BATTERY_CHARGED_DELAY_MS); pw.print("=");
             pw.println(BATTERY_CHARGED_DELAY_MS);
+            pw.print(KEY_RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS); pw.print("=");
+            pw.println(RESET_WHILE_PLUGGED_IN_MINIMUM_DURATION_HOURS);
         }
     }
 
diff --git a/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java b/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java
index d2b612a..f1ed3be 100644
--- a/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java
+++ b/core/java/com/android/internal/policy/GestureNavigationSettingsObserver.java
@@ -56,6 +56,9 @@
         }
     };
 
+    /**
+     * Registers the observer for all users.
+     */
     public void register() {
         ContentResolver r = mContext.getContentResolver();
         r.registerContentObserver(
@@ -73,7 +76,10 @@
                 mOnPropertiesChangedListener);
     }
 
-    public void registerForCurrentUser() {
+    /**
+     * Registers the observer for the calling user.
+     */
+    public void registerForCallingUser() {
         ContentResolver r = mContext.getContentResolver();
         r.registerContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.BACK_GESTURE_INSET_SCALE_LEFT),
@@ -103,12 +109,46 @@
         }
     }
 
+    /**
+     * Returns the left sensitivity for the current user.  To be used in code that runs primarily
+     * in one user's process.
+     */
     public int getLeftSensitivity(Resources userRes) {
-        return getSensitivity(userRes, Settings.Secure.BACK_GESTURE_INSET_SCALE_LEFT);
+        final float scale = Settings.Secure.getFloatForUser(mContext.getContentResolver(),
+                Settings.Secure.BACK_GESTURE_INSET_SCALE_LEFT, 1.0f, UserHandle.USER_CURRENT);
+        return (int) (getUnscaledInset(userRes) * scale);
     }
 
+    /**
+     * Returns the left sensitivity for the calling user.  To be used in code that runs in a
+     * per-user process.
+     */
+    @SuppressWarnings("NonUserGetterCalled")
+    public int getLeftSensitivityForCallingUser(Resources userRes) {
+        final float scale = Settings.Secure.getFloat(mContext.getContentResolver(),
+                Settings.Secure.BACK_GESTURE_INSET_SCALE_LEFT, 1.0f);
+        return (int) (getUnscaledInset(userRes) * scale);
+    }
+
+    /**
+     * Returns the right sensitivity for the current user.  To be used in code that runs primarily
+     * in one user's process.
+     */
     public int getRightSensitivity(Resources userRes) {
-        return getSensitivity(userRes, Settings.Secure.BACK_GESTURE_INSET_SCALE_RIGHT);
+        final float scale = Settings.Secure.getFloatForUser(mContext.getContentResolver(),
+                Settings.Secure.BACK_GESTURE_INSET_SCALE_RIGHT, 1.0f, UserHandle.USER_CURRENT);
+        return (int) (getUnscaledInset(userRes) * scale);
+    }
+
+    /**
+     * Returns the right sensitivity for the calling user.  To be used in code that runs in a
+     * per-user process.
+     */
+    @SuppressWarnings("NonUserGetterCalled")
+    public int getRightSensitivityForCallingUser(Resources userRes) {
+        final float scale = Settings.Secure.getFloat(mContext.getContentResolver(),
+                Settings.Secure.BACK_GESTURE_INSET_SCALE_RIGHT, 1.0f);
+        return (int) (getUnscaledInset(userRes) * scale);
     }
 
     public boolean areNavigationButtonForcedVisible() {
@@ -116,7 +156,7 @@
                 Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) == 0;
     }
 
-    private int getSensitivity(Resources userRes, String side) {
+    private float getUnscaledInset(Resources userRes) {
         final DisplayMetrics dm = userRes.getDisplayMetrics();
         final float defaultInset = userRes.getDimension(
                 com.android.internal.R.dimen.config_backGestureInset) / dm.density;
@@ -127,8 +167,6 @@
                 : defaultInset;
         final float inset = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, backGestureInset,
                 dm);
-        final float scale = Settings.Secure.getFloatForUser(
-                mContext.getContentResolver(), side, 1.0f, UserHandle.USER_CURRENT);
-        return (int) (inset * scale);
+        return inset;
     }
 }
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index fcfdd95..04e7172 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan gebare vasvang wat op die toestel se vingerafdruksensor uitgevoer word."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Neem skermkiekie"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan \'n skermkiekie neem."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Voorskou, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"deaktiveer of verander statusbalk"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Laat die program toe om die statusbalk te deaktiveer en stelselikone by te voeg of te verwyder."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"wees die statusbalk"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index a5619fd..65ce609 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"በመሣሪያው የጣት አሻራ ዳሳሽ ላይ የተከናወኑ የጣት ምልክቶችን መያዝ ይችላል።"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ቅጽበታዊ ገጽ እይታን ያነሳል"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"የማሳያው ቅጽበታዊ ገጽ እይታን ማንሳት ይችላል።"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"ቅድመ ዕይታ፣ <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"የሁኔቴ አሞሌ አቦዝን ወይም ቀይር"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"የስርዓት አዶዎችን ወደ ሁኔታ አሞሌ ላለማስቻል ወይም ለማከል እና ለማስወገድ ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"የሁኔታ አሞሌ መሆን"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 1aba35a..d46d330 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -346,6 +346,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"يمكن أن تلتقط الإيماءات من أداة استشعار بصمة الإصبع في الجهاز."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"أخذ لقطة شاشة"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"يمكن أخذ لقطة شاشة."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"نسخة حصرية، \"<xliff:g id="DREAM_NAME">%1$s</xliff:g>\""</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"إيقاف شريط الحالة أو تعديله"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"للسماح للتطبيق بإيقاف شريط الحالة أو إضافة رموز نظام وإزالتها."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"العمل كشريط للحالة"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 38ec792..e2213d7 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ডিভাইচটোৰ ফিংগাৰপ্ৰিণ্ট ছেন্সৰত দিয়া নিৰ্দেশ বুজিব পাৰে।"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"স্ক্ৰীনশ্বট লওক"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ডিছপ্লে’খনৰ এটা স্ক্ৰীনশ্বট ল\'ব পাৰে।"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"পূৰ্বদৰ্শন কৰক, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"স্থিতি দণ্ড অক্ষম কৰক বা সলনি কৰক"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"স্থিতি দণ্ড অক্ষম কৰিবলৈ বা ছিষ্টেম আইকন আঁতৰাবলৈ এপ্‌টোক অনুমতি দিয়ে।"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"স্থিতি দণ্ড হ\'ব পাৰে"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index d2359c7..ea8addec 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Cihazların barmaq izi sensorunda olan işarələri əldə edə bilər."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ekran şəkli çəkin"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Ekran şəkli çəkilə bilər."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Önizləmə, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"status panelini deaktivləşdir və ya dəyişdir"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Tətbiqə status panelini deaktiv etməyə və ya sistem ikonalarını əlavə etmək və ya silmək imkanı verir."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"status paneli edin"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 4a7a235..940b0919 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Može da registruje pokrete na senzoru za otisak prsta na uređaju."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Napravi snimak ekrana"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Može da napravi snimak ekrana."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Pregled, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"onemogućavanje ili izmena statusne trake"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Dozvoljava aplikaciji da onemogući statusnu traku ili da dodaje i uklanja sistemske ikone."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"funkcionisanje kao statusna traka"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 24d7990..58e72a7 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -344,6 +344,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Можа распазнаваць жэсты на сканеры адбіткаў пальцаў прылады."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Зрабіць здымак экрана"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Можна зрабіць здымак экрана."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Перадпрагляд, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"адключаць ці змяняць радок стану"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Дазваляе прыкладанням адключаць радок стану або дадаваць і выдаляць сістэмныя значкі."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"быць панэллю стану"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 164040f..523c8b5 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Може да улавя жестовете, извършени върху сензора за отпечатъци на устройството."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Създаване на екранна снимка"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Може да създава екранни снимки."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Визуализация на „<xliff:g id="DREAM_NAME">%1$s</xliff:g>“"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"деактивиране или промяна на лентата на състоянието"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Разрешава на приложението да деактивира лентата на състоянието или да добавя и премахва системни икони."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"изпълняване на ролята на лента на състоянието"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index b0a9467..73100098 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ডিভাইসের আঙ্গুলের ছাপের সেন্সরের উপরে ইঙ্গিত করলে বুঝতে পারে।"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"স্ক্রিনশট নিন"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ডিসপ্লের একটি স্ক্রিনশট নিতে পারেন।"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"প্রিভিউ, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"স্ট্যাটাস বার নিষ্ক্রিয় অথবা সংশোধন করে"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"অ্যাপ্লিকেশনকে স্ট্যাটাস বার অক্ষম করতে এবং সিস্টেম আইকনগুলি সরাতে দেয়৷"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"স্থিতি দন্ডে থাকুন"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index ec381a5..9219511 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Može zabilježiti pokrete na senzoru za otisak prsta uređaja."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"praviti snimke ekrana"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Može napraviti snimak ekrana."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Pregled, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"onemogućavanje ili mijenjanje statusne trake"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Dozvoljava aplikaciji onemogućavanje statusne trake ili dodavanje i uklanjanje sistemskih ikona."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"funkcioniranje u vidu statusne trake"</string>
@@ -2052,9 +2053,9 @@
     <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"IPAK OTVORI"</string>
     <string name="harmful_app_warning_title" msgid="8794823880881113856">"Otkrivena je štetna aplikacija"</string>
     <string name="log_access_confirmation_title" msgid="2343578467290592708">"Dozvoliti aplikaciji <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> da pristupa svim zapisnicima uređaja?"</string>
-    <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Dozvoli jednokratan pristup"</string>
+    <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Dozvoli jednokratni pristup"</string>
     <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Nemoj dozvoliti"</string>
-    <string name="log_access_confirmation_body" product="default" msgid="1806692062668620735">"Zapisnici uređaja bilježe šta se dešava na uređaju. Aplikacije mogu koristiti te zapisnike da pronađu i isprave probleme.\n\nNeki zapisnici mogu sadržavati osjetljive podatke, zato pristup svim zapisnicima uređaja dozvolite samo aplikacijama kojima vjerujete. \n\nAko ne dozvolite ovoj aplikaciji da pristupa svim zapisnicima uređaja, ona i dalje može pristupati svojim zapisnicima. Proizvođač uređaja će možda i dalje biti u stanju pristupiti nekim zapisnicima ili podacima na uređaju."</string>
+    <string name="log_access_confirmation_body" product="default" msgid="1806692062668620735">"Zapisnici uređaja bilježe šta se dešava na uređaju. Aplikacije mogu koristiti te zapisnike pronađu i riješe probleme.\n\nNeki zapisnici mogu sadržavati osjetljive podatke, zato pristup svim zapisnicima uređaja dozvolite samo aplikacijama kojima vjerujete. \n\nAko ne dozvolite ovoj aplikaciji da pristupa svim zapisnicima uređaja, ona i dalje može pristupati svojim zapisnicima. Proizvođač uređaja će možda i dalje biti u stanju pristupiti nekim zapisnicima ili podacima na uređaju."</string>
     <string name="log_access_confirmation_body" product="tv" msgid="7379536536425265262">"Zapisnici uređaja bilježe šta se dešava na uređaju. Aplikacije mogu koristiti te zapisnike da pronađu i riješe probleme.\n\nNeki zapisnici mogu sadržavati osjetljive podatke. Zbog toga pristup svim zapisnicima uređaja dozvolite samo aplikacijama koje smatrate pouzdanima. \n\nAko ne dozvolite ovoj aplikaciji da pristupa svim zapisnicima uređaja, ona i dalje može pristupati svojim zapisnicima. Proizvođač uređaja će možda i dalje moći pristupiti nekim zapisnicima ili podacima na uređaju.\n\nSaznajte više na g.co/android/devicelogs."</string>
     <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Ne prikazuj ponovo"</string>
     <string name="slices_permission_request" msgid="3677129866636153406">"Aplikacija <xliff:g id="APP_0">%1$s</xliff:g> želi prikazati isječke aplikacije <xliff:g id="APP_2">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 4cf9384..7a9fcb3 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Pot capturar els gestos fets en el sensor d\'empremtes digitals del dispositiu."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fer una captura de pantalla"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pot fer una captura de la pantalla."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Previsualitza, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"desactivar o modificar la barra d\'estat"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permet que l\'aplicació desactivi la barra d\'estat o afegeixi i elimini icones del sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"aparèixer a la barra d\'estat"</string>
@@ -2054,8 +2055,8 @@
     <string name="log_access_confirmation_title" msgid="2343578467290592708">"Vols permetre que <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> accedeixi a tots els registres del dispositiu?"</string>
     <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Permet l\'accés únic"</string>
     <string name="log_access_confirmation_deny" msgid="7685790957455099845">"No permetis"</string>
-    <string name="log_access_confirmation_body" product="default" msgid="1806692062668620735">"Els registres del dispositiu inclouen informació sobre tot allò que passa al teu dispositiu. Les aplicacions poden utilitzar aquests registres per detectar i corregir problemes.\n\nÉs possible que alguns registres continguin informació sensible; per això només has de donar-hi accés a les aplicacions de confiança. \n\nEncara que no permetis que aquesta aplicació pugui accedir a tots els registres del dispositiu, podrà accedir als seus propis registres. És possible que el fabricant del dispositiu també tingui accés a alguns registres o a informació del teu dispositiu."</string>
-    <string name="log_access_confirmation_body" product="tv" msgid="7379536536425265262">"Els registres del dispositiu inclouen informació sobre tot allò que passa al teu dispositiu. Les aplicacions poden utilitzar aquests registres per detectar i corregir problemes.\n\nÉs possible que alguns registres continguin informació sensible; per això només has de donar-hi accés a les aplicacions de confiança. \n\nEncara que no permetis que aquesta aplicació accedeixi a tots els registres del dispositiu, podrà accedir als seus propis registres. És possible que el fabricant del dispositiu també tingui accés a alguns registres o a informació del teu dispositiu.\n\nObtén més informació a g.co/android/devicelogs."</string>
+    <string name="log_access_confirmation_body" product="default" msgid="1806692062668620735">"Els registres del dispositiu inclouen informació sobre tot allò que passa al teu dispositiu. Les aplicacions poden utilitzar aquests registres per detectar i corregir problemes.\n\nCom que és possible que alguns registres continguin informació sensible, et recomanem que només hi permetis l\'accés a les aplicacions de confiança. \n\nEncara que no permetis que aquesta aplicació accedeixi a tots els registres del dispositiu, podrà accedir als seus propis registres. És possible que el fabricant del dispositiu també tingui accés a alguns registres o a informació del teu dispositiu."</string>
+    <string name="log_access_confirmation_body" product="tv" msgid="7379536536425265262">"Els registres del dispositiu inclouen informació sobre tot allò que passa al teu dispositiu. Les aplicacions poden utilitzar aquests registres per detectar i corregir problemes.\n\nCom que és possible que alguns registres continguin informació sensible, et recomanem que només hi permetis l\'accés a les aplicacions de confiança. \n\nEncara que no permetis que aquesta aplicació accedeixi a tots els registres del dispositiu, podrà accedir als seus propis registres. És possible que el fabricant del dispositiu també tingui accés a alguns registres o a informació del teu dispositiu.\n\nObtén més informació a g.co/android/devicelogs."</string>
     <string name="log_access_do_not_show_again" msgid="1058690599083091552">"No tornis a mostrar"</string>
     <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> vol mostrar porcions de l\'aplicació <xliff:g id="APP_2">%2$s</xliff:g>"</string>
     <string name="screenshot_edit" msgid="7408934887203689207">"Edita"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index a04b34a..9f67d08 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -344,6 +344,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Dokáže rozpoznat gesta zadaná na snímači otisků prstů."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Pořídit snímek obrazovky"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Může pořídit snímek obrazovky."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Náhled, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"zakázání či změny stavového řádku"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Umožňuje aplikaci zakázat stavový řádek nebo přidat či odebrat systémové ikony."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"vydávání se za stavový řádek"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 0e17b9a..fd169f5 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan registrere bevægelser, der foretages på enhedens fingeraftrykssensor."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Tag screenshot"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan tage et screenshot af skærmen."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Preview, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"deaktivere eller redigere statuslinje"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Tillader, at appen kan deaktivere statusbjælken eller tilføje og fjerne systemikoner."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"vær statusbjælken"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 9b416bc..42fb58f 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -296,7 +296,7 @@
     <string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="8974401416068943888">"Abgesicherter Modus"</string>
     <string name="android_system_label" msgid="5974767339591067210">"Android-System"</string>
-    <string name="user_owner_label" msgid="8628726904184471211">"Zum persönlichen Profil wechseln"</string>
+    <string name="user_owner_label" msgid="8628726904184471211">"Zum privaten Profil wechseln"</string>
     <string name="managed_profile_label" msgid="7316778766973512382">"Zum Arbeitsprofil wechseln"</string>
     <string name="permgrouplab_contacts" msgid="4254143639307316920">"Kontakte"</string>
     <string name="permgroupdesc_contacts" msgid="9163927941244182567">"auf deine Kontakte zugreifen"</string>
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Erfasst Touch-Gesten auf dem Fingerabdrucksensor des Geräts."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Screenshot erstellen"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Es kann ein Screenshot des Displays erstellt werden."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Vorschau – <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"Statusleiste deaktivieren oder ändern"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Ermöglicht der App, die Statusleiste zu deaktivieren oder Systemsymbole hinzuzufügen oder zu entfernen"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"Statusleiste darstellen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 8ab0345..e83314c 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Μπορεί να αναγνωρίσει κινήσεις που εκτελούνται στον αισθητήρα δακτυλικού αποτυπώματος της συσκευής."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Λήψη στιγμιότυπου οθόνης"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Μπορεί να τραβήξει στιγμιότυπο της οθόνης."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Προεπισκόπηση, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"απενεργοποιεί ή να τροποποιεί την γραμμή κατάστασης"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Επιτρέπει στην εφαρμογή να απενεργοποιεί τη γραμμή κατάστασης ή να προσθέτει και να αφαιρεί εικονίδια συστήματος."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ορίζεται ως γραμμή κατάστασης"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index e96b543..d1da0fb 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Can capture gestures performed on the device\'s fingerprint sensor."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Preview, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 7d455c7..8c6285c 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Can capture gestures performed on the device\'s fingerprint sensor."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Preview, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 0ee88ad..861393f 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Can capture gestures performed on the device\'s fingerprint sensor."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Preview, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 68cbfa8..a0a9436 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Can capture gestures performed on the device\'s fingerprint sensor."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Take screenshot"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Can take a screenshot of the display."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Preview, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"be the status bar"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index b8767b7b..b3551cf 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‎‎‏‏‎‏‎‎Can capture gestures performed on the device\'s fingerprint sensor.‎‏‎‎‏‎"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‎Take screenshot‎‏‎‎‏‎"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎Can take a screenshot of the display.‎‏‎‎‏‎"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‎‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‎‎Preview, ‎‏‎‎‏‏‎<xliff:g id="DREAM_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎disable or modify status bar‎‏‎‎‏‎"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‎Allows the app to disable the status bar or add and remove system icons.‎‏‎‎‏‎"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‎‎‎‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎be the status bar‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 2f51055..03534d0 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Capturará los gestos que se hacen en el sensor de huellas dactilares del dispositivo."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Tomar captura de pantalla"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Puede tomar capturas de pantalla."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Vista previa, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"desactivar o modificar la barra de estado"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite que la aplicación inhabilite la barra de estado o que agregue y elimine íconos del sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"aparecer en la barra de estado"</string>
@@ -2055,7 +2056,7 @@
     <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Permitir acceso por única vez"</string>
     <string name="log_access_confirmation_deny" msgid="7685790957455099845">"No permitir"</string>
     <string name="log_access_confirmation_body" product="default" msgid="1806692062668620735">"Los registros del dispositivo permiten documentar lo que sucede en él. Las apps pueden usar estos registros para encontrar y solucionar problemas.\n\nEs posible que algunos registros del dispositivo contengan información sensible, por lo que solo debes permitir que accedan a todos ellos las apps que sean de tu confianza. \n\nSi no permites que esta app acceda a todos los registros del dispositivo, aún puede acceder a sus propios registros. Además, es posible que el fabricante del dispositivo acceda a algunos registros o información en tu dispositivo."</string>
-    <string name="log_access_confirmation_body" product="tv" msgid="7379536536425265262">"Los registros del dispositivo permiten documentar lo que sucede en él. Las apps pueden usar estos registros para encontrar y solucionar problemas.\n\nEs posible que algunos registros del dispositivo contengan información sensible, por lo que solo debes permitir que accedan a todos los registros las apps que sean de tu confianza. \n\nTen en cuenta que la app puede acceder a sus propios registros incluso si no permites que acceda a todos los registros del dispositivo. También es posible que el fabricante del dispositivo acceda a algunos registros o información en tu dispositivo.\n\nObtén más información en g.co/android/devicelogs."</string>
+    <string name="log_access_confirmation_body" product="tv" msgid="7379536536425265262">"Los registros del dispositivo permiten documentar lo que sucede en él. Las apps pueden usar estos registros para encontrar y solucionar problemas.\n\nEs posible que algunos registros del dispositivo contengan información sensible, por lo que solo debes permitir que accedan a ellos las apps que sean de tu confianza. \n\nTen en cuenta que la app puede acceder a sus propios registros incluso si no permites que acceda a todos los registros del dispositivo. También es posible que el fabricante del dispositivo acceda a algunos registros o información en tu dispositivo.\n\nObtén más información en g.co/android/devicelogs."</string>
     <string name="log_access_do_not_show_again" msgid="1058690599083091552">"No volver a mostrar"</string>
     <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> quiere mostrar fragmentos de <xliff:g id="APP_2">%2$s</xliff:g>"</string>
     <string name="screenshot_edit" msgid="7408934887203689207">"Editar"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 29e8abf..1361870 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Puede capturar los gestos realizados en el sensor de huellas digitales del dispositivo."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Hacer captura"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Puede hacer capturas de la pantalla."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Vista previa, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"inhabilitar o modificar la barra de estado"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite que la aplicación inhabilite la barra de estado o añada y elimine iconos del sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"aparecer en la barra de estado"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 9178aff..22796f2 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Teil on võimalik jäädvustada seadme sõrmejäljeanduril tehtud liigutused."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Jäädvusta ekraanipilt"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Saab jäädvustada ekraanipildi."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Eelvaade, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"keela või muuda olekuriba"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Võimaldab rakendusel keelata olekuriba või lisada ja eemaldada süsteemiikoone."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"olekuribana kuvamine"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index fc7a86e..21ed746c 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Gailuaren hatz-marken sentsorean egindako keinuak atzeman ditzake."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Pantaila-argazkiak atera."</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pantaila-argazkiak atera ditzake."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Aurrebista, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"desgaitu edo aldatu egoera-barra"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Egoera-barra desgaitzea edo sistema-ikonoak gehitzea edo kentzea baimentzen die aplikazioei."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"bihurtu egoera-barra"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 26d1d4b..9491f22 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"می‌تواند اشاره‌های اجرا‌شده روی حسگر اثرانگشت دستگاه را ثبت کند."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"گرفتن نماگرفت"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"می‌تواند از نمایشگر نماگرفت بگیرد."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"پیش‌نما، <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"غیرفعال کردن یا تغییر نوار وضعیت"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"‏به برنامه اجازه می‎دهد تا نوار وضعیت را غیرفعال کند یا نمادهای سیستم را اضافه یا حذف کند."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"نوار وضعیت باشد"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 5f27e36..207f397 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Voi tallentaa laitteen sormenjälkitunnistimelle tehtyjä eleitä."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ota kuvakaappaus"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Voi ottaa kuvakaappauksen näytöstä."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Esikatselu, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"poista tilapalkki käytöstä tai muokkaa tilapalkkia"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Antaa sovelluksen poistaa tilapalkin käytöstä ja lisätä tai poistaa järjestelmäkuvakkeita."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"sijaita tilapalkissa"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 6ca95b3..257db1c 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Peut capturer des gestes effectués sur le capteur d\'empreintes digitales de l\'appareil."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Prendre une capture d\'écran"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Peut prendre une capture de l\'écran."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Aperçu, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"désactiver ou modifier la barre d\'état"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permet à l\'application de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"servir de barre d\'état"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 815ae1b..01f8f08 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Peut enregistrer des gestes effectués sur le lecteur d\'empreinte digitale de l\'appareil."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Prendre une capture d\'écran"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Peut prendre des captures d\'écran."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Aperçu, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"Désactivation ou modification de la barre d\'état"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permet à l\'application de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"remplacer la barre d\'état"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 5576f42..64e91ad 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Pode rexistrar os xestos realizados no sensor de impresión dixital do dispositivo."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Facer captura de pantalla"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pode facer capturas de pantalla."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Vista previa, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"desactivar ou modificar a barra de estado"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite á aplicación desactivar a barra de estado ou engadir e quitar as iconas do sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"actuar como a barra de estado"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 2665731..3c960169 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ડિવાઇસના ફિંગરપ્રિન્ટ સેન્સર પર કરવામાં આવેલા સંકેતો કૅપ્ચર કરી શકે છે."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"સ્ક્રીનશૉટ લો"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ડિસ્પ્લેનો સ્ક્રીનશૉટ લઈ શકે છે."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"પ્રીવ્યૂ, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"સ્ટેટસ બારને અક્ષમ કરો અથવા તેમાં ફેરફાર કરો"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ઍપ્લિકેશનને સ્ટેટસ બાર અક્ષમ કરવાની અથવા સિસ્ટમ આયકન્સ ઉમેરવા અને દૂર કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"સ્ટેટસ બારમાં બતાવો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index b17eb42..a20714d 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"डिवाइस के फ़िंगरप्रिंट सेंसर पर किए गए हाथ के जेस्चर कैप्चर किए जा सकते हैं."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"स्क्रीनशॉट लें"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"डिसप्ले का स्क्रीनशॉट लिया जा सकता है."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"<xliff:g id="DREAM_NAME">%1$s</xliff:g> की झलक"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"स्टेटस बार को अक्षम करें या बदलें"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ऐप को, स्टेटस बार को बंद करने या सिस्‍टम आइकॉन को जोड़ने और निकालने की अनुमति देता है."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"स्टेटस बार को रहने दें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 0b0b8fe..f380cb4 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Može snimati pokrete izvršene na senzoru otiska prsta na uređaju."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Snimi zaslon"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Možete napraviti snimku zaslona."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Pregled, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"onemogućavanje ili izmjena trake statusa"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Aplikaciji omogućuje onemogućavanje trake statusa ili dodavanje i uklanjanje sistemskih ikona."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"biti traka statusa"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index d797230..d3c252a 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Érzékeli az eszköz ujjlenyomat-érzékelőjén végzett kézmozdulatokat."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Képernyőkép készítése"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Készíthet képernyőképet a kijelzőről."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Előnézet, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"állapotsor kikapcsolása vagy módosítása"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Lehetővé teszi az alkalmazás számára az állapotsor kikapcsolását, illetve rendszerikonok hozzáadását és eltávolítását."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"az állapotsor szerepének átvétele"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 5937faf..1226661 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Կարող է արձանագրել մատնահետքերի սկաների վրա կատարվող ժեստերը"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Սքրինշոթի ստեղծում"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Կարող է ստեղծել էկրանի սքրինշոթ։"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Նախադիտում, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"անջատել կամ փոփոխել կարգավիճակի գոտին"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Թույլ է տալիս հավելվածին անջատել կարգավիճակի գոտին կամ ավելացնել ու հեռացնել համակարգի պատկերակները:"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"լինել կարգավիճակի գոտի"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 93b8a15..9257ed4 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Dapat merekam gestur yang dilakukan di sensor sidik jari perangkat."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ambil screenshot"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Dapat mengambil screenshot tampilan."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Pratinjau, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"nonaktifkan atau ubah bilah status"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Mengizinkan apl menonaktifkan bilah status atau menambah dan menghapus ikon sistem."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"jadikan bilah status"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 29c1a2a..30eefdf 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Getur fangað bendingar sem eru gerðar á fingrafaralesara tækisins."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Taka skjámynd"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Getur tekið skjámynd af skjánum."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Forskoðun, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"slökkva á eða breyta stöðustiku"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Leyfir forriti að slökkva á stöðustikunni eða bæta við og fjarlægja kerfistákn."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"vera stöðustikan"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 304d212..7060eef 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"È in grado di rilevare i gesti compiuti con il sensore di impronte dei dispositivi."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Acquisire screenshot"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Può acquisire uno screenshot del display."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"<xliff:g id="DREAM_NAME">%1$s</xliff:g> in anteprima"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"disattivazione o modifica della barra di stato"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Consente all\'applicazione di disattivare la barra di stato o di aggiungere e rimuovere icone di sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ruolo di barra di stato"</string>
@@ -2054,8 +2055,8 @@
     <string name="log_access_confirmation_title" msgid="2343578467290592708">"Consentire all\'app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> di accedere a tutti i log del dispositivo?"</string>
     <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Consenti accesso una tantum"</string>
     <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Non consentire"</string>
-    <string name="log_access_confirmation_body" product="default" msgid="1806692062668620735">"I log del dispositivo registrano tutto ciò che succede sul tuo dispositivo. Le app possono usare questi log per individuare problemi e correggerli.\n\nAlcuni log potrebbero contenere informazioni sensibili, quindi concedi l\'accesso a tutti i log del dispositivo soltanto alle app attendibili. \n\nSe le neghi l\'accesso a tutti i log del dispositivo, questa app può comunque accedere ai propri log. Il produttore del tuo dispositivo potrebbe essere comunque in grado di accedere ad alcuni log o informazioni sul dispositivo."</string>
-    <string name="log_access_confirmation_body" product="tv" msgid="7379536536425265262">"I log del dispositivo registrano tutto ciò che succede sul tuo dispositivo. Le app possono usare questi log per individuare problemi e correggerli.\n\nAlcuni log potrebbero contenere informazioni sensibili, quindi concedi l\'accesso a tutti i log del dispositivo soltanto alle app attendibili. \n\nSe le neghi l\'accesso a tutti i log del dispositivo, questa app può comunque accedere ai propri log. Il produttore del tuo dispositivo potrebbe essere comunque in grado di accedere ad alcuni log o informazioni sul dispositivo.\n\nScopri di più all\'indirizzo g.co/android/devicelogs."</string>
+    <string name="log_access_confirmation_body" product="default" msgid="1806692062668620735">"I log del dispositivo registrano tutto ciò che succede sul tuo dispositivo. Le app possono usare questi log per individuare problemi e correggerli.\n\nAlcuni log potrebbero contenere informazioni sensibili, quindi concedi l\'accesso a tutti i log del dispositivo soltanto alle app attendibili. \n\nSe neghi l\'accesso a tutti i log del dispositivo, questa app può comunque accedere ai propri log. Il produttore del tuo dispositivo potrebbe essere comunque in grado di accedere ad alcuni log o informazioni sul dispositivo."</string>
+    <string name="log_access_confirmation_body" product="tv" msgid="7379536536425265262">"I log del dispositivo registrano tutto ciò che succede sul tuo dispositivo. Le app possono usare questi log per individuare problemi e correggerli.\n\nAlcuni log potrebbero contenere informazioni sensibili, quindi concedi l\'accesso a tutti i log del dispositivo soltanto alle app attendibili. \n\nSe neghi l\'accesso a tutti i log del dispositivo, questa app può comunque accedere ai propri log. Il produttore del tuo dispositivo potrebbe essere comunque in grado di accedere ad alcuni log o informazioni sul dispositivo.\n\nScopri di più all\'indirizzo g.co/android/devicelogs."</string>
     <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Non mostrare più"</string>
     <string name="slices_permission_request" msgid="3677129866636153406">"L\'app <xliff:g id="APP_0">%1$s</xliff:g> vuole mostrare porzioni dell\'app <xliff:g id="APP_2">%2$s</xliff:g>"</string>
     <string name="screenshot_edit" msgid="7408934887203689207">"Modifica"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 963d473..628adec 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"אפשרות לזהות תנועות בזמן נגיעה בחיישן טביעות האצבע של המכשיר."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"צילום המסך"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ניתן לצלם צילום מסך של התצוגה."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"תצוגה מקדימה, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"השבתה או שינוי של שורת הסטטוס"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"מאפשרת לאפליקציה להשבית את שורת הסטטוס או להוסיף ולהסיר סמלי מערכת."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"להיות שורת הסטטוס"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index f2bc9a9..5a3deed 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"デバイスの指紋認証センサーで行われた操作をキャプチャできます。"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"スクリーンショットの撮影"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ディスプレイのスクリーンショットを撮影できます。"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"プレビュー - <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"ステータスバーの無効化や変更"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ステータスバーの無効化、システムアイコンの追加や削除をアプリに許可します。"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ステータスバーへの表示"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 3803a26..67c8203 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"შეუძლია აღბეჭდოს მოწყობილობის თითის ანაბეჭდის სენსორზე განხორციელებული ჟესტები."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ეკრანის ანაბეჭდის გადაღება"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"შეუძლია ეკრანის ანაბეჭდის გადაღება."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"გადახედვა, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"სტატუსის ზოლის გათიშვა ან ცვლილება"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"აპს შეეძლება სტატუსების ზოლის გათიშვა და სისტემის ხატულების დამატება/წაშლა."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"სტატუსის ზოლის ჩანაცვლება"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 2b11346..6bfce9e 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Құрылғының саусақ ізі сенсорында орындалған қимылдарды сақтайды."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Скриншот жасау"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Дисплейдің скриншотын жасай аласыз."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Алғы көрініс, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"күйін көрсету тақтасын өшіру немесе өзгерту"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Қолданбаға күй жолағын өшіруге немесе жүйелік белгішелерді қосуға және жоюға рұқсат береді."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"күй жолағы болу"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 9cf498d..445020d 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"អាចចាប់យក​ចលនា​ដែលធ្វើនៅលើ​នៅលើ​ឧបករណ៍​ចាប់​ស្នាម​ម្រាមដៃ​របស់ឧបករណ៍បាន។"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ថត​អេក្រង់"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"អាច​ថត​អេក្រង់​នៃ​ផ្ទាំង​អេក្រង់​បាន។"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"មើល​សាកល្បង <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"បិទ ឬ​កែ​របារ​ស្ថានភាព"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ឲ្យ​កម្មវិធី​បិទ​របារ​ស្ថានភាព ឬ​បន្ថែម និង​លុប​រូប​តំណាង​ប្រព័ន្ធ។"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ធ្វើជារបារស្ថានភាព"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 879f9e8..ee76ca3 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ಸಾಧನದ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌ನಲ್ಲಿ ನಡೆಸಿದ ಗೆಶ್ಚರ್‌ಗಳನ್ನು ಕ್ಯಾಪ್ಚರ್ ಮಾಡಿ."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ತೆಗೆದುಕೊಳ್ಳಿ"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ಪ್ರದರ್ಶನದ ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಅನ್ನು ತೆಗೆದುಕೊಳ್ಳಬಲ್ಲದು."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"ಪೂರ್ವವೀಕ್ಷಣೆ, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ ಇಲ್ಲವೇ ಮಾರ್ಪಡಿಸಿ"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಅಥವಾ ಸೇರಿಸಲು ಮತ್ತು ಸಿಸ್ಟಂ ಐಕಾನ್‌ಗಳನ್ನು ತೆಗೆದುಹಾಕಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯಾಗಿರಲು"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 7504943..bbfe134 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"기기 지문 센서에서 동작을 캡처합니다."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"스크린샷 촬영"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"디스플레이 스크린샷을 촬영할 수 있습니다."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"미리보기, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"상태 표시줄 사용 중지 또는 수정"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"앱이 상태 표시줄을 사용중지하거나 시스템 아이콘을 추가 및 제거할 수 있도록 허용합니다."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"상태 표시줄에 위치"</string>
@@ -2050,10 +2051,10 @@
     <string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"제거"</string>
     <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"열기"</string>
     <string name="harmful_app_warning_title" msgid="8794823880881113856">"유해한 앱 감지됨"</string>
-    <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>에서 모든 기기 로그에 액세스하도록 허용하시겠습니까?"</string>
+    <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g>에서 전체 기기 로그에 액세스하도록 허용하시겠습니까?"</string>
     <string name="log_access_confirmation_allow" msgid="5302517782599389507">"일회성 액세스 허용"</string>
     <string name="log_access_confirmation_deny" msgid="7685790957455099845">"허용 안함"</string>
-    <string name="log_access_confirmation_body" product="default" msgid="1806692062668620735">"기기 로그에 기기에서 발생한 상황이 기록됩니다. 앱은 문제를 찾고 해결하는 데 이 로그를 사용할 수 있습니다.\n\n일부 로그는 민감한 정보를 포함할 수 있으므로 신뢰할 수 있는 앱만 모든 기기 로그에 액세스하도록 허용하세요. \n\n앱에 전체 기기 로그에 대한 액세스 권한을 부여하지 않아도 앱이 자체 로그에는 액세스할 수 있습니다. 기기 제조업체에서 일부 로그 또는 기기 내 정보에 액세스할 수도 있습니다."</string>
+    <string name="log_access_confirmation_body" product="default" msgid="1806692062668620735">"기기 로그에는 기기에서 발생한 상황이 기록됩니다. 앱은 문제를 찾고 해결하는 데 이 로그를 사용할 수 있습니다.\n\n일부 로그는 민감한 정보를 포함할 수 있으므로 신뢰할 수 있는 앱만 전체 기기 로그에 액세스하도록 허용하세요. \n\n앱에 전체 기기 로그에 대한 액세스 권한을 부여하지 않아도 앱이 자체 로그에는 액세스할 수 있습니다. 기기 제조업체에서 일부 로그 또는 기기 내 정보에 액세스할 수도 있습니다."</string>
     <string name="log_access_confirmation_body" product="tv" msgid="7379536536425265262">"기기 로그에는 기기에서 발생한 상황이 기록됩니다. 앱은 문제를 찾고 해결하는 데 이 로그를 사용할 수 있습니다.\n\n일부 로그에 민감한 정보가 포함될 수 있으므로 신뢰할 수 있는 앱만 모든 기기 로그에 액세스하도록 허용하세요. \n\n앱에 전체 기기 로그에 대한 액세스 권한을 부여하지 않아도, 앱이 자체 로그에는 액세스할 수 있습니다. 기기 제조업체에서 기기 내 일부 로그 또는 정보에 액세스할 수도 있습니다.\n\ng.co/android/devicelogs에서 자세히 알아보세요."</string>
     <string name="log_access_do_not_show_again" msgid="1058690599083091552">"다시 표시 안함"</string>
     <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g>에서 <xliff:g id="APP_2">%2$s</xliff:g>의 슬라이스를 표시하려고 합니다"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index de2cdb7..fdf22a9 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Түзмөктөгү манжа изинин сенсорунда жасалган жаңсоолорду жаздырып алат."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Скриншот тартып алуу"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Дисплейдин скриншотун тартып алсаңыз болот."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Алдын ала көрүү, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"абал тилкесин өчүрүү же өзгөртүү"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Колдонмого абал тилкесин өчүрүү же тутум сүрөтчөлөрүн кошуу же алып салуу мүмкүнчүлүгүн берет."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"абал тилкесинин милдетин аткаруу"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 366881b..f06b2cf 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ສາມາດບັນທຶກທ່າທາງທີ່ເກີດຂຶ້ນໃນອຸປະກອນເຊັນເຊີລາຍນິ້ວມືໄດ້."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ຖ່າຍຮູບໜ້າຈໍ"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ສາມາດຖ່າຍຮູບໜ້າຈໍໄດ້."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"ຕົວຢ່າງ, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"ປິດການນນຳໃຊ້ ຫຼື ແກ້ໄຂແຖບສະຖານະ"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ອະນຸຍາດໃຫ້ແອັບຯປິດການເຮັດວຽກຂອງແຖບສະຖານະ ຫຼືເພີ່ມ ແລະລຶບໄອຄອນລະບົບອອກໄດ້."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ເປັນ​ແຖບ​ສະ​ຖາ​ນະ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 8f5e7fb..fcc0918 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -344,6 +344,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Gali užfiksuoti gestus, atliktus naudojant įrenginio piršto antspaudo jutiklį."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ekrano kopijos kūrimas"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Galima sukurti vaizdo ekrano kopiją."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Peržiūra, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"išjungti ar keisti būsenos juostą"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Leidžiama programai neleisti būsenos juostos arba pridėti ir pašalinti sistemos piktogramas."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"būti būsenos juosta"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index cf858b7..e1baffd 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Var uztvert žestus ierīces pirksta nospieduma sensorā."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ekrānuzņēmuma izveide"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Var izveidot displeja ekrānuzņēmumu."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"<xliff:g id="DREAM_NAME">%1$s</xliff:g> (priekšskatījums)"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"atspējot vai pārveidot statusa joslu"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Ļauj lietotnei atspējot statusa joslu vai pievienot un noņemt sistēmas ikonas."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"Būt par statusa joslu"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index beed8e6..605b7bb 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Може да сними движења што се направени на сензорот за отпечатоци на уредот."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Зачувување слика од екранот"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Може да зачува слика од екранот."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Преглед, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"оневозможи или измени статусна лента"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Дозволува апликацијата да ја оневозможи статусната лента или да додава или отстранува системски икони."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"да стане статусна лента"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 4ab4c07..7a9d4da 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ഉപകരണത്തിന്റെ ഫിംഗർപ്രിന്റ് സെൻസറിൽ ചെയ്‌ത ജെസ്‌റ്ററുകൾ ക്യാപ്‌ചർ ചെയ്യാനാകും."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"സ്ക്രീന്‍ഷോട്ട് എടുക്കുക"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ഡിസ്‌പ്ലേയുടെ സ്‌ക്രീൻഷോട്ട് എടുക്കാൻ കഴിയും."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"പ്രിവ്യൂ, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"സ്റ്റാറ്റസ് ബാർ പ്രവർത്തനരഹിതമാക്കുക അല്ലെങ്കിൽ പരിഷ്‌ക്കരിക്കുക"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"നില ബാർ പ്രവർത്തരഹിതമാക്കുന്നതിന് അല്ലെങ്കിൽ സിസ്‌റ്റം ഐക്കണുകൾ ചേർക്കുന്നതിനും നീക്കംചെയ്യുന്നതിനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"സ്റ്റാറ്റസ് ബാർ ആയിരിക്കുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 5e98d53..e4c68e2 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Төхөөрөмжийн хурууны хээ мэдрэгчид зангасан зангааг танина."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Дэлгэцийн зургийг дарах"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Дэлгэцийн зургийг дарах боломжтой."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Урьдчилан үзэх, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"статус самбарыг идэвхгүй болгох болон өөрчлөх"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Апп нь статус самбарыг идэвхгүй болгох эсвэл систем дүрсийг нэмэх, хасах боломжтой."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"статусын хэсэг болох"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 9b2f1be..1e08228 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"डिव्‍हाइसच्‍या फिंगरप्रिंट सेंन्सरवरील जेश्चर कॅप्‍चर करू शकते."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"स्क्रीनशॉट घ्या"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"डिस्प्लेचा स्क्रीनशॉट घेऊ शकतो."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"पूर्वावलोकन, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"स्टेटस बार अक्षम करा किंवा सुधारित करा"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"स्टेटस बार अक्षम करण्यासाठी किंवा सिस्टम चिन्हे जोडण्यासाठी आणि काढण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"स्टेटस बार होऊ द्या"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index fefa9f5..dca9de6 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Boleh menangkap gerak isyarat yang dilakukan pada penderia cap jari peranti."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ambil tangkapan skrin"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Boleh mengambil tangkapan skrin paparan."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Pratonton, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"lumpuhkan atau ubah suai bar status"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Membenarkan apl melumpuhkan bar status atau menambah dan mengalih keluar ikon sistem."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"jadi bar status"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index fa13d38..70d352f 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"စက်ပစ္စည်း၏ လက်ဗွေအာရုံခံကိရိယာတွင် လုပ်ဆောင်ထားသည့် လက်ဟန်များကို မှတ်သားထားနိုင်သည်။"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ဖန်သားပြင်ဓာတ်ပုံ ရိုက်ရန်"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ဖန်သားပြင်ပြသမှုကို ဓာတ်ပုံရိုက်နိုင်ပါသည်။"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"<xliff:g id="DREAM_NAME">%1$s</xliff:g> အစမ်းကြည့်ခြင်း"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"အခြေအနေပြဘားအား အလုပ်မလုပ်ခိုင်းရန်သို့မဟုတ် မွမ်းမံရန်"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"အက်ပ်အား အခြေအနေပြ ဘားကို ပိတ်ခွင့် သို့မဟတ် စနစ် အိုင်ကွန်များကို ထည့်ခြင်း ဖယ်ရှားခြင်း ပြုလုပ်ခွင့် ပြုသည်။"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"အခြေအနေပြ ဘားဖြစ်ပါစေ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index aec0089..c9c277c 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan fange inn bevegelser som utføres på enhetens fingeravtrykkssensor."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ta skjermdump"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan ikke ta en skjermdump av skjermen."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Forhåndsvisning, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"deaktivere eller endre statusfeltet"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Lar appen deaktivere statusfeltet eller legge til og fjerne systemikoner."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"vise appen i statusfeltet"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 5fa9b6c..6e73867 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"यसले यन्त्रक‍ो फिंगरप्रिन्टसम्बन्धी सेन्सरमा गरिएका इसाराहरूलाई खिच्‍न सक्छ।"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"स्क्रिनसट लिनुहोस्"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"डिस्प्लेको स्क्रिनसट लिन सकिन्छ।"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"प्रिभ्यू, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"स्थिति पट्टिलाई अक्षम वा संशोधित गर्नुहोस्"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"स्थिति पट्टि असक्षम पार्न वा प्रणाली आइकनहरू थप्न र हटाउन एपलाई अनुमति दिन्छ।"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"स्टाटस बार हुन दिनुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index c2639db..ba43d79 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan gebaren registreren die op de vingerafdruksensor van het apparaat worden getekend."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Screenshot maken"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan een screenshot van het scherm maken."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Voorbeeld, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"statusbalk uitzetten of wijzigen"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Hiermee kan de app de statusbalk uitzetten of systeemiconen toevoegen en verwijderen."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"de statusbalk zijn"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 8619511..b37d01c 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ଡିଭାଇସ୍‌ର ଟିପଚିହ୍ନ ସେନସର୍ ଉପରେ ଜେଶ୍ଚର୍‍ କ୍ୟାପଚର୍‍ କାର୍ଯ୍ୟ କରାଯାଇପାରିବ।"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ସ୍କ୍ରିନସଟ୍ ନିଅନ୍ତୁ"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ଡିସପ୍ଲେର ଏକ ସ୍କ୍ରିନସଟ୍ ନିଆଯାଇପାରେ।"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"ପ୍ରିଭ୍ୟୁ, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"ଷ୍ଟାଟସ୍‌ ବାର୍‌କୁ ଅକ୍ଷମ କିମ୍ୱା ସଂଶୋଧନ କରନ୍ତୁ"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ଆପ୍‍କୁ, ସ୍ଥିତି ବାର୍‍ ଅକ୍ଷମ କରିବାକୁ କିମ୍ବା ସିଷ୍ଟମ୍‍ ଆଇକନ୍‍ ଯୋଡ଼ିବା କିମ୍ବା ବାହାର କରିବାକୁ ଦେଇଥାଏ।"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ଷ୍ଟାଟସ୍‍ ବାର୍‍ ରହିବାକୁ ଦିଅନ୍ତୁ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 57e187b..660d395 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"ਡੀਵਾਈਸਾਂ ਦੇ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ \'ਤੇ ਕੀਤੇ ਗਏ ਸੰਕੇਤਾਂ ਨੂੰ ਕੈਪਚਰ ਕਰ ਸਕਦੇ ਹਨ।"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਓ"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ਡਿਸਪਲੇ ਦਾ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲੈ ਸਕਦੀ ਹੈ।"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"ਪੂਰਵ-ਝਲਕ ਦੇਖੋ, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"ਸਥਿਤੀ ਪੱਟੀ ਬੰਦ ਕਰੋ ਜਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ਐਪ ਨੂੰ ਸਥਿਤੀ ਪੱਟੀ ਨੂੰ ਚਾਲੂ ਕਰਨ ਜਾਂ ਸਿਸਟਮ ਪ੍ਰਤੀਕਾਂ ਨੂੰ ਜੋੜਨ ਅਤੇ ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ਸਥਿਤੀ ਪੱਟੀ ਬਣਨ ਦਿਓ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index ae83e68..524f044 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -344,6 +344,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Może przechwytywać gesty wykonywane na czytniku linii papilarnych w urządzeniu."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Robienie zrzutu ekranu"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Może robić zrzuty ekranu wyświetlacza."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Podgląd, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"wyłączanie lub zmienianie paska stanu"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Pozwala aplikacji na wyłączanie paska stanu oraz dodawanie i usuwanie ikon systemowych."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"działanie jako pasek stanu"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 7886d2b..f22499a 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Pode captar gestos realizados no sensor de impressão digital do dispositivo."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fazer uma captura de tela"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pode fazer uma captura de tela."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Visualização, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"desativar ou modificar a barra de status"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite que o app desative a barra de status ou adicione e remova ícones do sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ser a barra de status"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 561e47e..b6fbbea 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Pode capturar gestos realizados no sensor de impressões digitais do dispositivo."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fazer captura de ecrã"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"É possível tirar uma captura de ecrã."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Pré-visualização, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"desativar ou modificar barra de estado"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite à app desativar a barra de estado ou adicionar e remover ícones do sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ser apresentada na barra de estado"</string>
@@ -1235,7 +1236,7 @@
     <string name="unsupported_display_size_show" msgid="980129850974919375">"Mostrar sempre"</string>
     <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> foi concebida para uma versão incompatível do SO Android e pode ter um comportamento inesperado. Pode estar disponível uma versão atualizada da app."</string>
     <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Mostrar sempre"</string>
-    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Verificar atualizações"</string>
+    <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Rever atualizações"</string>
     <string name="smv_application" msgid="3775183542777792638">"A app <xliff:g id="APPLICATION">%1$s</xliff:g> (processo <xliff:g id="PROCESS">%2$s</xliff:g>) violou a política StrictMode auto-imposta."</string>
     <string name="smv_process" msgid="1398801497130695446">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> violou a política StrictMode auto-imposta."</string>
     <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"O telemóvel está a atualizar…"</string>
@@ -1963,7 +1964,7 @@
     <string name="app_streaming_blocked_message_for_settings_dialog" product="tablet" msgid="3286849551133045896">"Não é possível aceder a esta app no seu dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>. Em alternativa, experimente no tablet."</string>
     <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Não é possível aceder a esta app no seu dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>. Em alternativa, experimente no telemóvel."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"Esta app foi concebida para uma versão mais antiga do Android e pode não funcionar corretamente. Experimente verificar se existem atualizações ou contacte o programador."</string>
-    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Verificar atualizações"</string>
+    <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Rever atualizações"</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Tem mensagens novas"</string>
     <string name="new_sms_notification_content" msgid="3197949934153460639">"Abra a app de SMS para ver"</string>
     <string name="profile_encrypted_title" msgid="9001208667521266472">"Algumas funcionalidades limitadas"</string>
@@ -2293,7 +2294,7 @@
     <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Uma app ainda está ativa"</string>
     <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"A app <xliff:g id="APP">%1$s</xliff:g> está a ser executada em segundo plano Toque para gerir a utilização da bateria."</string>
     <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"A app <xliff:g id="APP">%1$s</xliff:g> pode afetar a autonomia da bateria. Toque para rever as apps ativas."</string>
-    <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificar apps ativas"</string>
+    <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Rever apps ativas"</string>
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"Não é possível aceder à câmara do telemóvel a partir do dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"Não é possível aceder à câmara do tablet a partir do dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_secure_window" msgid="161700398158812314">"Não é possível aceder a isto durante o streaming. Em alternativa, experimente no telemóvel."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 7886d2b..f22499a 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Pode captar gestos realizados no sensor de impressão digital do dispositivo."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fazer uma captura de tela"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Pode fazer uma captura de tela."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Visualização, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"desativar ou modificar a barra de status"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite que o app desative a barra de status ou adicione e remova ícones do sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"ser a barra de status"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 301d14c..295187b 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Poate reda gesturile făcute pe senzorul de amprentă al dispozitivului."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Fă o captură de ecran"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Poate face o captură de ecran."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Previzualizare, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"dezactivare sau modificare bare de stare"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite aplicației să dezactiveze bara de stare sau să adauge și să elimine pictograme de sistem."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"să fie bara de stare"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index c7658177..b3bfebb 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -344,6 +344,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Использовать сканер отпечатков пальцев для дополнительных жестов."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Создавать скриншоты"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Создавать снимки экрана."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"<xliff:g id="DREAM_NAME">%1$s</xliff:g>: предпросмотр"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"Отключение/изменение строки состояния"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Приложение сможет отключать строку состояния, а также добавлять и удалять системные значки."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"Замена строки состояния"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 69d806a..5896d91 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"උපාංගයෙහි ඇඟිලි සලකුණු සංවේදකය මත සිදු කරන ඉංගිත ග්‍රහණය කළ හැකිය."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"තිර රුව ගන්න"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"සංදර්ශකයේ තිර රුවක් ගැනීමට හැකිය."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"පෙරදසුන, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"තත්ව තීරුව අබල කරන්න හෝ වෙනස් කරන්න"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"තත්ව තීරුව අක්‍රිය කිරීමට හෝ පද්ධති නිරූපක එකතු හෝ ඉවත් කිරීමට යෙදුමට අවසර දේ."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"තත්ත්ව තීරුව බවට පත්වීම"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 6bbfe0a..d84a751 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -344,6 +344,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Dokáže zaznamenať gestá na senzore odtlačkov prstov zariadenia."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Vytvoriť snímku obrazovky"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Je možné vytvoriť snímku obrazovky."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Ukážka, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"zakázanie alebo zmeny stavového riadka"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Umožňuje aplikácii vypnúť stavový riadok alebo pridať a odstrániť systémové ikony."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"vydávanie sa za stavový riadok"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 1accd18..9279cd6 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -344,6 +344,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Prepoznava poteze, narejene po tipalu prstnih odtisov naprave."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ustvarjanje posnetka zaslona"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Lahko naredi posnetek zaslona."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Predogled, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"onemogočanje ali spreminjanje vrstice stanja"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Aplikacijam omogoča onemogočenje vrstice stanja ali dodajanje in odstranjevanje ikon sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"postane vrstica stanja"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index a8fc00e..b42d2ed 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Mund të regjistrojë gjestet e kryera në sensorin e gjurmës së gishtit të pajisjes."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Nxirr një pamje të ekranit"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Mund të nxjerrë një pamje e ekranit."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Versioni paraprak, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"çaktivizo ose modifiko shiritin e statusit"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Lejon aplikacionin të çaktivizojë shiritin e statusit dhe të heqë ikonat e sistemit."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"të bëhet shiriti i statusit"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index bf8c0f7..986b405 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -343,6 +343,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Може да региструје покрете на сензору за отисак прста на уређају."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Направи снимак екрана"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Може да направи снимак екрана."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Преглед, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"онемогућавање или измена статусне траке"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Дозвољава апликацији да онемогући статусну траку или да додаје и уклања системске иконе."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"функционисање као статусна трака"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 177615d..c822b5c 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan registrera rörelser som utförs med hjälp av enhetens fingeravtryckssensor."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ta skärmbild"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan ta en skärmbild av skärmen."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Förhandsgranskar <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"inaktivera eller ändra statusfält"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Tillåter att appen inaktiverar statusfältet eller lägger till och tar bort systemikoner."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"visas i statusfältet"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 1319d1b..304534b 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Inaweza kurekodi ishara zinazotekelezwa kwenye kitambua alama ya kidole."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Piga picha ya skrini"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Inaweza kupiga picha ya skrini ya onyesho."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Onyesho la kukagua, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"zima au rekebisha mwambaa hali"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Inaruhusu programu kulemaza upau wa hali au kuongeza na kutoa aikoni za mfumo."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"kuwa sehemu ya arifa"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 6b53c8e..a3f1420 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"சாதனத்தின் கைரேகை சென்சார்மேல் செய்யப்படும் சைகைகளைக் கேப்ட்சர் செய்ய முடியும்."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ஸ்கிரீன்ஷாட்டை எடுக்கும்"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"டிஸ்ப்ளேவை ஸ்கிரீன்ஷாட் எடுக்க முடியும்."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"மாதிரிக்காட்சி, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"நிலைப் பட்டியை முடக்குதல் அல்லது மாற்றுதல்"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"நிலைப் பட்டியை முடக்க அல்லது முறைமையில் ஐகான்களைச் சேர்க்க மற்றும் அகற்ற ஆப்ஸை அனுமதிக்கிறது."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"நிலைப் பட்டியில் இருக்கும்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index cff6773..f9880db 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"పరికర వేలిముద్ర సెన్సార్‌లో ఉపయోగించిన సంజ్ఞలను క్యాప్చర్ చేయవచ్చు."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"స్క్రీన్‌షాట్‌ను తీయండి"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"డిస్‌ప్లే యొక్క స్క్రీన్‌షాట్ తీసుకోవచ్చు."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"ప్రివ్యూ, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"స్టేటస్‌ బార్‌ను డిజేబుల్ చేయడం లేదా మార్చడం"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"స్టేటస్‌ బార్‌ను డిజేబుల్ చేయడానికి లేదా సిస్టమ్ చిహ్నాలను జోడించడానికి మరియు తీసివేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"స్టేటస్‌ పట్టీగా ఉండటం"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 10ee520..93fe817 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"สามารถจับท่าทางสัมผัสที่เกิดขึ้นบนเซ็นเซอร์ลายนิ้วมือของอุปกรณ์"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"ถ่ายภาพหน้าจอ"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ถ่ายภาพหน้าจอได้"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"ตัวอย่าง <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"ปิดการใช้งานหรือแก้ไขแถบสถานะ"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"อนุญาตให้แอปพลิเคชันปิดใช้งานแถบสถานะหรือเพิ่มและนำไอคอนระบบออก"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"เป็นแถบสถานะ"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index f4658cf..a56df48 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Makukunan ang mga galaw na ginawa sa sensor para sa fingerprint ng device."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Kumuha ng screenshot"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Puwedeng kumuha ng screenshot ng display."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Preview, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"i-disable o baguhin ang status bar"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Pinapayagan ang app na i-disable ang status bar o magdagdag at mag-alis ng mga icon ng system."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"maging status bar"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 0573fcd..270023d 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Cihazın parmak izi sensörlerinde gerçekleştirilen hareketleri yakalayabilir."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ekran görüntüsü al"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Ekran görüntüsü alınabilir."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Önizleme, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"durum çubuğunu devre dışı bırak veya değiştir"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Uygulamaya, durum çubuğunu devre dışı bırakma ve sistem simgelerini ekleyip kaldırma izni verir."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"durum çubuğunda olma"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index ad03757..8eddb31 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -344,6 +344,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Може фіксувати жести на сканері відбитків пальців."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Робити знімки екрана"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Може робити знімки екрана."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"<xliff:g id="DREAM_NAME">%1$s</xliff:g> (попередній перегляд)"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"вимикати чи змін. рядок стану"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Дозволяє програмі вимикати рядок стану чи додавати та видаляти піктограми системи."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"відображатися як рядок стану"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 4e03774..f98fc6c 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"آلہ کے فنگر پرنٹ سینسر پر کیے گئے اشاروں کو کیپچر کر سکتا ہے۔"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"اسکرین شاٹ لیں"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"ڈسپلے کا اسکرین شاٹ لیا جا سکتا ہے۔"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"پیش منظر، <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"اسٹیٹس بار کو غیر فعال یا اس میں ترمیم کریں"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"ایپ کو اسٹیٹس بار غیر فعال کرنے یا سسٹم آئیکنز شامل کرنے اور ہٹانے کی اجازت دیتا ہے۔"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"بطور اسٹیٹس بار کام لیں"</string>
@@ -2050,11 +2051,11 @@
     <string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"اَن انسٹال کریں"</string>
     <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"بہر صورت کھولیں"</string>
     <string name="harmful_app_warning_title" msgid="8794823880881113856">"ضرر رساں ایپ کا پتہ چلا"</string>
-    <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> کو آلے کے تمام لاگز تک رسائی کی اجازت دیں؟"</string>
+    <string name="log_access_confirmation_title" msgid="2343578467290592708">"‫<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> کو آلے کے تمام لاگز تک رسائی کی اجازت دیں؟"</string>
     <string name="log_access_confirmation_allow" msgid="5302517782599389507">"یک وقتی رسائی کی اجازت دیں"</string>
     <string name="log_access_confirmation_deny" msgid="7685790957455099845">"اجازت نہ دیں"</string>
     <string name="log_access_confirmation_body" product="default" msgid="1806692062668620735">"آپ کے آلے پر جو ہوتا ہے آلے کے لاگز اسے ریکارڈ کر لیتے ہیں۔ ایپس ان لاگز کا استعمال مسائل کو تلاش کرنے اور ان کو حل کرنے کے لیے کر سکتی ہیں۔\n\nکچھ لاگز میں حساس معلومات شامل ہو سکتی ہیں، اس لیے صرف اپنے بھروسے مند ایپس کو ہی آلے کے تمام لاگز تک رسائی کی اجازت دیں۔ \n\nاگر آپ اس ایپ کو آلے کے تمام لاگز تک رسائی کی اجازت نہیں دیتے ہیں تب بھی یہ اپنے لاگز تک رسائی حاصل کر سکتی ہے۔ آپ کے آلے کا مینوفیکچرر اب بھی آپ کے آلے پر کچھ لاگز یا معلومات تک رسائی حاصل کر سکتا ہے۔"</string>
-    <string name="log_access_confirmation_body" product="tv" msgid="7379536536425265262">"‏آپ کے آلے پر جو ہوتا ہے آلے کے لاگز اسے ریکارڈ کر لیتے ہیں۔ ایپس ان لاگز کا استعمال مسائل کو تلاش کرنے اور ان کو حل کرنے کے لیے کر سکتی ہیں۔\n\nکچھ لاگز میں حساس معلومات شامل ہو سکتی ہیں، اس لیے صرف اپنی بھروسے مند ایپس کو ہی آلے کے تمام لاگز تک رسائی کی اجازت دیں۔ \n\nاگر آپ اس ایپ کو آلے کے تمام لاگز تک رسائی کی اجازت نہیں دیتے ہیں تب بھی یہ اپنے لاگز تک رسائی حاصل کر سکتی ہے۔ آپ کے آلے کا مینوفیکچرر اب بھی آپ کے آلے پر کچھ لاگز یا معلومات تک رسائی حاصل کر سکتا ہے۔\n\ng.co/android/devicelogs پر مزید جانیں۔"</string>
+    <string name="log_access_confirmation_body" product="tv" msgid="7379536536425265262">"‏آپ کے آلے پر جو ہوتا ہے آلے کے لاگز اسے ریکارڈ کر لیتے ہیں۔ ایپس ان لاگز کا استعمال مسائل کو تلاش کرنے اور ان کو حل کرنے کے لیے کر سکتی ہیں۔\n\nکچھ لاگز میں حساس معلومات شامل ہو سکتی ہیں، اس لیے صرف اپنی بھروسے مند ایپس کو ہی آلے کے تمام لاگز تک رسائی کی اجازت دیں۔ \n\nاگر آپ اس ایپ کو آلے کے تمام لاگز تک رسائی کی اجازت نہیں دیتے ہیں تب بھی یہ اپنے لاگز تک رسائی حاصل کر سکتی ہے۔ آپ کے آلے کا مینوفیکچرر اب بھی آپ کے آلے پر کچھ لاگز یا معلومات تک رسائی حاصل کر سکتا ہے۔\n\nمزید جاننے کیلئے g.co/android/devicelogs ملاحظہ کریں۔"</string>
     <string name="log_access_do_not_show_again" msgid="1058690599083091552">"دوبارہ نہ دکھائیں"</string>
     <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> <xliff:g id="APP_2">%2$s</xliff:g> کے سلائسز دکھانا چاہتی ہے"</string>
     <string name="screenshot_edit" msgid="7408934887203689207">"ترمیم کریں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 8d3bedf..c328e6f 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Barmoq izi skanerida kiritilgan ishoralarni taniy oladi."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Skrinshot olish"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Ekrandan skrinshot olishi mumkin."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Razm solish, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"holat panelini o‘zgartirish yoki o‘chirish"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Ilova holat panelini o‘chirib qo‘yishi hamda tizim ikonkalarini qo‘shishi yoki olib tashlashi mumkin."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"holat qatorida ko‘rinishi"</string>
@@ -2050,8 +2051,8 @@
     <string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"O‘CHIRIB TASHLASH"</string>
     <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"BARIBIR OCHILSIN"</string>
     <string name="harmful_app_warning_title" msgid="8794823880881113856">"Zararli ilova aniqlandi"</string>
-    <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> ilovasining qurilmadagi barcha jurnallarga kirishiga ruxsat berilsinmi?"</string>
-    <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Bir matalik foydalanishga ruxsat berish"</string>
+    <string name="log_access_confirmation_title" msgid="2343578467290592708">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> uchun qurilmadagi barcha jurnallarga kirish ruxsati berilsinmi?"</string>
+    <string name="log_access_confirmation_allow" msgid="5302517782599389507">"Bir martalik ruxsat berish"</string>
     <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Rad etish"</string>
     <string name="log_access_confirmation_body" product="default" msgid="1806692062668620735">"Qurilma jurnaliga qurilma bilan yuz bergan hodisalar qaydlari yoziladi. Ilovalar bu jurnal qaydlari yordamida muammolarni topishi va bartaraf qilishi mumkin.\n\nAyrim jurnal qaydlarida maxfiy axborotlar yozilishi mumkin, shu sababli qurilmadagi barcha jurnal qaydlariga ruxsatni faqat ishonchli ilovalarga bering. \n\nBu ilovaga qurilmadagi barcha jurnal qaydlariga ruxsat berilmasa ham, u oʻzining jurnalini ocha oladi. Qurilma ishlab chiqaruvchisi ham ayrim jurnallar yoki qurilma haqidagi axborotlarni ocha oladi."</string>
     <string name="log_access_confirmation_body" product="tv" msgid="7379536536425265262">"Qurilma jurnaliga qurilma bilan yuz bergan hodisalar qaydlari yoziladi. Ilovalar bu jurnal qaydlari yordamida muammolarni topishi va bartaraf qilishi mumkin.\n\nAyrim jurnal qaydlarida maxfiy axborotlar yozilishi mumkin, shu sababli qurilmadagi barcha jurnal qaydlariga ruxsatni faqat ishonchli ilovalarga bering. \n\nBu ilovaga qurilmadagi barcha jurnal qaydlariga ruxsat berilmasa ham, u oʻzining jurnalini ocha oladi. Qurilma ishlab chiqaruvchisi ham ayrim jurnallar yoki qurilma haqidagi axborotlarni ocha oladi.\n\nBatafsil: g.co/android/devicelogs."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index f30df3b..c71a33d 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Có thể ghi lại các cử chỉ được thực hiện trên cảm biến vân tay của thiết bị."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Chụp ảnh màn hình"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Có thể chụp ảnh màn hình."</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Bản xem trước, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"vô hiệu hóa hoặc sửa đổi thanh trạng thái"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Cho phép ứng dụng vô hiệu hóa thanh trạng thái hoặc thêm và xóa biểu tượng hệ thống."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"trở thành thanh trạng thái"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 2f3951f..5e11f19 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"可以捕捉在设备指纹传感器上执行的手势。"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"截取屏幕截图"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"可截取显示画面的屏幕截图。"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"预览,<xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"停用或修改状态栏"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"允许应用停用状态栏或者增删系统图标。"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"用作状态栏"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index ed5e989..3b3018a 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"可以擷取在裝置指紋感應器上執行的手勢。"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"擷取螢幕擷圖"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"可以擷取螢幕截圖。"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"預覽,<xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"停用或修改狀態列"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"允許應用程式停用狀態列,並可新增或移除系統圖示。"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"成為狀態列"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 08b597a..65967bd 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"可以擷取使用者對裝置的指紋感應器執行的手勢。"</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"擷取螢幕畫面"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"可以擷取螢幕畫面。"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"預覽,<xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"停用或變更狀態列"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"允許應用程式停用狀態列,並可新增或移除系統圖示。"</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"以狀態列顯示"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index a8cdb4e..524ccb1 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -342,6 +342,7 @@
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Ingathatha ukuthinta okwenziwe kunzwa yezigxivizo zeminwe zedivayisi."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Thatha isithombe-skrini"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Ingathatha isithombe-skrini sesiboniso"</string>
+    <string name="dream_preview_title" msgid="5570751491996100804">"Hlola kuqala, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"khubaza noma guqula ibha yomumo"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Ivumela uhlelo lokusebenza ukuthi yenze umudwa ochaza ngesimo ukuthi ungasebenzi noma ukufaka noma ukukhipha izithonjana zohlelo."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"yiba yibha yesimo"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index dafa0ad..58c8b29 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -6092,4 +6092,9 @@
 
     <!-- Whether to show weather on the lock screen by default. -->
     <bool name="config_lockscreenWeatherEnabledByDefault">false</bool>
+
+    <!-- Whether to reset Battery Stats on unplug when the battery level is high. -->
+    <bool name="config_batteryStatsResetOnUnplugHighBatteryLevel">true</bool>
+    <!-- Whether to reset Battery Stats on unplug if the battery was significantly charged -->
+    <bool name="config_batteryStatsResetOnUnplugAfterSignificantCharge">true</bool>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 591ba5f..8addca2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4903,4 +4903,7 @@
 
   <!-- Whether to show weather on the lockscreen by default. -->
   <java-symbol type="bool" name="config_lockscreenWeatherEnabledByDefault" />
+
+  <java-symbol type="bool" name="config_batteryStatsResetOnUnplugHighBatteryLevel" />
+  <java-symbol type="bool" name="config_batteryStatsResetOnUnplugAfterSignificantCharge" />
 </resources>
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsResetTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsResetTest.java
new file mode 100644
index 0000000..9c2d332
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsResetTest.java
@@ -0,0 +1,362 @@
+/*
+ * 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.internal.os;
+
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.os.BatteryManager;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class BatteryStatsResetTest {
+
+    private static final int BATTERY_NOMINAL_VOLTAGE_MV = 3700;
+    private static final int BATTERY_CAPACITY_UAH = 4_000_000;
+    private static final int BATTERY_CHARGE_RATE_SECONDS_PER_LEVEL = 100;
+
+    private MockClock mMockClock;
+    private MockBatteryStatsImpl mBatteryStatsImpl;
+
+
+    /**
+     * Battery status. Must be one of the following:
+     * {@link BatteryManager#BATTERY_STATUS_UNKNOWN}
+     * {@link BatteryManager#BATTERY_STATUS_CHARGING}
+     * {@link BatteryManager#BATTERY_STATUS_DISCHARGING}
+     * {@link BatteryManager#BATTERY_STATUS_NOT_CHARGING}
+     * {@link BatteryManager#BATTERY_STATUS_FULL}
+     */
+    private int mBatteryStatus;
+    /**
+     * Battery health. Must be one of the following:
+     * {@link BatteryManager#BATTERY_HEALTH_UNKNOWN}
+     * {@link BatteryManager#BATTERY_HEALTH_GOOD}
+     * {@link BatteryManager#BATTERY_HEALTH_OVERHEAT}
+     * {@link BatteryManager#BATTERY_HEALTH_DEAD}
+     * {@link BatteryManager#BATTERY_HEALTH_OVER_VOLTAGE}
+     * {@link BatteryManager#BATTERY_HEALTH_UNSPECIFIED_FAILURE}
+     * {@link BatteryManager#BATTERY_HEALTH_COLD}
+     */
+    private int mBatteryHealth;
+    /**
+     * Battery plug type. Can be the union of any number of the following flags:
+     * {@link BatteryManager#BATTERY_PLUGGED_AC}
+     * {@link BatteryManager#BATTERY_PLUGGED_USB}
+     * {@link BatteryManager#BATTERY_PLUGGED_WIRELESS}
+     * {@link BatteryManager#BATTERY_PLUGGED_DOCK}
+     *
+     * Zero means the device is unplugged.
+     */
+    private int mBatteryPlugType;
+    private int mBatteryLevel;
+    private int mBatteryTemp;
+    private int mBatteryVoltageMv;
+    private int mBatteryChargeUah;
+    private int mBatteryChargeFullUah;
+    private long mBatteryChargeTimeToFullSeconds;
+
+    @Before
+    public void setUp() {
+        final Context context = InstrumentationRegistry.getContext();
+
+        mMockClock = new MockClock();
+        mBatteryStatsImpl = new MockBatteryStatsImpl(mMockClock, context.getFilesDir());
+        mBatteryStatsImpl.onSystemReady();
+
+
+        // Set up the battery state. Start off with a fully charged plugged in battery.
+        mBatteryStatus = BatteryManager.BATTERY_STATUS_FULL;
+        mBatteryHealth = BatteryManager.BATTERY_HEALTH_GOOD;
+        mBatteryPlugType = BatteryManager.BATTERY_PLUGGED_USB;
+        mBatteryLevel = 100;
+        mBatteryTemp = 70; // Arbitrary reasonable temperature.
+        mBatteryVoltageMv = BATTERY_NOMINAL_VOLTAGE_MV;
+        mBatteryChargeUah = BATTERY_CAPACITY_UAH;
+        mBatteryChargeFullUah = BATTERY_CAPACITY_UAH;
+        mBatteryChargeTimeToFullSeconds = 0;
+    }
+
+    @Test
+    public void testResetOnUnplug_highBatteryLevel() {
+        mBatteryStatsImpl.setBatteryStatsConfig(
+                new BatteryStatsImpl.BatteryStatsConfig.Builder()
+                        .setResetOnUnplugHighBatteryLevel(true)
+                        .build());
+
+        long expectedResetTimeUs = 0;
+
+        unplugBattery();
+        dischargeToLevel(60);
+
+        plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
+        chargeToLevel(80);
+        unplugBattery();
+        // Reset should not occur until battery level above 90.
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
+        chargeToLevel(95);
+        // Reset should not occur until unplug.
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        unplugBattery();
+        // Reset should occur on unplug now that battery level is high (>=90)
+        expectedResetTimeUs = mMockClock.elapsedRealtime() * 1000;
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        // disable high battery level reset on unplug.
+        mBatteryStatsImpl.setBatteryStatsConfig(
+                new BatteryStatsImpl.BatteryStatsConfig.Builder()
+                        .setResetOnUnplugHighBatteryLevel(false)
+                        .build());
+
+        dischargeToLevel(60);
+
+        plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
+        chargeToLevel(95);
+        unplugBattery();
+        // Reset should not occur since the high battery level logic has been disabled.
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+    }
+
+    @Test
+    public void testResetOnUnplug_significantCharge() {
+        mBatteryStatsImpl.setBatteryStatsConfig(
+                new BatteryStatsImpl.BatteryStatsConfig.Builder()
+                        .setResetOnUnplugAfterSignificantCharge(true)
+                        .build());
+        long expectedResetTimeUs = 0;
+
+        unplugBattery();
+        // Battery level dropped below 20%.
+        dischargeToLevel(15);
+
+        plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
+        chargeToLevel(50);
+        unplugBattery();
+        // Reset should not occur until battery level above 80
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
+        chargeToLevel(85);
+        unplugBattery();
+        // Reset should not occur because the charge session did not go from 20% to 80%
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        // Battery level dropped below 20%.
+        dischargeToLevel(15);
+
+        plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
+        chargeToLevel(85);
+        unplugBattery();
+        // Reset should occur after significant charge amount.
+        expectedResetTimeUs = mMockClock.elapsedRealtime() * 1000;
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        // disable reset on unplug after significant charge.
+        mBatteryStatsImpl.setBatteryStatsConfig(
+                new BatteryStatsImpl.BatteryStatsConfig.Builder()
+                        .setResetOnUnplugAfterSignificantCharge(false)
+                        .build());
+
+        // Battery level dropped below 20%.
+        dischargeToLevel(15);
+
+        plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
+        chargeToLevel(85);
+        unplugBattery();
+        // Reset should not occur after significant charge amount.
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+    }
+
+    @Test
+    public void testResetOnUnplug_manyPartialCharges() {
+        long expectedResetTimeUs = 0;
+
+        unplugBattery();
+        // Cumulative battery discharged: 60%.
+        dischargeToLevel(40);
+
+        plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
+        chargeToLevel(80);
+        unplugBattery();
+        // Reset should not occur
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        // Cumulative battery discharged: 100%.
+        dischargeToLevel(40);
+
+        plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
+        chargeToLevel(80);
+        unplugBattery();
+        // Reset should not occur
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        // Cumulative battery discharged: 140%.
+        dischargeToLevel(40);
+
+        plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
+        chargeToLevel(80);
+        unplugBattery();
+        // Reset should not occur
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        // Cumulative battery discharged: 180%.
+        dischargeToLevel(40);
+
+        plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
+        chargeToLevel(80);
+        unplugBattery();
+        // Reset should not occur
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        // Cumulative battery discharged: 220%.
+        dischargeToLevel(40);
+
+        plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
+        chargeToLevel(80);
+        unplugBattery();
+        // Should reset after >200% of cumulative battery discharge
+        expectedResetTimeUs = mMockClock.elapsedRealtime() * 1000;
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+    }
+
+    @Test
+    public void testResetWhilePluggedIn_longPlugIn() {
+        // disable high battery level reset on unplug.
+        mBatteryStatsImpl.setBatteryStatsConfig(
+                new BatteryStatsImpl.BatteryStatsConfig.Builder()
+                        .setResetOnUnplugHighBatteryLevel(false)
+                        .setResetOnUnplugAfterSignificantCharge(false)
+                        .build());
+        long expectedResetTimeUs = 0;
+
+        plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
+        mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
+        // Reset should not occur
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        // Increment time a day
+        incTimeMs(24L * 60L * 60L * 1000L);
+        mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
+        // Reset should still not occur
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        // Increment time a day
+        incTimeMs(24L * 60L * 60L * 1000L);
+        mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
+        // Reset 47 hour threshold crossed, reset should occur.
+        expectedResetTimeUs = mMockClock.elapsedRealtime() * 1000;
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        // Increment time a day
+        incTimeMs(24L * 60L * 60L * 1000L);
+        mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
+        // Reset should not occur
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        // Increment time a day
+        incTimeMs(24L * 60L * 60L * 1000L);
+        mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
+        // Reset another 47 hour threshold crossed, reset should occur.
+        expectedResetTimeUs = mMockClock.elapsedRealtime() * 1000;
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        // Increment time a day
+        incTimeMs(24L * 60L * 60L * 1000L);
+        mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
+        // Reset should not occur
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        unplugBattery();
+        plugBattery(BatteryManager.BATTERY_PLUGGED_USB);
+
+        // Increment time a day
+        incTimeMs(24L * 60L * 60L * 1000L);
+        mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
+        // Reset should not occur, since unplug occurred recently.
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+
+        // Increment time a day
+        incTimeMs(24L * 60L * 60L * 1000L);
+        mBatteryStatsImpl.maybeResetWhilePluggedInLocked();
+        // Reset another 47 hour threshold crossed, reset should occur.
+        expectedResetTimeUs = mMockClock.elapsedRealtime() * 1000;
+        assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs);
+    }
+
+    private void dischargeToLevel(int targetLevel) {
+        mBatteryStatus = BatteryManager.BATTERY_STATUS_DISCHARGING;
+        for (int level = mBatteryLevel - 1; level >= targetLevel; level--) {
+            prepareBatteryLevel(level);
+            incTimeMs(5000); // Arbitrary discharge rate.
+            updateBatteryState();
+        }
+    }
+
+    private void chargeToLevel(int targetLevel) {
+        mBatteryStatus = BatteryManager.BATTERY_STATUS_CHARGING;
+        for (int level = mBatteryLevel + 1; level <= targetLevel; level++) {
+            if (level >= 100) mBatteryStatus = BatteryManager.BATTERY_STATUS_FULL;
+            prepareBatteryLevel(level);
+            incTimeMs(BATTERY_CHARGE_RATE_SECONDS_PER_LEVEL * 1000);
+            updateBatteryState();
+        }
+    }
+
+    private void unplugBattery() {
+        mBatteryPlugType = 0;
+        updateBatteryState();
+    }
+
+    private void plugBattery(int type) {
+        mBatteryPlugType |= type;
+        updateBatteryState();
+    }
+
+    private void prepareBatteryLevel(int level) {
+        mBatteryLevel = level;
+        mBatteryChargeUah = mBatteryLevel * mBatteryChargeFullUah / 100;
+        mBatteryChargeTimeToFullSeconds =
+                (100 - mBatteryLevel) * BATTERY_CHARGE_RATE_SECONDS_PER_LEVEL;
+    }
+
+    private void incTimeMs(long milliseconds) {
+        mMockClock.realtime += milliseconds;
+        mMockClock.uptime += milliseconds / 2; // Arbitrary slower uptime accumulation
+        mMockClock.currentTime += milliseconds;
+    }
+
+    private void updateBatteryState() {
+        mBatteryStatsImpl.setBatteryStateLocked(mBatteryStatus, mBatteryHealth, mBatteryPlugType,
+                mBatteryLevel, mBatteryTemp, mBatteryVoltageMv, mBatteryChargeUah,
+                mBatteryChargeFullUah, mBatteryChargeTimeToFullSeconds,
+                mMockClock.elapsedRealtime(), mMockClock.uptimeMillis(),
+                mMockClock.currentTimeMillis());
+    }
+}
+
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
index 2742861..ae2d1af 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
@@ -342,7 +342,7 @@
         Context context = InstrumentationRegistry.getContext();
         BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
         mStatsRule.setCurrentTime(5 * MINUTE_IN_MS);
-        batteryStats.resetAllStatsCmdLocked();
+        batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
 
         BatteryUsageStatsStore batteryUsageStatsStore = new BatteryUsageStatsStore(context,
                 batteryStats, new File(context.getCacheDir(), "BatteryUsageStatsProviderTest"),
@@ -357,14 +357,14 @@
         batteryStats.noteFlashlightOffLocked(APP_UID,
                 20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS);
         mStatsRule.setCurrentTime(25 * MINUTE_IN_MS);
-        batteryStats.resetAllStatsCmdLocked();
+        batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
 
         batteryStats.noteFlashlightOnLocked(APP_UID,
                 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS);
         batteryStats.noteFlashlightOffLocked(APP_UID,
                 50 * MINUTE_IN_MS, 50 * MINUTE_IN_MS);
         mStatsRule.setCurrentTime(55 * MINUTE_IN_MS);
-        batteryStats.resetAllStatsCmdLocked();
+        batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
 
         // This section should be ignored because the timestamp is out or range
         batteryStats.noteFlashlightOnLocked(APP_UID,
@@ -372,7 +372,7 @@
         batteryStats.noteFlashlightOffLocked(APP_UID,
                 70 * MINUTE_IN_MS, 70 * MINUTE_IN_MS);
         mStatsRule.setCurrentTime(75 * MINUTE_IN_MS);
-        batteryStats.resetAllStatsCmdLocked();
+        batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
 
         // This section should be ignored because it represents the current stats session
         batteryStats.noteFlashlightOnLocked(APP_UID,
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java
index c9729fa..11b9047 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsStoreTest.java
@@ -84,7 +84,7 @@
 
         mMockClock.realtime = 1_000_000;
         mMockClock.uptime = 1_000_000;
-        mBatteryStats.resetAllStatsCmdLocked();
+        mBatteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
 
         final long[] timestamps = mBatteryUsageStatsStore.listBatteryUsageStatsTimestamps();
         assertThat(timestamps).hasLength(1);
@@ -114,7 +114,7 @@
         final int numberOfSnapshots =
                 (int) (MAX_BATTERY_STATS_SNAPSHOT_STORAGE_BYTES / snapshotFileSize);
         for (int i = 0; i < numberOfSnapshots + 2; i++) {
-            mBatteryStats.resetAllStatsCmdLocked();
+            mBatteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
 
             mMockClock.realtime += 10_000_000;
             mMockClock.uptime += 10_000_000;
@@ -141,7 +141,7 @@
             mMockClock.currentTime += 10_000_000;
             prepareBatteryStats();
 
-            mBatteryStats.resetAllStatsCmdLocked();
+            mBatteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
         }
 
         assertThat(getDirectorySize(mStoreDirectory)).isNotEqualTo(0);
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 0f45219..c7c9424 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -49,6 +49,7 @@
         "src/com/android/wm/shell/animation/Interpolators.java",
         "src/com/android/wm/shell/pip/PipContentOverlay.java",
         "src/com/android/wm/shell/startingsurface/SplashScreenExitAnimationUtils.java",
+        "src/com/android/wm/shell/draganddrop/DragAndDropConstants.java",
     ],
     path: "src",
 }
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background.xml
deleted file mode 100644
index 0d88113..0000000
--- a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2022 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle">
-    <solid android:color="@color/letterbox_education_accent_primary"/>
-    <corners android:radius="12dp"/>
-</shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml
index 42572d6..a269968 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml
@@ -14,7 +14,30 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-        android:color="@color/letterbox_education_dismiss_button_background_ripple">
-    <item android:drawable="@drawable/letterbox_education_dismiss_button_background"/>
-</ripple>
\ No newline at end of file
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+       android:insetTop="@dimen/letterbox_education_dialog_vertical_inset"
+       android:insetBottom="@dimen/letterbox_education_dialog_vertical_inset">
+    <ripple android:color="@color/letterbox_education_dismiss_button_background_ripple">
+        <item android:id="@android:id/mask">
+            <shape android:shape="rectangle">
+                <corners android:radius="@dimen/letterbox_education_dialog_button_radius"/>
+                <solid android:color="@android:color/white"/>
+            </shape>
+        </item>
+        <item>
+            <shape android:shape="rectangle">
+                <solid android:color="@android:color/transparent"/>
+            </shape>
+        </item>
+        <item>
+            <shape android:shape="rectangle">
+                <solid android:color="@color/letterbox_education_accent_primary"/>
+                <corners android:radius="@dimen/letterbox_education_dialog_button_radius"/>
+                <padding android:left="@dimen/letterbox_education_dialog_horizontal_padding"
+                         android:top="@dimen/letterbox_education_dialog_vertical_padding"
+                         android:right="@dimen/letterbox_education_dialog_horizontal_padding"
+                         android:bottom="@dimen/letterbox_education_dialog_vertical_padding"/>
+            </shape>
+        </item>
+    </ripple>
+</inset>
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_restart_button_background.xml b/libs/WindowManager/Shell/res/drawable/letterbox_restart_button_background.xml
deleted file mode 100644
index 60f3cfe..0000000
--- a/libs/WindowManager/Shell/res/drawable/letterbox_restart_button_background.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?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.
-  -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-       android:shape="rectangle">
-    <solid android:color="?androidprv:attr/colorAccentPrimaryVariant"/>
-    <corners android:radius="@dimen/letterbox_restart_dialog_button_radius"/>
-</shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_restart_button_background_ripple.xml b/libs/WindowManager/Shell/res/drawable/letterbox_restart_button_background_ripple.xml
index ef97ea1..1f12514 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_restart_button_background_ripple.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_restart_button_background_ripple.xml
@@ -14,7 +14,31 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-        android:color="@color/letterbox_restart_button_background_ripple">
-    <item android:drawable="@drawable/letterbox_restart_button_background"/>
-</ripple>
\ No newline at end of file
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+       xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+       android:insetTop="@dimen/letterbox_restart_dialog_vertical_inset"
+       android:insetBottom="@dimen/letterbox_restart_dialog_vertical_inset">
+    <ripple android:color="@color/letterbox_restart_dismiss_button_background_ripple">
+        <item android:id="@android:id/mask">
+            <shape android:shape="rectangle">
+                <corners android:radius="@dimen/letterbox_restart_dialog_button_radius"/>
+                <solid android:color="@android:color/white"/>
+            </shape>
+        </item>
+        <item>
+            <shape android:shape="rectangle">
+                <solid android:color="@android:color/transparent"/>
+            </shape>
+        </item>
+        <item>
+            <shape android:shape="rectangle">
+                <solid android:color="?androidprv:attr/colorAccentPrimaryVariant"/>
+                <corners android:radius="@dimen/letterbox_restart_dialog_button_radius"/>
+                <padding android:left="@dimen/letterbox_restart_dialog_horizontal_padding"
+                         android:top="@dimen/letterbox_restart_dialog_vertical_padding"
+                         android:right="@dimen/letterbox_restart_dialog_horizontal_padding"
+                         android:bottom="@dimen/letterbox_restart_dialog_vertical_padding"/>
+            </shape>
+        </item>
+    </ripple>
+</inset>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_restart_dismiss_button_background.xml b/libs/WindowManager/Shell/res/drawable/letterbox_restart_dismiss_button_background.xml
deleted file mode 100644
index af89d41..0000000
--- a/libs/WindowManager/Shell/res/drawable/letterbox_restart_dismiss_button_background.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?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.
-  -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-       android:shape="rectangle">
-    <stroke android:color="?androidprv:attr/colorAccentPrimaryVariant" android:width="1dp"/>
-    <solid android:color="?androidprv:attr/colorSurface" />
-    <corners android:radius="@dimen/letterbox_restart_dialog_button_radius"/>
-</shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_restart_dismiss_button_background_ripple.xml b/libs/WindowManager/Shell/res/drawable/letterbox_restart_dismiss_button_background_ripple.xml
index e32aefc..3aa0981 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_restart_dismiss_button_background_ripple.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_restart_dismiss_button_background_ripple.xml
@@ -14,7 +14,33 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-        android:color="@color/letterbox_restart_dismiss_button_background_ripple">
-    <item android:drawable="@drawable/letterbox_restart_dismiss_button_background"/>
-</ripple>
\ No newline at end of file
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+       xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+       android:insetTop="@dimen/letterbox_restart_dialog_vertical_inset"
+       android:insetBottom="@dimen/letterbox_restart_dialog_vertical_inset">
+    <ripple android:color="@color/letterbox_restart_dismiss_button_background_ripple">
+        <item android:id="@android:id/mask">
+            <shape android:shape="rectangle">
+                <corners android:radius="@dimen/letterbox_restart_dialog_button_radius"/>
+                <solid android:color="@android:color/white"/>
+            </shape>
+        </item>
+        <item>
+            <shape android:shape="rectangle">
+                <solid android:color="@android:color/transparent"/>
+            </shape>
+        </item>
+        <item>
+            <shape android:shape="rectangle">
+                <stroke android:color="?androidprv:attr/colorAccentPrimaryVariant"
+                        android:width="1dp"/>
+                <solid android:color="?androidprv:attr/colorSurface"/>
+                <corners android:radius="@dimen/letterbox_restart_dialog_button_radius"/>
+                <padding android:left="@dimen/letterbox_restart_dialog_horizontal_padding"
+                         android:top="@dimen/letterbox_restart_dialog_vertical_padding"
+                         android:right="@dimen/letterbox_restart_dialog_horizontal_padding"
+                         android:bottom="@dimen/letterbox_restart_dialog_vertical_padding"/>
+            </shape>
+        </item>
+    </ripple>
+</inset>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/compat_mode_hint.xml b/libs/WindowManager/Shell/res/layout/compat_mode_hint.xml
index 44b2f45..3d3c003 100644
--- a/libs/WindowManager/Shell/res/layout/compat_mode_hint.xml
+++ b/libs/WindowManager/Shell/res/layout/compat_mode_hint.xml
@@ -29,11 +29,15 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:lineSpacingExtra="4sp"
+        android:letterSpacing="0.02"
         android:background="@drawable/compat_hint_bubble"
         android:padding="16dp"
         android:textAlignment="viewStart"
         android:textColor="@color/compat_controls_text"
-        android:textSize="14sp"/>
+        android:textSize="14sp"
+        android:fontFamily="@*android:string/config_bodyFontFamily"
+        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+    />
 
     <ImageView
         android:layout_width="wrap_content"
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml
index c65f24d..095576b 100644
--- a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml
@@ -29,6 +29,8 @@
         android:layout_marginBottom="20dp"/>
 
     <TextView
+        android:fontFamily="@*android:string/config_bodyFontFamily"
+        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"
         android:id="@+id/letterbox_education_dialog_action_text"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
index 3a44eb9..e8edad1 100644
--- a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
@@ -69,6 +69,8 @@
                     android:text="@string/letterbox_education_dialog_title"
                     android:textAlignment="center"
                     android:textColor="@color/compat_controls_text"
+                    android:fontFamily="@*android:string/config_bodyFontFamilyMedium"
+                    android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Headline"
                     android:textSize="24sp"/>
 
                 <LinearLayout
@@ -95,10 +97,16 @@
                 </LinearLayout>
 
                 <Button
+                    android:fontFamily="@*android:string/config_bodyFontFamily"
+                    android:fontWeight="500"
+                    android:lineHeight="20dp"
+                    android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Small"
                     android:id="@+id/letterbox_education_dialog_dismiss_button"
+                    android:textStyle="bold"
                     android:layout_width="match_parent"
                     android:layout_height="56dp"
                     android:layout_marginTop="40dp"
+                    android:textSize="14sp"
                     android:background=
                         "@drawable/letterbox_education_dismiss_button_background_ripple"
                     android:text="@string/letterbox_education_got_it"
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 26246fc..0a5134e 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Bo 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Bo 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Volskerm onder"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Verdeel links"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Verdeel regs"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Verdeel bo"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Verdeel onder"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Gebruik eenhandmodus"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Swiep van die onderkant van die skerm af op of tik enige plek bo die program om uit te gaan"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Begin eenhandmodus"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Maak toe"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Terug"</string>
     <string name="handle_text" msgid="1766582106752184456">"Handvatsel"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Appikoon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Volskerm"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Rekenaarmodus"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Verdeelde skerm"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Meer"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Sweef"</string>
+    <string name="select_text" msgid="5139083974039906583">"Kies"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Skermskoot"</string>
+    <string name="close_text" msgid="4986518933445178928">"Maak toe"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Maak kieslys toe"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 7f0a3ab..6734195 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ከላይ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ከላይ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"የታች ሙሉ ማያ ገጽ"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"ወደ ግራ ከፋፍል"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"ወደ ቀኝ ከፋፍል"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"ወደ ላይ ከፋፍል"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"ወደ ታች ከፋፍል"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ባለአንድ እጅ ሁነታን በመጠቀም ላይ"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ለመውጣት ከማያው ግርጌ ወደ ላይ ይጥረጉ ወይም ከመተግበሪያው በላይ ማንኛውም ቦታ ላይ መታ ያድርጉ"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ባለአንድ እጅ ሁነታ ጀምር"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"ዝጋ"</string>
     <string name="back_button_text" msgid="1469718707134137085">"ተመለስ"</string>
     <string name="handle_text" msgid="1766582106752184456">"መያዣ"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"የመተግበሪያ አዶ"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ሙሉ ማያ"</string>
     <string name="desktop_text" msgid="1077633567027630454">"የዴስክቶፕ ሁነታ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"የተከፈለ ማያ ገጽ"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ተጨማሪ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ተንሳፋፊ"</string>
+    <string name="select_text" msgid="5139083974039906583">"ምረጥ"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"ቅጽበታዊ ገጽ እይታ"</string>
+    <string name="close_text" msgid="4986518933445178928">"ዝጋ"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"ምናሌ ዝጋ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 7f81e50..6bef71a 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ضبط حجم النافذة العلوية ليكون ٥٠%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ضبط حجم النافذة العلوية ليكون ٣٠%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"عرض النافذة السفلية بملء الشاشة"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"تقسيم لليسار"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"تقسيم لليمين"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"تقسيم للأعلى"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"تقسيم للأسفل"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"استخدام وضع \"التصفح بيد واحدة\""</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"للخروج، مرِّر سريعًا من أسفل الشاشة إلى أعلاها أو انقر في أي مكان فوق التطبيق."</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"بدء وضع \"التصفح بيد واحدة\""</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"إغلاق"</string>
     <string name="back_button_text" msgid="1469718707134137085">"رجوع"</string>
     <string name="handle_text" msgid="1766582106752184456">"مقبض"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"رمز التطبيق"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ملء الشاشة"</string>
     <string name="desktop_text" msgid="1077633567027630454">"وضع سطح المكتب"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"تقسيم الشاشة"</string>
     <string name="more_button_text" msgid="3655388105592893530">"المزيد"</string>
     <string name="float_button_text" msgid="9221657008391364581">"نافذة عائمة"</string>
+    <string name="select_text" msgid="5139083974039906583">"اختيار"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"لقطة شاشة"</string>
+    <string name="close_text" msgid="4986518933445178928">"إغلاق"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"إغلاق القائمة"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 505ca96..48b93ce 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"শীর্ষ স্ক্ৰীনখন ৫০% কৰক"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"শীর্ষ স্ক্ৰীনখন ৩০% কৰক"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"তলৰ স্ক্ৰীনখন সম্পূৰ্ণ স্ক্ৰীন কৰক"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"বাওঁফালে বিভাজন কৰক"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"সোঁফালে বিভাজন কৰক"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"একেবাৰে ওপৰৰফালে বিভাজন কৰক"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"একেবাৰে তলৰফালে বিভাজন কৰক"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"এখন হাতেৰে ব্যৱহাৰ কৰা ম’ড ব্যৱহাৰ কৰা"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"বাহিৰ হ’বলৈ স্ক্ৰীনখনৰ একেবাৰে তলৰ পৰা ওপৰলৈ ছোৱাইপ কৰক অথবা এপ্‌টোৰ ওপৰত যিকোনো ঠাইত টিপক"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"এখন হাতেৰে ব্যৱহাৰ কৰা ম\'ডটো আৰম্ভ কৰক"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"বন্ধ কৰক"</string>
     <string name="back_button_text" msgid="1469718707134137085">"উভতি যাওক"</string>
     <string name="handle_text" msgid="1766582106752184456">"হেণ্ডেল"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"এপৰ চিহ্ন"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"সম্পূৰ্ণ স্ক্ৰীন"</string>
     <string name="desktop_text" msgid="1077633567027630454">"ডেস্কটপ ম’ড"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"বিভাজিত স্ক্ৰীন"</string>
     <string name="more_button_text" msgid="3655388105592893530">"অধিক"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ওপঙা"</string>
+    <string name="select_text" msgid="5139083974039906583">"বাছনি কৰক"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"স্ক্ৰীনশ্বট"</string>
+    <string name="close_text" msgid="4986518933445178928">"বন্ধ কৰক"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"মেনু বন্ধ কৰক"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 0d754ba..8233dd3 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Yuxarı 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Yuxarı 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Aşağı tam ekran"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Sola ayırın"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Sağa ayırın"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Yuxarı ayırın"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Aşağı ayırın"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Birəlli rejim istifadəsi"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Çıxmaq üçün ekranın aşağısından yuxarıya doğru sürüşdürün və ya tətbiqin yuxarısında istənilən yerə toxunun"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Birəlli rejim başlasın"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Bağlayın"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Geriyə"</string>
     <string name="handle_text" msgid="1766582106752184456">"Hər kəsə açıq istifadəçi adı"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Tətbiq ikonası"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Tam Ekran"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Masaüstü Rejimi"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Bölünmüş Ekran"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Ardı"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Üzən pəncərə"</string>
+    <string name="select_text" msgid="5139083974039906583">"Seçin"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Skrinşot"</string>
+    <string name="close_text" msgid="4986518933445178928">"Bağlayın"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Menyunu bağlayın"</string>
 </resources>
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 46d9f2b..34c42a9 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gornji ekran 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Gornji ekran 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Režim celog ekrana za donji ekran"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Podelite levo"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Podelite desno"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Podelite u vrhu"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Podelite u dnu"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Korišćenje režima jednom rukom"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Da biste izašli, prevucite nagore od dna ekrana ili dodirnite bilo gde iznad aplikacije"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Pokrenite režim jednom rukom"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Zatvorite"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Nazad"</string>
     <string name="handle_text" msgid="1766582106752184456">"Identifikator"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Preko celog ekrana"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Režim za računare"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Podeljeni ekran"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Još"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Plutajuće"</string>
+    <string name="select_text" msgid="5139083974039906583">"Izaberite"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Snimak ekrana"</string>
+    <string name="close_text" msgid="4986518933445178928">"Zatvorite"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite meni"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 31d0484..4f21e73 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Верхні экран – 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Верхні экран – 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ніжні экран – поўнаэкранны рэжым"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Падзяліць злева"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Падзяліць справа"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Падзяліць уверсе"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Падзяліць унізе"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Выкарыстоўваецца рэжым кіравання адной рукой"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Каб выйсці, правядзіце па экране пальцам знізу ўверх або націсніце ў любым месцы над праграмай"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Запусціць рэжым кіравання адной рукой"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Закрыць"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
     <string name="handle_text" msgid="1766582106752184456">"Маркер"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Значок праграмы"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"На ўвесь экран"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Рэжым працоўнага стала"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Падзяліць экран"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Яшчэ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Зрабіць рухомым акном"</string>
+    <string name="select_text" msgid="5139083974039906583">"Выбраць"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Здымак экрана"</string>
+    <string name="close_text" msgid="4986518933445178928">"Закрыць"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Закрыць меню"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index 08fe365..9414649 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горен екран: 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Горен екран: 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Долен екран: Показване на цял екран"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Разделяне в лявата част"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Разделяне в дясната част"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Разделяне в горната част"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Разделяне в долната част"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Използване на режима за работа с една ръка"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"За изход прекарайте пръст нагоре от долната част на екрана или докоснете произволно място над приложението"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Стартиране на режима за работа с една ръка"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Затваряне"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
     <string name="handle_text" msgid="1766582106752184456">"Манипулатор"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Икона на приложението"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Цял екран"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Режим за настолни компютри"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Разделяне на екрана"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Още"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Плаващо"</string>
+    <string name="select_text" msgid="5139083974039906583">"Избиране"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Екранна снимка"</string>
+    <string name="close_text" msgid="4986518933445178928">"Затваряне"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Затваряне на менюто"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index ac0daa0..1718b51 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"শীর্ষ ৫০%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"শীর্ষ ৩০%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"নীচের অংশ নিয়ে পূর্ণ স্ক্রিন"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"স্ক্রিনের বাঁদিকে স্প্লিট করুন"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"স্ক্রিনের ডানদিকে স্প্লিট করুন"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"স্ক্রিনের উপরের দিকে স্প্লিট করুন"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"স্প্লিট করার বোতাম"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"\'এক হাতে ব্যবহার করার মোড\'-এর ব্যবহার"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"বেরিয়ে আসার জন্য, স্ক্রিনের নিচ থেকে উপরের দিকে সোয়াইপ করুন অথবা অ্যাপ আইকনের উপরে যেকোনও জায়গায় ট্যাপ করুন"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"\'এক হাতে ব্যবহার করার মোড\' শুরু করুন"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"বন্ধ করুন"</string>
     <string name="back_button_text" msgid="1469718707134137085">"ফিরে যান"</string>
     <string name="handle_text" msgid="1766582106752184456">"হাতল"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"অ্যাপ আইকন"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ফুলস্ক্রিন"</string>
     <string name="desktop_text" msgid="1077633567027630454">"ডেস্কটপ মোড"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"স্প্লিট স্ক্রিন"</string>
     <string name="more_button_text" msgid="3655388105592893530">"আরও"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ফ্লোট"</string>
+    <string name="select_text" msgid="5139083974039906583">"বেছে নিন"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"স্ক্রিনশট"</string>
+    <string name="close_text" msgid="4986518933445178928">"বন্ধ করুন"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"\'মেনু\' বন্ধ করুন"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 745e6fc..440cfad 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gore 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Gore 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Donji ekran kao cijeli ekran"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Podjela ulijevo"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Podjela udesno"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Podjela nagore"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Podjela nadolje"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Korištenje načina rada jednom rukom"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Da izađete, prevucite s dna ekrana prema gore ili dodirnite bilo gdje iznad aplikacije"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Započinjanje načina rada jednom rukom"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Zatvaranje"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Nazad"</string>
     <string name="handle_text" msgid="1766582106752184456">"Identifikator"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Cijeli ekran"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Način rada radne površine"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Podijeljeni ekran"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Više"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Lebdeći"</string>
+    <string name="select_text" msgid="5139083974039906583">"Odabir"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Snimak ekrana"</string>
+    <string name="close_text" msgid="4986518933445178928">"Zatvaranje"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Zatvaranje menija"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 727c319..a19706a 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Pantalla superior al 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Pantalla superior al 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pantalla inferior completa"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Divideix a l\'esquerra"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Divideix a la dreta"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Divideix a la part superior"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Divideix a la part inferior"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"S\'està utilitzant el mode d\'una mà"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Per sortir, llisca cap amunt des de la part inferior de la pantalla o toca qualsevol lloc a sobre de l\'aplicació"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Inicia el mode d\'una mà"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Tanca"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Enrere"</string>
     <string name="handle_text" msgid="1766582106752184456">"Ansa"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Icona de l\'aplicació"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Mode d\'escriptori"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Més"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Flotant"</string>
+    <string name="select_text" msgid="5139083974039906583">"Selecciona"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
+    <string name="close_text" msgid="4986518933445178928">"Tanca"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Tanca el menú"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index 395e12c..684a6ff 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % nahoře"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30 % nahoře"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Dolní část na celou obrazovku"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Rozdělit vlevo"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Rozdělit vpravo"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Rozdělit nahoře"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Rozdělit dole"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Používání režimu jedné ruky"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Režim ukončíte, když přejedete prstem z dolní části obrazovky nahoru nebo klepnete kamkoli nad aplikaci"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Spustit režim jedné ruky"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Zavřít"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Zpět"</string>
     <string name="handle_text" msgid="1766582106752184456">"Úchyt"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikace"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Celá obrazovka"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Režim počítače"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Rozdělená obrazovka"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Více"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Plovoucí"</string>
+    <string name="select_text" msgid="5139083974039906583">"Vybrat"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Snímek obrazovky"</string>
+    <string name="close_text" msgid="4986518933445178928">"Zavřít"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Zavřít nabídku"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index 5087c13..140610d 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Øverste 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Øverste 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Vis nederste del i fuld skærm"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Vis i venstre side"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Vis i højre side"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Vis øverst"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Vis nederst"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Brug af enhåndstilstand"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Du kan afslutte ved at stryge opad fra bunden af skærmen eller trykke et vilkårligt sted over appen"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Start enhåndstilstand"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Luk"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Tilbage"</string>
     <string name="handle_text" msgid="1766582106752184456">"Håndtag"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Fuld skærm"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Computertilstand"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Opdelt skærm"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Mere"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Svævende"</string>
+    <string name="select_text" msgid="5139083974039906583">"Vælg"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+    <string name="close_text" msgid="4986518933445178928">"Luk"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Luk menu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index e97f068..cd1213d 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % oben"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30 % oben"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Vollbild unten"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Links teilen"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Rechts teilen"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Oben teilen"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Unten teilen"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Einhandmodus wird verwendet"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Wenn du die App schließen möchtest, wische vom unteren Rand des Displays nach oben oder tippe auf eine beliebige Stelle oberhalb der App"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Einhandmodus starten"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Schließen"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Zurück"</string>
     <string name="handle_text" msgid="1766582106752184456">"Ziehpunkt"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"App-Symbol"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Vollbild"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Desktopmodus"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Geteilter Bildschirm"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Mehr"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Frei schwebend"</string>
+    <string name="select_text" msgid="5139083974039906583">"Auswählen"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+    <string name="close_text" msgid="4986518933445178928">"Schließen"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Menü schließen"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index df82625..2e6b912 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Πάνω 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Πάνω 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Κάτω πλήρης οθόνη"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Διαχωρισμός αριστερά"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Διαχωρισμός δεξιά"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Διαχωρισμός επάνω"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Διαχωρισμός κάτω"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Χρήση λειτουργίας ενός χεριού"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Για έξοδο, σύρετε προς τα πάνω από το κάτω μέρος της οθόνης ή πατήστε οπουδήποτε πάνω από την εφαρμογή."</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Έναρξη λειτουργίας ενός χεριού"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Κλείσιμο"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Πίσω"</string>
     <string name="handle_text" msgid="1766582106752184456">"Λαβή"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Εικονίδιο εφαρμογής"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Πλήρης οθόνη"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Λειτουργία επιφάνειας εργασίας"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Διαχωρισμός οθόνης"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Περισσότερα"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Κινούμενο"</string>
+    <string name="select_text" msgid="5139083974039906583">"Επιλογή"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Στιγμιότυπο οθόνης"</string>
+    <string name="close_text" msgid="4986518933445178928">"Κλείσιμο"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Κλείσιμο μενού"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index b1c9ba8..4d18f5e 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -96,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Close"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Back"</string>
     <string name="handle_text" msgid="1766582106752184456">"Handle"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Desktop mode"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Split screen"</string>
     <string name="more_button_text" msgid="3655388105592893530">"More"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Float"</string>
+    <string name="select_text" msgid="5139083974039906583">"Select"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+    <string name="close_text" msgid="4986518933445178928">"Close"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index 4aa2211..40b9d95 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -96,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Close"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Back"</string>
     <string name="handle_text" msgid="1766582106752184456">"Handle"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"App Icon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Fullscreen"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Desktop Mode"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Split Screen"</string>
     <string name="more_button_text" msgid="3655388105592893530">"More"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Float"</string>
+    <string name="select_text" msgid="5139083974039906583">"Select"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+    <string name="close_text" msgid="4986518933445178928">"Close"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Close Menu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index b1c9ba8..4d18f5e 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -96,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Close"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Back"</string>
     <string name="handle_text" msgid="1766582106752184456">"Handle"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Desktop mode"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Split screen"</string>
     <string name="more_button_text" msgid="3655388105592893530">"More"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Float"</string>
+    <string name="select_text" msgid="5139083974039906583">"Select"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+    <string name="close_text" msgid="4986518933445178928">"Close"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index b1c9ba8..4d18f5e 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -96,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Close"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Back"</string>
     <string name="handle_text" msgid="1766582106752184456">"Handle"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Desktop mode"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Split screen"</string>
     <string name="more_button_text" msgid="3655388105592893530">"More"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Float"</string>
+    <string name="select_text" msgid="5139083974039906583">"Select"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+    <string name="close_text" msgid="4986518933445178928">"Close"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
index 265849c..e0fbfbb 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
@@ -96,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎Close‎‏‎‎‏‎"</string>
     <string name="back_button_text" msgid="1469718707134137085">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‎‎‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‏‎‏‎Back‎‏‎‎‏‎"</string>
     <string name="handle_text" msgid="1766582106752184456">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‎‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‎‎‎Handle‎‏‎‎‏‎"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‏‏‎‎‏‎‎‎‎‏‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎‏‏‎App Icon‎‏‎‎‏‎"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‎‏‏‏‏‎Fullscreen‎‏‎‎‏‎"</string>
     <string name="desktop_text" msgid="1077633567027630454">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‎‏‎‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‏‎‎Desktop Mode‎‏‎‎‏‎"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‏‎‎Split Screen‎‏‎‎‏‎"</string>
     <string name="more_button_text" msgid="3655388105592893530">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎More‎‏‎‎‏‎"</string>
     <string name="float_button_text" msgid="9221657008391364581">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‎‏‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎Float‎‏‎‎‏‎"</string>
+    <string name="select_text" msgid="5139083974039906583">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‎‏‏‏‎‏‏‏‏‎‎‎‏‏‎‏‎‎‏‎‏‎‎‏‎‎‎‏‎‏‏‏‎Select‎‏‎‎‏‎"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎Screenshot‎‏‎‎‏‎"</string>
+    <string name="close_text" msgid="4986518933445178928">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‏‎‎‎‎‎Close‎‏‎‎‏‎"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‎‏‎‎‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‏‎Close Menu‎‏‎‎‏‎"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 1196aaf..f1357d8 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Superior: 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Superior: 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pantalla inferior completa"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Dividir a la izquierda"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Dividir a la derecha"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Dividir en la parte superior"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Dividir en la parte inferior"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Cómo usar el modo de una mano"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para salir, desliza el dedo hacia arriba desde la parte inferior de la pantalla o presiona cualquier parte arriba de la app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar el modo de una mano"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Atrás"</string>
     <string name="handle_text" msgid="1766582106752184456">"Controlador"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Ícono de la app"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Modo de escritorio"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Más"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Flotante"</string>
+    <string name="select_text" msgid="5139083974039906583">"Seleccionar"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
+    <string name="close_text" msgid="4986518933445178928">"Cerrar"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index c3c832b..9aa3d60 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Superior 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Superior 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pantalla inferior completa"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Dividir en la parte izquierda"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Dividir en la parte derecha"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Dividir en la parte superior"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Dividir en la parte inferior"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Usar modo Una mano"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para salir, desliza el dedo hacia arriba desde la parte inferior de la pantalla o toca cualquier zona que haya encima de la aplicación"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar modo Una mano"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Atrás"</string>
     <string name="handle_text" msgid="1766582106752184456">"Controlador"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Icono de la aplicación"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Modo Escritorio"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Más"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Flotante"</string>
+    <string name="select_text" msgid="5139083974039906583">"Seleccionar"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
+    <string name="close_text" msgid="4986518933445178928">"Cerrar"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index 4722c07..1e13283 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Ülemine: 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Ülemine: 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Alumine täisekraan"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Jaga vasakule"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Jaga paremale"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Jaga üles"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Jaga alla"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Ühekäerežiimi kasutamine"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Väljumiseks pühkige ekraani alaosast üles või puudutage rakenduse kohal olevat ala"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Ühekäerežiimi käivitamine"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Sule"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Tagasi"</string>
     <string name="handle_text" msgid="1766582106752184456">"Käepide"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Rakenduse ikoon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Täisekraan"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Lauaarvuti režiim"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Jagatud ekraanikuva"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Rohkem"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Hõljuv"</string>
+    <string name="select_text" msgid="5139083974039906583">"Vali"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Ekraanipilt"</string>
+    <string name="close_text" msgid="4986518933445178928">"Sule"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Sule menüü"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index e1c2a0d..72e94dc 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Ezarri goialdea % 50en"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Ezarri goialdea % 30en"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ezarri behealdea pantaila osoan"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Zatitu ezkerraldean"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Zatitu eskuinaldean"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Zatitu goialdean"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Zatitu behealdean"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Esku bakarreko modua erabiltzea"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Irteteko, pasatu hatza pantailaren behealdetik gora edo sakatu aplikazioaren gainaldea"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Abiarazi esku bakarreko modua"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Itxi"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Atzera"</string>
     <string name="handle_text" msgid="1766582106752184456">"Kontu-izena"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Aplikazioaren ikonoa"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Pantaila osoa"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Ordenagailuetarako modua"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Pantaila zatitua"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Gehiago"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Leiho gainerakorra"</string>
+    <string name="select_text" msgid="5139083974039906583">"Hautatu"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Pantaila-argazkia"</string>
+    <string name="close_text" msgid="4986518933445178928">"Itxi"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Itxi menua"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index 5a4871d..1cc5faa 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"٪۵۰ بالا"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"٪۳۰ بالا"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"تمام‌صفحه پایین"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"تقسیم از چپ"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"تقسیم از راست"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"تقسیم از بالا"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"تقسیم از پایین"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"استفاده از حالت یک‌دستی"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"برای خارج شدن، از پایین صفحه‌نمایش تند به‌طرف بالا بکشید یا در هر جایی از بالای برنامه که می‌خواهید ضربه بزنید"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"آغاز «حالت یک‌دستی»"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"بستن"</string>
     <string name="back_button_text" msgid="1469718707134137085">"برگشتن"</string>
     <string name="handle_text" msgid="1766582106752184456">"دستگیره"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"نماد برنامه"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"تمام‌صفحه"</string>
     <string name="desktop_text" msgid="1077633567027630454">"حالت رایانه"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"صفحهٔ دونیمه"</string>
     <string name="more_button_text" msgid="3655388105592893530">"بیشتر"</string>
     <string name="float_button_text" msgid="9221657008391364581">"شناور"</string>
+    <string name="select_text" msgid="5139083974039906583">"انتخاب"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"نماگرفت"</string>
+    <string name="close_text" msgid="4986518933445178928">"بستن"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"بستن منو"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index 56f444e..ee6f995d 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Yläosa 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Yläosa 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Alaosa koko näytölle"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Vasemmalla"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Oikealla"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Ylhäällä"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Alhaalla"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Yhden käden moodin käyttö"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Poistu pyyhkäisemällä ylös näytön alareunasta tai napauttamalla sovelluksen yllä"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Käynnistä yhden käden moodi"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Sulje"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Takaisin"</string>
     <string name="handle_text" msgid="1766582106752184456">"Kahva"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Sovelluskuvake"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Koko näyttö"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Työpöytätila"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Jaettu näyttö"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Lisää"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Kelluva ikkuna"</string>
+    <string name="select_text" msgid="5139083974039906583">"Valitse"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Kuvakaappaus"</string>
+    <string name="close_text" msgid="4986518933445178928">"Sulje"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Sulje valikko"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index e48d794..283876c 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % dans le haut"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30 % dans le haut"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Plein écran dans le bas"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Diviser à gauche"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Diviser à droite"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Diviser dans la partie supérieure"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Diviser dans la partie inférieure"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Utiliser le mode Une main"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Pour quitter, balayez l\'écran du bas vers le haut, ou touchez n\'importe où sur l\'écran en haut de l\'application"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Démarrer le mode Une main"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Fermer"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Retour"</string>
     <string name="handle_text" msgid="1766582106752184456">"Identifiant"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Icône de l\'application"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Plein écran"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Mode Bureau"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Écran partagé"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Plus"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Flottant"</string>
+    <string name="select_text" msgid="5139083974039906583">"Sélectionner"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Capture d\'écran"</string>
+    <string name="close_text" msgid="4986518933445178928">"Fermer"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index 301bca6..4e80360 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Écran du haut à 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Écran du haut à 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Écran du bas en plein écran"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Affichée à gauche"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Affichée à droite"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Affichée en haut"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Affichée en haut"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Utiliser le mode une main"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Pour quitter, balayez l\'écran de bas en haut ou appuyez n\'importe où au-dessus de l\'application"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Démarrer le mode une main"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Fermer"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Retour"</string>
     <string name="handle_text" msgid="1766582106752184456">"Poignée"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Icône d\'application"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Plein écran"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Mode ordinateur"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Écran partagé"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Plus"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Flottante"</string>
+    <string name="select_text" msgid="5139083974039906583">"Sélectionner"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Capture d\'écran"</string>
+    <string name="close_text" msgid="4986518933445178928">"Fermer"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index 967945c..974a687 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % arriba"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30 % arriba"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pantalla completa abaixo"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Dividir (esquerda)"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Dividir (dereita)"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Dividir (arriba)"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Dividir (abaixo)"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Como se usa o modo dunha soa man?"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para saír, pasa o dedo cara arriba desde a parte inferior da pantalla ou toca calquera lugar da zona situada encima da aplicación"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar modo dunha soa man"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Pechar"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Atrás"</string>
     <string name="handle_text" msgid="1766582106752184456">"Controlador"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Icona de aplicación"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Modo de escritorio"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Máis"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Flotante"</string>
+    <string name="select_text" msgid="5139083974039906583">"Seleccionar"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Captura de pantalla"</string>
+    <string name="close_text" msgid="4986518933445178928">"Pechar"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Pechar o menú"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index 653e1a69..be8a9ff 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"શીર્ષ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"શીર્ષ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"તળિયાની પૂર્ણ સ્ક્રીન"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"ડાબે વિભાજિત કરો"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"જમણે વિભાજિત કરો"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"ઉપર વિભાજિત કરો"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"નીચે વિભાજિત કરો"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"એક-હાથે વાપરો મોડનો ઉપયોગ કરી રહ્યાં છીએ"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"બહાર નીકળવા માટે, સ્ક્રીનની નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરો અથવા ઍપના આઇકન પર ગમે ત્યાં ટૅપ કરો"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"એક-હાથે વાપરો મોડ શરૂ કરો"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"બંધ કરો"</string>
     <string name="back_button_text" msgid="1469718707134137085">"પાછળ"</string>
     <string name="handle_text" msgid="1766582106752184456">"હૅન્ડલ"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"ઍપનું આઇકન"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"પૂર્ણસ્ક્રીન"</string>
     <string name="desktop_text" msgid="1077633567027630454">"ડેસ્કટૉપ મોડ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"સ્ક્રીનને વિભાજિત કરો"</string>
     <string name="more_button_text" msgid="3655388105592893530">"વધુ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ફ્લોટિંગ વિન્ડો"</string>
+    <string name="select_text" msgid="5139083974039906583">"પસંદ કરો"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"સ્ક્રીનશૉટ"</string>
+    <string name="close_text" msgid="4986518933445178928">"બંધ કરો"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"મેનૂ બંધ કરો"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 25b658a..120ecc9 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ऊपर की स्क्रीन को 50% बनाएं"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ऊपर की स्क्रीन को 30% बनाएं"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"नीचे की स्क्रीन को फ़ुल स्क्रीन बनाएं"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"स्क्रीन को बाएं हिस्से में स्प्लिट करें"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"स्क्रीन को दाएं हिस्से में स्प्लिट करें"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"स्क्रीन को ऊपर के हिस्से में स्प्लिट करें"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"स्क्रीन को सबसे नीचे वाले हिस्से में स्प्लिट करें"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"वन-हैंडेड मोड का इस्तेमाल करना"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"इस मोड से बाहर निकलने के लिए, स्क्रीन के सबसे निचले हिस्से से ऊपर की ओर स्वाइप करें या ऐप्लिकेशन के बाहर कहीं भी टैप करें"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"वन-हैंडेड मोड चालू करें"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"बंद करें"</string>
     <string name="back_button_text" msgid="1469718707134137085">"वापस जाएं"</string>
     <string name="handle_text" msgid="1766582106752184456">"हैंडल"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"ऐप्लिकेशन आइकॉन"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"फ़ुलस्क्रीन"</string>
     <string name="desktop_text" msgid="1077633567027630454">"डेस्कटॉप मोड"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"स्प्लिट स्क्रीन मोड"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ज़्यादा देखें"</string>
     <string name="float_button_text" msgid="9221657008391364581">"फ़्लोट"</string>
+    <string name="select_text" msgid="5139083974039906583">"चुनें"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"स्क्रीनशॉट"</string>
+    <string name="close_text" msgid="4986518933445178928">"बंद करें"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"मेन्यू बंद करें"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 57fd2fa..cde33c7 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gornji zaslon na 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Gornji zaslon na 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Donji zaslon u cijeli zaslon"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Podijeli lijevo"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Podijeli desno"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Podijeli gore"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Podijeli dolje"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Korištenje načina rada jednom rukom"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Za izlaz prijeđite prstom od dna zaslona prema gore ili dodirnite bio gdje iznad aplikacije"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Pokretanje načina rada jednom rukom"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Zatvori"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Natrag"</string>
     <string name="handle_text" msgid="1766582106752184456">"Pokazivač"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Puni zaslon"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Stolni način rada"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Razdvojeni zaslon"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Više"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Plutajući"</string>
+    <string name="select_text" msgid="5139083974039906583">"Odaberite"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Snimka zaslona"</string>
+    <string name="close_text" msgid="4986518933445178928">"Zatvorite"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite izbornik"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index ee7ff86..7edd915 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Felső 50%-ra"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Felső 30%-ra"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Alsó teljes képernyőre"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Osztás a képernyő bal oldalán"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Osztás a képernyő jobb oldalán"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Osztás a képernyő tetején"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Osztás alul"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Egykezes mód használata"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"A kilépéshez csúsztasson felfelé a képernyő aljáról, vagy koppintson az alkalmazás felett a képernyő bármelyik részére"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Egykezes mód indítása"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Bezárás"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Vissza"</string>
     <string name="handle_text" msgid="1766582106752184456">"Fogópont"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Alkalmazásikon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Teljes képernyő"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Asztali üzemmód"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Osztott képernyő"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Továbbiak"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Lebegő"</string>
+    <string name="select_text" msgid="5139083974039906583">"Kiválasztás"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Képernyőkép"</string>
+    <string name="close_text" msgid="4986518933445178928">"Bezárás"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Menü bezárása"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 4538cec..94950a0 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Վերևի էկրանը՝ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Վերևի էկրանը՝ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ներքևի էկրանը՝ լիաէկրան"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Հավելվածը ձախ կողմում"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Հավելվածը աջ կողմում"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Հավելվածը վերևում"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Հավելվածը ներքևում"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Ինչպես օգտվել մեկ ձեռքի ռեժիմից"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Դուրս գալու համար մատը սահեցրեք էկրանի ներքևից վերև կամ հպեք հավելվածի վերևում որևէ տեղ։"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Գործարկել մեկ ձեռքի ռեժիմը"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Փակել"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Հետ"</string>
     <string name="handle_text" msgid="1766582106752184456">"Նշիչ"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Հավելվածի պատկերակ"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Լիաէկրան"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Համակարգչի ռեժիմ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Տրոհված էկրան"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Ավելին"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Լողացող պատուհան"</string>
+    <string name="select_text" msgid="5139083974039906583">"Ընտրել"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Սքրինշոթ"</string>
+    <string name="close_text" msgid="4986518933445178928">"Փակել"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Փակել ընտրացանկը"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index 6880d53..890b86a 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Atas 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Atas 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Layar penuh di bawah"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Pisahkan ke kiri"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Pisahkan ke kanan"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Pisahkan ke atas"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Pisahkan ke bawah"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Menggunakan mode satu tangan"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Untuk keluar, geser layar dari bawah ke atas atau ketuk di mana saja di atas aplikasi"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Mulai mode satu tangan"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Tutup"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Kembali"</string>
     <string name="handle_text" msgid="1766582106752184456">"Tuas"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Ikon Aplikasi"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Layar Penuh"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Mode Desktop"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Layar Terpisah"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Lainnya"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Mengambang"</string>
+    <string name="select_text" msgid="5139083974039906583">"Pilih"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+    <string name="close_text" msgid="4986518933445178928">"Tutup"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index 23c93a3..f4a9a57 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Efri 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Efri 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Neðri á öllum skjánum"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Skipta vinstra megin"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Skipta hægra megin"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Skipta efst"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Skipta neðst"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Notkun einhentrar stillingar"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Til að loka skaltu strjúka upp frá neðri hluta skjásins eða ýta hvar sem er fyrir ofan forritið"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Ræsa einhenta stillingu"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Loka"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Til baka"</string>
     <string name="handle_text" msgid="1766582106752184456">"Handfang"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Tákn forrits"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Allur skjárinn"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Skjáborðsstilling"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Skjáskipting"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Meira"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Reikult"</string>
+    <string name="select_text" msgid="5139083974039906583">"Velja"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Skjámynd"</string>
+    <string name="close_text" msgid="4986518933445178928">"Loka"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Loka valmynd"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index ece92cf..4647e9a 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Schermata superiore al 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Schermata superiore al 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Schermata inferiore a schermo intero"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Dividi a sinistra"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Dividi a destra"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Dividi in alto"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Dividi in basso"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Usare la modalità a una mano"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Per uscire, scorri verso l\'alto dalla parte inferiore dello schermo oppure tocca un punto qualsiasi sopra l\'app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Avvia la modalità a una mano"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Chiudi"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Indietro"</string>
     <string name="handle_text" msgid="1766582106752184456">"Handle"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Icona dell\'app"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Schermo intero"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Modalità desktop"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Schermo diviso"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Altro"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Mobile"</string>
+    <string name="select_text" msgid="5139083974039906583">"Seleziona"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+    <string name="close_text" msgid="4986518933445178928">"Chiudi"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Chiudi il menu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index 948137f..5dd99d0 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"עליון 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"למעלה 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"מסך תחתון מלא"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"פיצול שמאלה"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"פיצול ימינה"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"פיצול למעלה"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"פיצול למטה"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"איך להשתמש בתכונה \'מצב שימוש ביד אחת\'"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"כדי לצאת, יש להחליק למעלה מתחתית המסך או להקיש במקום כלשהו במסך מעל האפליקציה"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"הפעלה של מצב שימוש ביד אחת"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"סגירה"</string>
     <string name="back_button_text" msgid="1469718707134137085">"חזרה"</string>
     <string name="handle_text" msgid="1766582106752184456">"נקודת אחיזה"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"סמל האפליקציה"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"מסך מלא"</string>
     <string name="desktop_text" msgid="1077633567027630454">"ממשק המחשב"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"מסך מפוצל"</string>
     <string name="more_button_text" msgid="3655388105592893530">"עוד"</string>
     <string name="float_button_text" msgid="9221657008391364581">"בלונים"</string>
+    <string name="select_text" msgid="5139083974039906583">"בחירה"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"צילום מסך"</string>
+    <string name="close_text" msgid="4986518933445178928">"סגירה"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"סגירת התפריט"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 9fdb861..bde3eb1 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"上 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"上 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"下部全画面"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"左に分割"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"右に分割"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"上に分割"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"下に分割"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"片手モードの使用"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"終了するには、画面を下から上にスワイプするか、アプリの任意の場所をタップします"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"片手モードを開始します"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"閉じる"</string>
     <string name="back_button_text" msgid="1469718707134137085">"戻る"</string>
     <string name="handle_text" msgid="1766582106752184456">"ハンドル"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"アプリのアイコン"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"全画面表示"</string>
     <string name="desktop_text" msgid="1077633567027630454">"デスクトップ モード"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"分割画面"</string>
     <string name="more_button_text" msgid="3655388105592893530">"その他"</string>
     <string name="float_button_text" msgid="9221657008391364581">"フローティング"</string>
+    <string name="select_text" msgid="5139083974039906583">"選択"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"スクリーンショット"</string>
+    <string name="close_text" msgid="4986518933445178928">"閉じる"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"メニューを閉じる"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index d827f19..a455c74 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ზედა ეკრანი — 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ზედა ეკრანი — 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"ქვედა ნაწილის სრულ ეკრანზე გაშლა"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"გაყოფა მარცხნივ"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"გაყოფა მარჯვნივ"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"გაყოფა ზემოთ"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"გაყოფა ქვემოთ"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ცალი ხელის რეჟიმის გამოყენება"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"გასასვლელად გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ ან შეეხეთ ნებისმიერ ადგილას აპის ზემოთ"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ცალი ხელის რეჟიმის დაწყება"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"დახურვა"</string>
     <string name="back_button_text" msgid="1469718707134137085">"უკან"</string>
     <string name="handle_text" msgid="1766582106752184456">"იდენტიფიკატორი"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"აპის ხატულა"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"სრულ ეკრანზე"</string>
     <string name="desktop_text" msgid="1077633567027630454">"დესკტოპის რეჟიმი"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"ეკრანის გაყოფა"</string>
     <string name="more_button_text" msgid="3655388105592893530">"სხვა"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ფარფატი"</string>
+    <string name="select_text" msgid="5139083974039906583">"არჩევა"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"ეკრანის ანაბეჭდი"</string>
+    <string name="close_text" msgid="4986518933445178928">"დახურვა"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"მენიუს დახურვა"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index b0b0375..16189e0 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% жоғарғы жақта"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30% жоғарғы жақта"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Төменгісін толық экранға шығару"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Сол жақтан шығару"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Оң жақтан шығару"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Жоғарыдан шығару"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Астынан шығару"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Бір қолмен енгізу режимін пайдалану"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Шығу үшін экранның төменгі жағынан жоғары қарай сырғытыңыз немесе қолданбаның үстінен кез келген жерден түртіңіз."</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Бір қолмен енгізу режимін іске қосу"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Жабу"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Артқа"</string>
     <string name="handle_text" msgid="1766582106752184456">"Идентификатор"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Қолданба белгішесі"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Толық экран"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Компьютер режимі"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Экранды бөлу"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Қосымша"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Қалқыма"</string>
+    <string name="select_text" msgid="5139083974039906583">"Таңдау"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Скриншот"</string>
+    <string name="close_text" msgid="4986518933445178928">"Жабу"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Мәзірді жабу"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 3783067..70bcdbf 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ខាងលើ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ខាងលើ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"អេក្រង់ពេញខាងក្រោម"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"បំបែក​ខាងឆ្វេង"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"បំបែក​ខាងស្ដាំ"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"បំបែក​ខាងលើ"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"បំបែក​ខាងក្រោម"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"កំពុងប្រើ​មុខងារប្រើដៃម្ខាង"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ដើម្បីចាកចេញ សូមអូសឡើងលើ​ពីផ្នែកខាងក្រោមអេក្រង់ ឬចុចផ្នែកណាមួយ​នៅខាងលើកម្មវិធី"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ចាប់ផ្ដើម​មុខងារប្រើដៃម្ខាង"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"បិទ"</string>
     <string name="back_button_text" msgid="1469718707134137085">"ថយក្រោយ"</string>
     <string name="handle_text" msgid="1766582106752184456">"ឈ្មោះអ្នកប្រើប្រាស់"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"រូប​កម្មវិធី"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"អេក្រង់​ពេញ"</string>
     <string name="desktop_text" msgid="1077633567027630454">"មុខងារកុំព្យូទ័រ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"មុខងារ​បំបែក​អេក្រង់"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ច្រើនទៀត"</string>
     <string name="float_button_text" msgid="9221657008391364581">"អណ្ដែត"</string>
+    <string name="select_text" msgid="5139083974039906583">"ជ្រើសរើស"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"រូបថតអេក្រង់"</string>
+    <string name="close_text" msgid="4986518933445178928">"បិទ"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"បិទ​ម៉ឺនុយ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 45fd76f..86cc71c 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% ಮೇಲಕ್ಕೆ"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30% ಮೇಲಕ್ಕೆ"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"ಕೆಳಗಿನ ಪೂರ್ಣ ಪರದೆ"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"ಎಡಕ್ಕೆ ವಿಭಜಿಸಿ"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"ಬಲಕ್ಕೆ ವಿಭಜಿಸಿ"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"ಮೇಲಕ್ಕೆ ವಿಭಜಿಸಿ"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"ಕೆಳಕ್ಕೆ ವಿಭಜಿಸಿ"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ಒಂದು ಕೈ ಮೋಡ್ ಬಳಸುವುದರ ಬಗ್ಗೆ"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ನಿರ್ಗಮಿಸಲು, ಸ್ಕ್ರೀನ್‌ನ ಕೆಳಗಿನಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಅಥವಾ ಆ್ಯಪ್‌ನ ಮೇಲೆ ಎಲ್ಲಿಯಾದರೂ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ಒಂದು ಕೈ ಮೋಡ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಿ"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"ಮುಚ್ಚಿರಿ"</string>
     <string name="back_button_text" msgid="1469718707134137085">"ಹಿಂದಕ್ಕೆ"</string>
     <string name="handle_text" msgid="1766582106752184456">"ಹ್ಯಾಂಡಲ್"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"ಆ್ಯಪ್ ಐಕಾನ್"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ಫುಲ್‌ಸ್ಕ್ರೀನ್"</string>
     <string name="desktop_text" msgid="1077633567027630454">"ಡೆಸ್ಕ್‌ಟಾಪ್ ಮೋಡ್"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ಇನ್ನಷ್ಟು"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ಫ್ಲೋಟ್"</string>
+    <string name="select_text" msgid="5139083974039906583">"ಆಯ್ಕೆಮಾಡಿ"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್"</string>
+    <string name="close_text" msgid="4986518933445178928">"ಮುಚ್ಚಿ"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"ಮೆನು ಮುಚ್ಚಿ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 0ee1feb..d9711e5 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"위쪽 화면 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"위쪽 화면 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"아래쪽 화면 전체화면"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"왼쪽으로 분할"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"오른쪽으로 분할"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"위쪽으로 분할"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"아래쪽으로 분할"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"한 손 사용 모드 사용하기"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"화면 하단에서 위로 스와이프하거나 앱 상단을 탭하여 종료합니다."</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"한 손 사용 모드 시작"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"닫기"</string>
     <string name="back_button_text" msgid="1469718707134137085">"뒤로"</string>
     <string name="handle_text" msgid="1766582106752184456">"핸들"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"앱 아이콘"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"전체 화면"</string>
     <string name="desktop_text" msgid="1077633567027630454">"데스크톱 모드"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"화면 분할"</string>
     <string name="more_button_text" msgid="3655388105592893530">"더보기"</string>
     <string name="float_button_text" msgid="9221657008391364581">"플로팅"</string>
+    <string name="select_text" msgid="5139083974039906583">"선택"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"스크린샷"</string>
+    <string name="close_text" msgid="4986518933445178928">"닫기"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"메뉴 닫기"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 6798f49..391c3af 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Үстүнкү экранды 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Үстүнкү экранды 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ылдыйкы экранды толук экран режимине өткөрүү"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Солго бөлүү"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Оңго бөлүү"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Өйдө бөлүү"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Ылдый бөлүү"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Бир кол режимин колдонуу"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Чыгуу үчүн экранды ылдый жагынан өйдө сүрүңүз же колдонмонун өйдө жагын басыңыз"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Бир кол режимин баштоо"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Жабуу"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Артка"</string>
     <string name="handle_text" msgid="1766582106752184456">"Маркер"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Колдонмонун сүрөтчөсү"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Толук экран"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Компьютер режими"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Экранды бөлүү"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Дагы"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Калкыма"</string>
+    <string name="select_text" msgid="5139083974039906583">"Тандоо"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Скриншот"</string>
+    <string name="close_text" msgid="4986518933445178928">"Жабуу"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Менюну жабуу"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index b758c0c..bc1ac73 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ເທິງສຸດ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ເທິງສຸດ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"ເຕັມໜ້າຈໍລຸ່ມສຸດ"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"ແຍກຊ້າຍ"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"ແຍກຂວາ"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"ແຍກເທິງ"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"ແຍກລຸ່ມ"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ກຳລັງໃຊ້ໂໝດມືດຽວ"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ເພື່ອອອກ, ໃຫ້ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍ ຫຼື ແຕະບ່ອນໃດກໍໄດ້ຢູ່ເໜືອແອັບ"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ເລີ່ມໂໝດມືດຽວ"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"ປິດ"</string>
     <string name="back_button_text" msgid="1469718707134137085">"ກັບຄືນ"</string>
     <string name="handle_text" msgid="1766582106752184456">"ມືບັງຄັບ"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"ໄອຄອນແອັບ"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ເຕັມຈໍ"</string>
     <string name="desktop_text" msgid="1077633567027630454">"ໂໝດເດັສທັອບ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"ແບ່ງໜ້າຈໍ"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ເພີ່ມເຕີມ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ລອຍ"</string>
+    <string name="select_text" msgid="5139083974039906583">"ເລືອກ"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"ຮູບໜ້າຈໍ"</string>
+    <string name="close_text" msgid="4986518933445178928">"ປິດ"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"ປິດເມນູ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 84f4264..6dc5b44 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Viršutinis ekranas 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Viršutinis ekranas 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Apatinis ekranas viso ekrano režimu"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Išskaidyti kairėn"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Išskaidyti dešinėn"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Išskaidyti viršuje"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Išskaidyti apačioje"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Vienos rankos režimo naudojimas"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Jei norite išeiti, perbraukite aukštyn nuo ekrano apačios arba palieskite bet kur virš programos"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Pradėti vienos rankos režimą"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Uždaryti"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Atgal"</string>
     <string name="handle_text" msgid="1766582106752184456">"Rankenėlė"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Programos piktograma"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Visas ekranas"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Stalinio kompiuterio režimas"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Išskaidyto ekrano režimas"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Daugiau"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Slankusis langas"</string>
+    <string name="select_text" msgid="5139083974039906583">"Pasirinkti"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Ekrano kopija"</string>
+    <string name="close_text" msgid="4986518933445178928">"Uždaryti"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Uždaryti meniu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index bac75e3..76d8db3 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Augšdaļa 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Augšdaļa 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Apakšdaļu pa visu ekrānu"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Sadalījums pa kreisi"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Sadalījums pa labi"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Sadalījums augšdaļā"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Sadalījums apakšdaļā"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Vienas rokas režīma izmantošana"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Lai izietu, velciet augšup no ekrāna apakšdaļas vai pieskarieties jebkurā vietā virs lietotnes"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Pāriet vienas rokas režīmā"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Aizvērt"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Atpakaļ"</string>
     <string name="handle_text" msgid="1766582106752184456">"Turis"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Lietotnes ikona"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Pilnekrāna režīms"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Darbvirsmas režīms"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Sadalīt ekrānu"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Vairāk"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Peldošs"</string>
+    <string name="select_text" msgid="5139083974039906583">"Atlasīt"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Ekrānuzņēmums"</string>
+    <string name="close_text" msgid="4986518933445178928">"Aizvērt"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Aizvērt izvēlni"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index b96f8a1..190f729 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горниот 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Горниот 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Долниот на цел екран"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Подели налево"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Подели надесно"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Подели нагоре"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Подели долу"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Користење на режимот со една рака"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"За да излезете, повлечете нагоре од дното на екранот или допрете каде било над апликацијата"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Започни го режимот со една рака"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Затвори"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
     <string name="handle_text" msgid="1766582106752184456">"Прекар"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Икона на апликацијата"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Цел екран"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Режим за компјутер"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Поделен екран"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Повеќе"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Лебдечко"</string>
+    <string name="select_text" msgid="5139083974039906583">"Изберете"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Слика од екранот"</string>
+    <string name="close_text" msgid="4986518933445178928">"Затворете"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Затворете го менито"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index f67e7ab..7307f20 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"മുകളിൽ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"മുകളിൽ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"താഴെ പൂർണ്ണ സ്ക്രീൻ"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"ഇടത് ഭാഗത്തേക്ക് വിഭജിക്കുക"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"വലത് ഭാഗത്തേക്ക് വിഭജിക്കുക"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"മുകളിലേക്ക് വിഭജിക്കുക"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"താഴേക്ക് വിഭജിക്കുക"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ഒറ്റക്കൈ മോഡ് എങ്ങനെ ഉപയോഗിക്കാം"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"പുറത്ത് കടക്കാൻ, സ്ക്രീനിന്റെ ചുവടെ നിന്ന് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക അല്ലെങ്കിൽ ആപ്പിന് മുകളിലായി എവിടെയെങ്കിലും ടാപ്പ് ചെയ്യുക"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ഒറ്റക്കൈ മോഡ് ആരംഭിച്ചു"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"അടയ്ക്കുക"</string>
     <string name="back_button_text" msgid="1469718707134137085">"മടങ്ങുക"</string>
     <string name="handle_text" msgid="1766582106752184456">"ഹാൻഡിൽ"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"ആപ്പ് ഐക്കൺ"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"പൂർണ്ണസ്ക്രീൻ"</string>
     <string name="desktop_text" msgid="1077633567027630454">"ഡെസ്‌ക്ടോപ്പ് മോഡ്"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"സ്‌ക്രീൻ വിഭജനം"</string>
     <string name="more_button_text" msgid="3655388105592893530">"കൂടുതൽ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ഫ്ലോട്ട്"</string>
+    <string name="select_text" msgid="5139083974039906583">"തിരഞ്ഞെടുക്കുക"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"സ്ക്രീൻഷോട്ട്"</string>
+    <string name="close_text" msgid="4986518933445178928">"അടയ്ക്കുക"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"മെനു അടയ്ക്കുക"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 00846ef..bc43b70 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Дээд 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Дээд 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Доод бүтэн дэлгэц"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Зүүн талд хуваах"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Баруун талд хуваах"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Дээд талд хуваах"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Доод талд хуваах"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Нэг гарын горимыг ашиглаж байна"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Гарахын тулд дэлгэцийн доод хэсгээс дээш шударч эсвэл апп дээр хүссэн газраа товшино уу"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Нэг гарын горимыг эхлүүлэх"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Хаах"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Буцах"</string>
     <string name="handle_text" msgid="1766582106752184456">"Бариул"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Aппын дүрс тэмдэг"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Бүтэн дэлгэц"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Дэлгэцийн горим"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Дэлгэцийг хуваах"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Бусад"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Хөвөгч"</string>
+    <string name="select_text" msgid="5139083974039906583">"Сонгох"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Дэлгэцийн агшин"</string>
+    <string name="close_text" msgid="4986518933445178928">"Хаах"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Цэсийг хаах"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index 888e8dd..a31056d 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"शीर्ष 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"शीर्ष 10"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"तळाशी फुल स्क्रीन"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"डावीकडे स्प्लिट करा"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"उजवीकडे स्प्लिट करा"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"सर्वात वरती स्प्लिट करा"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"खालती स्प्लिट करा"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"एकहाती मोड वापरणे"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"बाहेर पडण्यासाठी स्क्रीनच्या खालून वरच्या दिशेने स्वाइप करा किंवा ॲपवर कोठेही टॅप करा"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"एकहाती मोड सुरू करा"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"बंद करा"</string>
     <string name="back_button_text" msgid="1469718707134137085">"मागे जा"</string>
     <string name="handle_text" msgid="1766582106752184456">"हँडल"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"अ‍ॅप आयकन"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"फुलस्‍क्रीन"</string>
     <string name="desktop_text" msgid="1077633567027630454">"डेस्कटॉप मोड"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"स्प्लिट स्क्रीन"</string>
     <string name="more_button_text" msgid="3655388105592893530">"आणखी"</string>
     <string name="float_button_text" msgid="9221657008391364581">"फ्लोट"</string>
+    <string name="select_text" msgid="5139083974039906583">"निवडा"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"स्क्रीनशॉट"</string>
+    <string name="close_text" msgid="4986518933445178928">"बंद करा"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"मेनू बंद करा"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index d4a659b..8435ccf 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Atas 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Atas 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Skrin penuh bawah"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Pisah kiri"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Pisah kanan"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Pisah atas"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Pisah bawah"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Menggunakan mod sebelah tangan"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Untuk keluar, leret ke atas daripada bahagian bawah skrin atau ketik pada mana-mana di bahagian atas apl"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Mulakan mod sebelah tangan"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Tutup"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Kembali"</string>
     <string name="handle_text" msgid="1766582106752184456">"Pemegang"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Ikon Apl"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Skrin penuh"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Mod Desktop"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Skrin Pisah"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Lagi"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Terapung"</string>
+    <string name="select_text" msgid="5139083974039906583">"Pilih"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Tangkapan skrin"</string>
+    <string name="close_text" msgid="4986518933445178928">"Tutup"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 6f8b3c7..acc9130 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"အပေါ်ဘက် မျက်နှာပြင် ၅၀%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"အပေါ်ဘက် မျက်နှာပြင် ၃၀%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"အောက်ခြေ မျက်နှာပြင်အပြည့်"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"ဘယ်ဘက်ကို ခွဲရန်"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"ညာဘက်ကို ခွဲရန်"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"ထိပ်ပိုင်းကို ခွဲရန်"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"အောက်ခြေကို ခွဲရန်"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"လက်တစ်ဖက်သုံးမုဒ် အသုံးပြုခြင်း"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ထွက်ရန် ဖန်သားပြင်၏အောက်ခြေမှ အပေါ်သို့ပွတ်ဆွဲပါ သို့မဟုတ် အက်ပ်အပေါ်ဘက် မည်သည့်နေရာတွင်မဆို တို့ပါ"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"လက်တစ်ဖက်သုံးမုဒ်ကို စတင်လိုက်သည်"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"ပိတ်ရန်"</string>
     <string name="back_button_text" msgid="1469718707134137085">"နောက်သို့"</string>
     <string name="handle_text" msgid="1766582106752184456">"သုံးသူအမည်"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"အက်ပ်သင်္ကေတ"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ဖန်သားပြင်အပြည့်"</string>
     <string name="desktop_text" msgid="1077633567027630454">"ဒက်စ်တော့မုဒ်"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"မျက်နှာပြင် ခွဲ၍ပြသရန်"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ပိုပြပါ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"မျှောရန်"</string>
+    <string name="select_text" msgid="5139083974039906583">"ရွေးရန်"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
+    <string name="close_text" msgid="4986518933445178928">"ပိတ်ရန်"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"မီနူး ပိတ်ရန်"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 1ea3907..6511567 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Sett størrelsen på den øverste delen av skjermen til 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Sett størrelsen på den øverste delen av skjermen til 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Utvid den nederste delen av skjermen til hele skjermen"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Del opp til venstre"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Del opp til høyre"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Del opp øverst"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Del opp nederst"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Bruk av enhåndsmodus"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"For å avslutte, sveip opp fra bunnen av skjermen eller trykk hvor som helst over appen"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Start enhåndsmodus"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Lukk"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Tilbake"</string>
     <string name="handle_text" msgid="1766582106752184456">"Håndtak"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Fullskjerm"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Skrivebordmodus"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Delt skjerm"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Mer"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Svevende"</string>
+    <string name="select_text" msgid="5139083974039906583">"Velg"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Skjermdump"</string>
+    <string name="close_text" msgid="4986518933445178928">"Lukk"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Lukk menyen"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index fd3485c..56bde82 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"माथिल्लो भाग ५०%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"माथिल्लो भाग ३०%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"तल्लो भाग फुल स्क्रिन"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"बायाँतिर स्प्लिट गर्नुहोस्"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"दायाँतिर स्प्लिट गर्नुहोस्"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"सिरानतिर स्प्लिट गर्नुहोस्"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"पुछारतिर स्प्लिट गर्नुहोस्"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"एक हाते मोड प्रयोग गरिँदै छ"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"बाहिर निस्कन, स्क्रिनको पुछारबाट माथितिर स्वाइप गर्नुहोस् वा एपभन्दा माथि जुनसुकै ठाउँमा ट्याप गर्नुहोस्"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"एक हाते मोड सुरु गर्नुहोस्"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"बन्द गर्नुहोस्"</string>
     <string name="back_button_text" msgid="1469718707134137085">"पछाडि"</string>
     <string name="handle_text" msgid="1766582106752184456">"ह्यान्डल"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"एपको आइकन"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"फुल स्क्रिन"</string>
     <string name="desktop_text" msgid="1077633567027630454">"डेस्कटप मोड"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"स्प्लिट स्क्रिन"</string>
     <string name="more_button_text" msgid="3655388105592893530">"थप"</string>
     <string name="float_button_text" msgid="9221657008391364581">"फ्लोट"</string>
+    <string name="select_text" msgid="5139083974039906583">"चयन गर्नुहोस्"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"स्क्रिनसट"</string>
+    <string name="close_text" msgid="4986518933445178928">"बन्द गर्नुहोस्"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"मेनु बन्द गर्नुहोस्"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index c3ab297..364774b 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Bovenste scherm 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Bovenste scherm 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Onderste scherm op volledig scherm"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Gesplitst scherm links"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Gesplitst scherm rechts"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Gesplitst scherm boven"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Gesplitst scherm onder"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Bediening met 1 hand gebruiken"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Als je wilt afsluiten, swipe je omhoog vanaf de onderkant van het scherm of tik je ergens boven de app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Bediening met 1 hand starten"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Sluiten"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Terug"</string>
     <string name="handle_text" msgid="1766582106752184456">"Gebruikersnaam"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"App-icoon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Volledig scherm"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Desktopmodus"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Gesplitst scherm"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Meer"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Zwevend"</string>
+    <string name="select_text" msgid="5139083974039906583">"Selecteren"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+    <string name="close_text" msgid="4986518933445178928">"Sluiten"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Menu sluiten"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index 90c90d3..59af0d9 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ଉପର ଆଡ଼କୁ 50% କରନ୍ତୁ"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ଉପର ଆଡ଼କୁ 30% କରନ୍ତୁ"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"ତଳ ଅଂଶର ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍‍"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"ବାମପଟକୁ ସ୍ପ୍ଲିଟ କରନ୍ତୁ"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"ଡାହାଣପଟକୁ ସ୍ପ୍ଲିଟ କରନ୍ତୁ"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"ଶୀର୍ଷକୁ ସ୍ପ୍ଲିଟ କରନ୍ତୁ"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"ନିମ୍ନକୁ ସ୍ଲିଟ କରନ୍ତୁ"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ଏକ-ହାତ ମୋଡ୍ ବ୍ୟବହାର କରି"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ବାହାରି ଯିବା ପାଇଁ, ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ କିମ୍ବା ଆପରେ ଯେ କୌଣସି ସ୍ଥାନରେ ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ଏକ-ହାତ ମୋଡ୍ ଆରମ୍ଭ କରନ୍ତୁ"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="back_button_text" msgid="1469718707134137085">"ପଛକୁ ଫେରନ୍ତୁ"</string>
     <string name="handle_text" msgid="1766582106752184456">"ହେଣ୍ଡେଲ"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"ଆପ ଆଇକନ"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ପୂର୍ଣ୍ଣସ୍କ୍ରିନ"</string>
     <string name="desktop_text" msgid="1077633567027630454">"ଡେସ୍କଟପ ମୋଡ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ଅଧିକ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ଫ୍ଲୋଟ"</string>
+    <string name="select_text" msgid="5139083974039906583">"ଚୟନ କରନ୍ତୁ"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"ସ୍କ୍ରିନସଟ"</string>
+    <string name="close_text" msgid="4986518933445178928">"ବନ୍ଦ କରନ୍ତୁ"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"ମେନୁ ବନ୍ଦ କରନ୍ତୁ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index b27e034..a40c7e5 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ਉੱਪਰ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ਉੱਪਰ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"ਹੇਠਾਂ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"ਖੱਬੇ ਪਾਸੇ ਵੰਡੋ"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"ਸੱਜੇ ਪਾਸੇ ਵੰਡੋ"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"ਸਿਖਰ \'ਤੇ ਵੰਡੋ"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"ਹੇਠਾਂ ਵੰਡੋ"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ਇੱਕ ਹੱਥ ਮੋਡ ਵਰਤਣਾ"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ਬਾਹਰ ਜਾਣ ਲਈ, ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ ਜਾਂ ਐਪ \'ਤੇ ਕਿਤੇ ਵੀ ਟੈਪ ਕਰੋ"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ਇੱਕ ਹੱਥ ਮੋਡ ਸ਼ੁਰੂ ਕਰੋ"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"ਬੰਦ ਕਰੋ"</string>
     <string name="back_button_text" msgid="1469718707134137085">"ਪਿੱਛੇ"</string>
     <string name="handle_text" msgid="1766582106752184456">"ਹੈਂਡਲ"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"ਐਪ ਪ੍ਰਤੀਕ"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ਪੂਰੀ-ਸਕ੍ਰੀਨ"</string>
     <string name="desktop_text" msgid="1077633567027630454">"ਡੈਸਕਟਾਪ ਮੋਡ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ਹੋਰ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ਫ਼ਲੋਟ"</string>
+    <string name="select_text" msgid="5139083974039906583">"ਚੁਣੋ"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
+    <string name="close_text" msgid="4986518933445178928">"ਬੰਦ ਕਰੋ"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"ਮੀਨੂ ਬੰਦ ਕਰੋ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index 6d00aaa..82ce6c9 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% górnej części ekranu"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30% górnej części ekranu"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Dolna część ekranu na pełnym ekranie"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Podziel po lewej"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Podziel po prawej"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Podziel u góry"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Podziel u dołu"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Korzystanie z trybu jednej ręki"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Aby zamknąć, przesuń palcem z dołu ekranu w górę lub kliknij dowolne miejsce nad aplikacją"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Uruchom tryb jednej ręki"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Zamknij"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Wstecz"</string>
     <string name="handle_text" msgid="1766582106752184456">"Uchwyt"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacji"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Pełny ekran"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Tryb pulpitu"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Podzielony ekran"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Więcej"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Pływające"</string>
+    <string name="select_text" msgid="5139083974039906583">"Wybierz"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Zrzut ekranu"</string>
+    <string name="close_text" msgid="4986518933445178928">"Zamknij"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Zamknij menu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index b2f3121..ee9000b 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Parte superior a 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Parte superior a 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Parte inferior em tela cheia"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Dividir para a esquerda"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Dividir para a direita"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Dividir para cima"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Dividir para baixo"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Como usar o modo para uma mão"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para sair, deslize de baixo para cima na tela ou toque em qualquer lugar acima do app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar o modo para uma mão"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Voltar"</string>
     <string name="handle_text" msgid="1766582106752184456">"Alça"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Ícone do app"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Tela cheia"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Modo área de trabalho"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Tela dividida"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Mais"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Ponto flutuante"</string>
+    <string name="select_text" msgid="5139083974039906583">"Selecionar"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Captura de tela"</string>
+    <string name="close_text" msgid="4986518933445178928">"Fechar"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 3f3be4b..f33a0ec 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% no ecrã superior"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30% no ecrã superior"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ecrã inferior inteiro"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Divisão à esquerda"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Divisão à direita"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Divisão na parte superior"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Divisão na parte inferior"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Utilize o modo para uma mão"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para sair, deslize rapidamente para cima a partir da parte inferior do ecrã ou toque em qualquer ponto acima da app."</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar o modo para uma mão"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Anterior"</string>
     <string name="handle_text" msgid="1766582106752184456">"Indicador"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Ícone da app"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Ecrã inteiro"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Modo de ambiente de trabalho"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Ecrã dividido"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Mais"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Flutuar"</string>
+    <string name="select_text" msgid="5139083974039906583">"Selecionar"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Captura de ecrã"</string>
+    <string name="close_text" msgid="4986518933445178928">"Fechar"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index b2f3121..ee9000b 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Parte superior a 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Parte superior a 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Parte inferior em tela cheia"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Dividir para a esquerda"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Dividir para a direita"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Dividir para cima"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Dividir para baixo"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Como usar o modo para uma mão"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para sair, deslize de baixo para cima na tela ou toque em qualquer lugar acima do app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar o modo para uma mão"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Voltar"</string>
     <string name="handle_text" msgid="1766582106752184456">"Alça"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Ícone do app"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Tela cheia"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Modo área de trabalho"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Tela dividida"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Mais"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Ponto flutuante"</string>
+    <string name="select_text" msgid="5139083974039906583">"Selecionar"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Captura de tela"</string>
+    <string name="close_text" msgid="4986518933445178928">"Fechar"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index 402ef6b..afd3fe8 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Partea de sus: 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Partea de sus: 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Partea de jos pe ecran complet"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Împarte în stânga"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Împarte în dreapta"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Împarte în sus"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Împarte în jos"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Folosirea modului cu o mână"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Pentru a ieși, glisează în sus din partea de jos a ecranului sau atinge oriunde deasupra ferestrei aplicației"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Activează modul cu o mână"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Închide"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Înapoi"</string>
     <string name="handle_text" msgid="1766582106752184456">"Ghidaj"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Pictograma aplicației"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Ecran complet"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Modul desktop"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Ecran împărțit"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Mai multe"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Flotantă"</string>
+    <string name="select_text" msgid="5139083974039906583">"Selectează"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Captură de ecran"</string>
+    <string name="close_text" msgid="4986518933445178928">"Închide"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Închide meniul"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index dd59545..1248103 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Верхний на 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Верхний на 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Нижний во весь экран"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Приложение слева"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Приложение справа"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Приложение сверху"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Приложение снизу"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Использование режима управления одной рукой"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Чтобы выйти, проведите по экрану снизу вверх или коснитесь области за пределами приложения."</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Запустить режим управления одной рукой"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Закрыть"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
     <string name="handle_text" msgid="1766582106752184456">"Маркер"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Значок приложения"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Полноэкранный режим"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Режим компьютера"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Разделить экран"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Ещё"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Плавающее окно"</string>
+    <string name="select_text" msgid="5139083974039906583">"Выбрать"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Скриншот"</string>
+    <string name="close_text" msgid="4986518933445178928">"Закрыть"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Закрыть меню"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 91342c4..15d2c36 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ඉහළම 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ඉහළම 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"පහළ පූර්ණ තිරය"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"වම බෙදන්න"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"දකුණ බෙදන්න"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"ඉහළ බෙදන්න"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"පහළ බෙදන්න"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"තනි-අත් ප්‍රකාරය භාවිත කරමින්"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"පිටවීමට, තිරයේ පහළ සිට ඉහළට ස්වයිප් කරන්න හෝ යෙදුමට ඉහළින් ඕනෑම තැනක තට්ටු කරන්න"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"තනි අත් ප්‍රකාරය ආරම්භ කරන්න"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"වසන්න"</string>
     <string name="back_button_text" msgid="1469718707134137085">"ආපසු"</string>
     <string name="handle_text" msgid="1766582106752184456">"හැඬලය"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"යෙදුම් නිරූපකය"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"පූර්ණ තිරය"</string>
     <string name="desktop_text" msgid="1077633567027630454">"ඩෙස්ක්ටොප් ප්‍රකාරය"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"බෙදුම් තිරය"</string>
     <string name="more_button_text" msgid="3655388105592893530">"තව"</string>
     <string name="float_button_text" msgid="9221657008391364581">"පාවෙන"</string>
+    <string name="select_text" msgid="5139083974039906583">"තෝරන්න"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"තිර රුව"</string>
+    <string name="close_text" msgid="4986518933445178928">"වසන්න"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"මෙනුව වසන්න"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index b9199c2..422c25d 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Horná – 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Horná – 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Dolná – na celú obrazovku"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Rozdeliť vľavo"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Rozdeliť vpravo"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Rozdeliť hore"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Rozdeliť dole"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Používanie režimu jednej ruky"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Ukončíte potiahnutím z dolnej časti obrazovky nahor alebo klepnutím kdekoľvek nad aplikáciu"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Spustiť režim jednej ruky"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Zavrieť"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Späť"</string>
     <string name="handle_text" msgid="1766582106752184456">"Rukoväť"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikácie"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Celá obrazovka"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Režim počítača"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Rozdelená obrazovka"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Viac"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Plávajúce"</string>
+    <string name="select_text" msgid="5139083974039906583">"Vybrať"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Snímka obrazovky"</string>
+    <string name="close_text" msgid="4986518933445178928">"Zavrieť"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Zavrieť ponuku"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 0fd44f0..7096998 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Zgornji 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Zgornji 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Spodnji v celozaslonski način"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Delitev levo"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Delitev desno"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Delitev zgoraj"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Delitev spodaj"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Uporaba enoročnega načina"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Za izhod povlecite z dna zaslona navzgor ali se dotaknite na poljubnem mestu nad aplikacijo"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Zagon enoročnega načina"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Zapri"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Nazaj"</string>
     <string name="handle_text" msgid="1766582106752184456">"Ročica"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Celozaslonsko"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Namizni način"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Razdeljen zaslon"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Več"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Lebdeče"</string>
+    <string name="select_text" msgid="5139083974039906583">"Izberi"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Posnetek zaslona"</string>
+    <string name="close_text" msgid="4986518933445178928">"Zapri"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Zapri meni"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index 00e63d2..3ef8b18 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Lart 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Lart 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ekrani i plotë poshtë"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Ndaj majtas"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Ndaj djathtas"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Ndaj lart"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Ndaj në fund"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Po përdor modalitetin e përdorimit me një dorë"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Për të dalë, rrëshqit lart nga fundi i ekranit ose trokit diku mbi aplikacion"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Modaliteti i përdorimit me një dorë"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Mbyll"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Pas"</string>
     <string name="handle_text" msgid="1766582106752184456">"Emërtimi"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Ikona e aplikacionit"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Ekrani i plotë"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Modaliteti i desktopit"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Ekrani i ndarë"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Më shumë"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Pluskuese"</string>
+    <string name="select_text" msgid="5139083974039906583">"Zgjidh"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Pamja e ekranit"</string>
+    <string name="close_text" msgid="4986518933445178928">"Mbyll"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Mbyll menynë"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index d0f689c..09c5ad1 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горњи екран 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Горњи екран 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Режим целог екрана за доњи екран"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Поделите лево"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Поделите десно"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Поделите у врху"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Поделите у дну"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Коришћење режима једном руком"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Да бисте изашли, превуците нагоре од дна екрана или додирните било где изнад апликације"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Покрените режим једном руком"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Затворите"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
     <string name="handle_text" msgid="1766582106752184456">"Идентификатор"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Икона апликације"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Преко целог екрана"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Режим за рачунаре"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Подељени екран"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Још"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Плутајуће"</string>
+    <string name="select_text" msgid="5139083974039906583">"Изаберите"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Снимак екрана"</string>
+    <string name="close_text" msgid="4986518933445178928">"Затворите"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Затворите мени"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index e3827d6..5bfa238 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Övre 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Övre 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Helskärm på nedre skärm"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Till vänster på delad skärm"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Till höger på delad skärm"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Upptill på delad skärm"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Nedtill på delad skärm"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Använda enhandsläge"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Avsluta genom att svepa uppåt från skärmens nederkant eller trycka ovanför appen"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Starta enhandsläge"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Stäng"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Tillbaka"</string>
     <string name="handle_text" msgid="1766582106752184456">"Handtag"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Helskärm"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Datorläge"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Delad skärm"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Mer"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Svävande"</string>
+    <string name="select_text" msgid="5139083974039906583">"Välj"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Skärmbild"</string>
+    <string name="close_text" msgid="4986518933445178928">"Stäng"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Stäng menyn"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 8c2f2ad..489d56e 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Juu 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Juu 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Skrini nzima ya chini"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Gawanya sehemu ya kushoto"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Gawanya sehemu ya kulia"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Gawanya sehemu ya juu"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Gawanya sehemu ya chini"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Kutumia hali ya kutumia kwa mkono mmoja"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Ili ufunge, telezesha kidole juu kutoka sehemu ya chini ya skrini au uguse mahali popote juu ya programu"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Anzisha hali ya kutumia kwa mkono mmoja"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Funga"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Rudi nyuma"</string>
     <string name="handle_text" msgid="1766582106752184456">"Ncha"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Aikoni ya Programu"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Skrini nzima"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Hali ya Kompyuta ya mezani"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Gawa Skrini"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Zaidi"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Inayoelea"</string>
+    <string name="select_text" msgid="5139083974039906583">"Chagua"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Picha ya skrini"</string>
+    <string name="close_text" msgid="4986518933445178928">"Funga"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Funga Menyu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index 4732e39..8a75b21 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"மேலே 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"மேலே 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"கீழ்ப்புறம் முழுத் திரை"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"இடதுபுறமாகப் பிரிக்கும்"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"வலதுபுறமாகப் பிரிக்கும்"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"மேற்புறமாகப் பிரிக்கும்"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"கீழ்புறமாகப் பிரிக்கும்"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ஒற்றைக் கைப் பயன்முறையைப் பயன்படுத்துதல்"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"வெளியேற, திரையின் கீழிருந்து மேல்நோக்கி ஸ்வைப் செய்யவும் அல்லது ஆப்ஸுக்கு மேலே ஏதேனும் ஓர் இடத்தில் தட்டவும்"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ஒற்றைக் கைப் பயன்முறையைத் தொடங்கும்"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"மூடும்"</string>
     <string name="back_button_text" msgid="1469718707134137085">"பின்செல்லும்"</string>
     <string name="handle_text" msgid="1766582106752184456">"ஹேண்டில்"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"ஆப்ஸ் ஐகான்"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"முழுத்திரை"</string>
     <string name="desktop_text" msgid="1077633567027630454">"டெஸ்க்டாப் பயன்முறை"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"திரையைப் பிரிக்கும்"</string>
     <string name="more_button_text" msgid="3655388105592893530">"கூடுதல் விருப்பத்தேர்வுகள்"</string>
     <string name="float_button_text" msgid="9221657008391364581">"மிதக்கும் சாளரம்"</string>
+    <string name="select_text" msgid="5139083974039906583">"தேர்ந்தெடுக்கும்"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"ஸ்கிரீன்ஷாட்"</string>
+    <string name="close_text" msgid="4986518933445178928">"மூடும்"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"மெனுவை மூடும்"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 093a848..d0e459a 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ఎగువ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ఎగువ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"దిగువ ఫుల్-స్క్రీన్‌"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"ఎడమ వైపున్న భాగంలో విభజించండి"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"కుడి వైపున్న భాగంలో విభజించండి"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"ఎగువ భాగంలో విభజించండి"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"దిగువ భాగంలో విభజించండి"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"వన్-హ్యాండెడ్ మోడ్‌ను ఉపయోగించడం"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"నిష్క్రమించడానికి, స్క్రీన్ కింది భాగం నుండి పైకి స్వైప్ చేయండి లేదా యాప్ పైన ఎక్కడైనా ట్యాప్ చేయండి"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"వన్-హ్యాండెడ్ మోడ్‌ను ప్రారంభిస్తుంది"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"మూసివేయండి"</string>
     <string name="back_button_text" msgid="1469718707134137085">"వెనుకకు"</string>
     <string name="handle_text" msgid="1766582106752184456">"హ్యాండిల్"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"యాప్ చిహ్నం"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ఫుల్-స్క్రీన్"</string>
     <string name="desktop_text" msgid="1077633567027630454">"డెస్క్‌టాప్ మోడ్"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"స్ప్లిట్ స్క్రీన్"</string>
     <string name="more_button_text" msgid="3655388105592893530">"మరిన్ని"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ఫ్లోట్"</string>
+    <string name="select_text" msgid="5139083974039906583">"ఎంచుకోండి"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"స్క్రీన్‌షాట్"</string>
+    <string name="close_text" msgid="4986518933445178928">"మూసివేయండి"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"మెనూను మూసివేయండి"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index f7c810b..2e926c4 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ด้านบน 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ด้านบน 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"เต็มหน้าจอด้านล่าง"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"แยกไปทางซ้าย"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"แยกไปทางขวา"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"แยกไปด้านบน"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"แยกไปด้านล่าง"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"การใช้โหมดมือเดียว"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"หากต้องการออก ให้เลื่อนขึ้นจากด้านล่างของหน้าจอหรือแตะที่ใดก็ได้เหนือแอป"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"เริ่มโหมดมือเดียว"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"ปิด"</string>
     <string name="back_button_text" msgid="1469718707134137085">"กลับ"</string>
     <string name="handle_text" msgid="1766582106752184456">"แฮนเดิล"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"ไอคอนแอป"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"เต็มหน้าจอ"</string>
     <string name="desktop_text" msgid="1077633567027630454">"โหมดเดสก์ท็อป"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"แยกหน้าจอ"</string>
     <string name="more_button_text" msgid="3655388105592893530">"เพิ่มเติม"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ล่องลอย"</string>
+    <string name="select_text" msgid="5139083974039906583">"เลือก"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"ภาพหน้าจอ"</string>
+    <string name="close_text" msgid="4986518933445178928">"ปิด"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"ปิดเมนู"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index 4660d6d..3db2507 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gawing 50% ang nasa itaas"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Gawing 30% ang nasa itaas"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"I-full screen ang nasa ibaba"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Hatiin sa kaliwa"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Hatiin sa kanan"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Hatiin sa itaas"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Hatiin sa ilalim"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Paggamit ng one-hand mode"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para lumabas, mag-swipe pataas mula sa ibaba ng screen o mag-tap kahit saan sa itaas ng app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Simulan ang one-hand mode"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Isara"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Bumalik"</string>
     <string name="handle_text" msgid="1766582106752184456">"Handle"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Icon ng App"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Fullscreen"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Desktop Mode"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Split Screen"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Higit pa"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Float"</string>
+    <string name="select_text" msgid="5139083974039906583">"Piliin"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string>
+    <string name="close_text" msgid="4986518933445178928">"Isara"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Isara ang Menu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 6fdfe56..e43e424 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Üstte %50"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Üstte %30"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Altta tam ekran"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Sol tarafta böl"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Sağ tarafta böl"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Üst tarafta böl"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Alt tarafta böl"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Tek el modunu kullanma"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Çıkmak için ekranın alt kısmından yukarı kaydırın veya uygulamanın üzerinde herhangi bir yere dokunun"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Tek el modunu başlat"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Kapat"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Geri"</string>
     <string name="handle_text" msgid="1766582106752184456">"Herkese açık kullanıcı adı"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Uygulama Simgesi"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Tam Ekran"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Masaüstü Modu"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Bölünmüş Ekran"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Daha Fazla"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Havada Süzülen"</string>
+    <string name="select_text" msgid="5139083974039906583">"Seç"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Ekran görüntüsü"</string>
+    <string name="close_text" msgid="4986518933445178928">"Kapat"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Menüyü kapat"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index c5cfd02..99f7e30 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Верхнє вікно на 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Верхнє вікно на 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Нижнє вікно на весь екран"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Розділити зліва"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Розділити справа"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Розділити вгорі"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Розділити внизу"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Як користуватися режимом керування однією рукою"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Щоб вийти, проведіть пальцем по екрану знизу вгору або торкніться екрана над додатком"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Увімкнути режим керування однією рукою"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Закрити"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
     <string name="handle_text" msgid="1766582106752184456">"Маркер"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Значок додатка"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"На весь екран"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Режим комп’ютера"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Розділити екран"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Більше"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Плаваюче вікно"</string>
+    <string name="select_text" msgid="5139083974039906583">"Вибрати"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Знімок екрана"</string>
+    <string name="close_text" msgid="4986518933445178928">"Закрити"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Закрити меню"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 9c138d9..abab3e7 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"اوپر %50"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"اوپر %30"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"نچلی فل اسکرین"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"دائیں طرف تقسیم کریں"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"بائیں طرف تقسیم کریں"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"اوپر کی طرف تقسیم کریں"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"نیچے کی طرف تقسیم کریں"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ایک ہاتھ کی وضع کا استعمال کرنا"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"باہر نکلنے کیلئے، اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں یا ایپ کے اوپر کہیں بھی تھپتھپائیں"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ایک ہاتھ کی وضع شروع کریں"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"بند کریں"</string>
     <string name="back_button_text" msgid="1469718707134137085">"پیچھے"</string>
     <string name="handle_text" msgid="1766582106752184456">"ہینڈل"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"ایپ کا آئیکن"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"مکمل اسکرین"</string>
     <string name="desktop_text" msgid="1077633567027630454">"ڈیسک ٹاپ موڈ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"اسپلٹ اسکرین"</string>
     <string name="more_button_text" msgid="3655388105592893530">"مزید"</string>
     <string name="float_button_text" msgid="9221657008391364581">"فلوٹ"</string>
+    <string name="select_text" msgid="5139083974039906583">"منتخب کریں"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"اسکرین شاٹ"</string>
+    <string name="close_text" msgid="4986518933445178928">"بند کریں"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"مینو بند کریں"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 907c5bd..90f3c60 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Tepada 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Tepada 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pastda to‘liq ekran"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Chapga ajratish"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Oʻngga ajratish"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Yuqoriga ajratish"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Pastga ajratish"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Ixcham rejimdan foydalanish"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Chiqish uchun ekran pastidan tepaga suring yoki ilovaning tepasidagi istalgan joyga bosing."</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Ixcham rejimni ishga tushirish"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Yopish"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Orqaga"</string>
     <string name="handle_text" msgid="1766582106752184456">"Identifikator"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Ilova belgisi"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Butun ekran"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Desktop rejimi"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Ekranni ikkiga ajratish"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Yana"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Pufakli"</string>
+    <string name="select_text" msgid="5139083974039906583">"Tanlash"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Skrinshot"</string>
+    <string name="close_text" msgid="4986518933445178928">"Yopish"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Menyuni yopish"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 211e231..535fee3 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Trên 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Trên 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Toàn màn hình phía dưới"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Chia đôi màn hình về bên trái"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Chia đôi màn hình về bên phải"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Chia đôi màn hình lên trên cùng"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Chia đôi màn hình xuống dưới cùng"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Cách dùng chế độ một tay"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Để thoát, hãy vuốt lên từ cuối màn hình hoặc nhấn vào vị trí bất kỳ phía trên ứng dụng"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Bắt đầu chế độ một tay"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Đóng"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Quay lại"</string>
     <string name="handle_text" msgid="1766582106752184456">"Xử lý"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Biểu tượng ứng dụng"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Toàn màn hình"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Chế độ máy tính"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Chia đôi màn hình"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Tuỳ chọn khác"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Nổi"</string>
+    <string name="select_text" msgid="5139083974039906583">"Chọn"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Ảnh chụp màn hình"</string>
+    <string name="close_text" msgid="4986518933445178928">"Đóng"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Đóng trình đơn"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index 3d0637a..83f703d 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"顶部 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"顶部 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"底部全屏"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"左分屏"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"右分屏"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"上分屏"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"下分屏"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"使用单手模式"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"如需退出,请从屏幕底部向上滑动,或点按应用上方的任意位置"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"启动单手模式"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"关闭"</string>
     <string name="back_button_text" msgid="1469718707134137085">"返回"</string>
     <string name="handle_text" msgid="1766582106752184456">"处理"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"应用图标"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"全屏"</string>
     <string name="desktop_text" msgid="1077633567027630454">"桌面模式"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"分屏"</string>
     <string name="more_button_text" msgid="3655388105592893530">"更多"</string>
     <string name="float_button_text" msgid="9221657008391364581">"悬浮"</string>
+    <string name="select_text" msgid="5139083974039906583">"选择"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"屏幕截图"</string>
+    <string name="close_text" msgid="4986518933445178928">"关闭"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"关闭菜单"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index c4df086..c83f65d 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"頂部 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"頂部 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"底部全螢幕"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"分割左側區域"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"分割右側區域"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"分割上方區域"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"分割下方區域"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"使用單手模式"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"如要退出,請從螢幕底部向上滑動,或輕按應用程式上方的任何位置"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"開始單手模式"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"關閉"</string>
     <string name="back_button_text" msgid="1469718707134137085">"返去"</string>
     <string name="handle_text" msgid="1766582106752184456">"控點"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"應用程式圖示"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"全螢幕"</string>
     <string name="desktop_text" msgid="1077633567027630454">"桌面模式"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"分割螢幕"</string>
     <string name="more_button_text" msgid="3655388105592893530">"更多"</string>
     <string name="float_button_text" msgid="9221657008391364581">"浮動"</string>
+    <string name="select_text" msgid="5139083974039906583">"選取"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"螢幕截圖"</string>
+    <string name="close_text" msgid="4986518933445178928">"關閉"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index 2d9e7f3..08df469 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"以 50% 的螢幕空間顯示頂端畫面"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"以 30% 的螢幕空間顯示頂端畫面"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"以全螢幕顯示底部畫面"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"分割左側區域"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"分割右側區域"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"分割上方區域"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"分割下方區域"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"使用單手模式"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"如要退出,請從螢幕底部向上滑動,或輕觸應用程式上方的任何位置"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"啟動單手模式"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"關閉"</string>
     <string name="back_button_text" msgid="1469718707134137085">"返回"</string>
     <string name="handle_text" msgid="1766582106752184456">"控點"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"應用程式圖示"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"全螢幕"</string>
     <string name="desktop_text" msgid="1077633567027630454">"電腦模式"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"分割畫面"</string>
     <string name="more_button_text" msgid="3655388105592893530">"更多"</string>
     <string name="float_button_text" msgid="9221657008391364581">"浮動"</string>
+    <string name="select_text" msgid="5139083974039906583">"選取"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"螢幕截圖"</string>
+    <string name="close_text" msgid="4986518933445178928">"關閉"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 5c60056..9232b72 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -47,14 +47,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Okuphezulu okungu-50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Okuphezulu okungu-30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ngaphansi kwesikrini esigcwele"</string>
-    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
-    <skip />
-    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
-    <skip />
-    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
-    <skip />
-    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
-    <skip />
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Hlukanisa ngakwesobunxele"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Hlukanisa ngakwesokudla"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Hlukanisa phezulu"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Hlukanisa phansi"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Ukusebenzisa imodi yesandla esisodwa"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Ukuze uphume, swayipha ngaphezulu kusuka ngezansi kwesikrini noma thepha noma kuphi ngenhla kohlelo lokusebenza"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Qalisa imodi yesandla esisodwa"</string>
@@ -100,9 +96,14 @@
     <string name="close_button_text" msgid="2913281996024033299">"Vala"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Emuva"</string>
     <string name="handle_text" msgid="1766582106752184456">"Isibambo"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Isithonjana Se-app"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Isikrini esigcwele"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Imodi Yedeskithophu"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Hlukanisa isikrini"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Okwengeziwe"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Iflowuthi"</string>
+    <string name="select_text" msgid="5139083974039906583">"Khetha"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Isithombe-skrini"</string>
+    <string name="close_text" msgid="4986518933445178928">"Vala"</string>
+    <string name="collapse_menu_text" msgid="7515008122450342029">"Vala Imenyu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 6f31d06..336c156 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -273,6 +273,18 @@
     <!-- The space between two actions in the letterbox education dialog -->
     <dimen name="letterbox_education_dialog_space_between_actions">24dp</dimen>
 
+    <!-- The corner radius of the buttons in the letterbox education dialog -->
+    <dimen name="letterbox_education_dialog_button_radius">12dp</dimen>
+
+    <!-- The horizontal padding for the buttons in the letterbox education dialog -->
+    <dimen name="letterbox_education_dialog_horizontal_padding">16dp</dimen>
+
+    <!-- The vertical padding for the buttons in the letterbox education dialog -->
+    <dimen name="letterbox_education_dialog_vertical_padding">8dp</dimen>
+
+    <!-- The insets for the buttons in the letterbox education dialog -->
+    <dimen name="letterbox_education_dialog_vertical_inset">6dp</dimen>
+
     <!-- The margin between the dialog container and its parent. -->
     <dimen name="letterbox_restart_dialog_margin">24dp</dimen>
 
@@ -306,6 +318,15 @@
     <!-- The corner radius of the buttons in the restart dialog -->
     <dimen name="letterbox_restart_dialog_button_radius">18dp</dimen>
 
+    <!-- The insets for the buttons in the letterbox restart dialog -->
+    <dimen name="letterbox_restart_dialog_vertical_inset">6dp</dimen>
+
+    <!-- The horizontal padding for the buttons in the letterbox restart dialog -->
+    <dimen name="letterbox_restart_dialog_horizontal_padding">16dp</dimen>
+
+    <!-- The vertical padding for the buttons in the letterbox restart dialog -->
+    <dimen name="letterbox_restart_dialog_vertical_padding">8dp</dimen>
+
     <!-- The width of the brand image on staring surface. -->
     <dimen name="starting_surface_brand_image_width">200dp</dimen>
 
@@ -331,30 +352,6 @@
     -->
     <dimen name="overridable_minimal_size_pip_resizable_task">48dp</dimen>
 
-    <!-- The size of the drag handle / menu shown along with a floating task. -->
-    <dimen name="floating_task_menu_size">32dp</dimen>
-
-    <!-- The size of menu items in the floating task menu. -->
-    <dimen name="floating_task_menu_item_size">24dp</dimen>
-
-    <!-- The horizontal margin of menu items in the floating task menu. -->
-    <dimen name="floating_task_menu_item_padding">5dp</dimen>
-
-    <!-- The width of visible floating view region when stashed. -->
-    <dimen name="floating_task_stash_offset">32dp</dimen>
-
-    <!-- The amount of elevation for a floating task. -->
-    <dimen name="floating_task_elevation">8dp</dimen>
-
-    <!-- The amount of padding around the bottom and top of the task. -->
-    <dimen name="floating_task_vertical_padding">8dp</dimen>
-
-    <!-- The normal size of the dismiss target. -->
-    <dimen name="floating_task_dismiss_circle_size">150dp</dimen>
-
-    <!-- The smaller size of the dismiss target (shrinks when something is in the target). -->
-    <dimen name="floating_dismiss_circle_small">120dp</dimen>
-
     <!-- The thickness of shadows of a window that has focus in DIP. -->
     <dimen name="freeform_decor_shadow_focused_thickness">20dp</dimen>
 
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
index bae009a..0a0c49f 100644
--- a/libs/WindowManager/Shell/res/values/styles.xml
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -87,6 +87,9 @@
         <item name="android:textAppearance">
             @*android:style/TextAppearance.DeviceDefault.Headline
         </item>
+        <item name="android:fontFamily">
+            @*android:string/config_bodyFontFamilyMedium
+        </item>
     </style>
 
     <style name="RestartDialogBodyText">
@@ -97,24 +100,44 @@
         <item name="android:textAppearance">
             @*android:style/TextAppearance.DeviceDefault.Body2
         </item>
+        <item name="android:fontFamily">
+            @*android:string/config_bodyFontFamily
+        </item>
     </style>
 
     <style name="RestartDialogCheckboxText">
         <item name="android:textSize">16sp</item>
         <item name="android:textColor">?android:attr/textColorPrimary</item>
         <item name="android:lineSpacingExtra">4sp</item>
-        <item name="android:textAppearance">@*android:style/TextAppearance.DeviceDefault</item>
+        <item name="android:textAppearance">
+            @*android:style/TextAppearance.DeviceDefault.Headline
+        </item>
+        <item name="android:fontFamily">
+            @*android:string/config_bodyFontFamilyMedium
+        </item>
     </style>
 
     <style name="RestartDialogDismissButton">
         <item name="android:lineSpacingExtra">2sp</item>
         <item name="android:textSize">14sp</item>
         <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:textAppearance">
+            @*android:style/TextAppearance.DeviceDefault.Body2
+        </item>
+        <item name="android:fontFamily">
+            @*android:string/config_bodyFontFamily
+        </item>
     </style>
 
     <style name="RestartDialogConfirmButton">
         <item name="android:lineSpacingExtra">2sp</item>
         <item name="android:textSize">14sp</item>
         <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+        <item name="android:textAppearance">
+            @*android:style/TextAppearance.DeviceDefault.Body2
+        </item>
+        <item name="android:fontFamily">
+            @*android:string/config_bodyFontFamily
+        </item>
     </style>
 </resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DevicePostureController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DevicePostureController.java
new file mode 100644
index 0000000..22587f4
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DevicePostureController.java
@@ -0,0 +1,147 @@
+/*
+ * 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.common;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.content.Context;
+import android.hardware.devicestate.DeviceStateManager;
+import android.util.SparseIntArray;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.wm.shell.sysui.ShellInit;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Wrapper class to track the device posture change on Fold-ables.
+ * See also <a
+ * href="https://developer.android.com/guide/topics/large-screens/learn-about-foldables
+ * #foldable_postures">Foldable states and postures</a> for reference.
+ *
+ * Note that most of the implementation here inherits from
+ * {@link com.android.systemui.statusbar.policy.DevicePostureController}.
+ */
+public class DevicePostureController {
+    @IntDef(prefix = {"DEVICE_POSTURE_"}, value = {
+            DEVICE_POSTURE_UNKNOWN,
+            DEVICE_POSTURE_CLOSED,
+            DEVICE_POSTURE_HALF_OPENED,
+            DEVICE_POSTURE_OPENED,
+            DEVICE_POSTURE_FLIPPED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DevicePostureInt {}
+
+    // NOTE: These constants **must** match those defined for Jetpack Sidecar. This is because we
+    // use the Device State -> Jetpack Posture map to translate between the two.
+    public static final int DEVICE_POSTURE_UNKNOWN = 0;
+    public static final int DEVICE_POSTURE_CLOSED = 1;
+    public static final int DEVICE_POSTURE_HALF_OPENED = 2;
+    public static final int DEVICE_POSTURE_OPENED = 3;
+    public static final int DEVICE_POSTURE_FLIPPED = 4;
+
+    private final Context mContext;
+    private final ShellExecutor mMainExecutor;
+    private final List<OnDevicePostureChangedListener> mListeners = new ArrayList<>();
+    private final SparseIntArray mDeviceStateToPostureMap = new SparseIntArray();
+
+    private int mDevicePosture = DEVICE_POSTURE_UNKNOWN;
+
+    public DevicePostureController(
+            Context context, ShellInit shellInit, ShellExecutor mainExecutor) {
+        mContext = context;
+        mMainExecutor = mainExecutor;
+        shellInit.addInitCallback(this::onInit, this);
+    }
+
+    private void onInit() {
+        // Most of this is borrowed from WindowManager/Jetpack/DeviceStateManagerPostureProducer.
+        // Using the sidecar/extension libraries directly brings in a new dependency that it'd be
+        // good to avoid (along with the fact that sidecar is deprecated, and extensions isn't fully
+        // ready yet), and we'd have to make our own layer over the sidecar library anyway to easily
+        // allow the implementation to change, so it was easier to just interface with
+        // DeviceStateManager directly.
+        String[] deviceStatePosturePairs = mContext.getResources()
+                .getStringArray(R.array.config_device_state_postures);
+        for (String deviceStatePosturePair : deviceStatePosturePairs) {
+            String[] deviceStatePostureMapping = deviceStatePosturePair.split(":");
+            if (deviceStatePostureMapping.length != 2) {
+                continue;
+            }
+
+            int deviceState;
+            int posture;
+            try {
+                deviceState = Integer.parseInt(deviceStatePostureMapping[0]);
+                posture = Integer.parseInt(deviceStatePostureMapping[1]);
+            } catch (NumberFormatException e) {
+                continue;
+            }
+
+            mDeviceStateToPostureMap.put(deviceState, posture);
+        }
+
+        final DeviceStateManager deviceStateManager = mContext.getSystemService(
+                DeviceStateManager.class);
+        if (deviceStateManager != null) {
+            deviceStateManager.registerCallback(mMainExecutor, state -> onDevicePostureChanged(
+                    mDeviceStateToPostureMap.get(state, DEVICE_POSTURE_UNKNOWN)));
+        }
+    }
+
+    @VisibleForTesting
+    void onDevicePostureChanged(int devicePosture) {
+        if (devicePosture == mDevicePosture) return;
+        mDevicePosture = devicePosture;
+        mListeners.forEach(l -> l.onDevicePostureChanged(mDevicePosture));
+    }
+
+    /**
+     * Register {@link OnDevicePostureChangedListener} for device posture changes.
+     * The listener will receive callback with current device posture upon registration.
+     */
+    public void registerOnDevicePostureChangedListener(
+            @NonNull OnDevicePostureChangedListener listener) {
+        if (mListeners.contains(listener)) return;
+        mListeners.add(listener);
+        listener.onDevicePostureChanged(mDevicePosture);
+    }
+
+    /**
+     * Unregister {@link OnDevicePostureChangedListener} for device posture changes.
+     */
+    public void unregisterOnDevicePostureChangedListener(
+            @NonNull OnDevicePostureChangedListener listener) {
+        mListeners.remove(listener);
+    }
+
+    /**
+     * Listener interface for device posture change.
+     */
+    public interface OnDevicePostureChangedListener {
+        /**
+         * Callback when device posture changes.
+         * See {@link DevicePostureInt} for callback values.
+         */
+        void onDevicePostureChanged(@DevicePostureInt int posture);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 25c430c..72dc771 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -41,6 +41,7 @@
 import com.android.wm.shell.back.BackAnimationController;
 import com.android.wm.shell.bubbles.BubbleController;
 import com.android.wm.shell.bubbles.Bubbles;
+import com.android.wm.shell.common.DevicePostureController;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayImeController;
 import com.android.wm.shell.common.DisplayInsetsController;
@@ -160,6 +161,16 @@
 
     @WMSingleton
     @Provides
+    static DevicePostureController provideDevicePostureController(
+            Context context,
+            ShellInit shellInit,
+            @ShellMainThread ShellExecutor mainExecutor
+    ) {
+        return new DevicePostureController(context, shellInit, mainExecutor);
+    }
+
+    @WMSingleton
+    @Provides
     static DragAndDropController provideDragAndDropController(Context context,
             ShellInit shellInit,
             ShellController shellController,
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 efc7d1f..1239cdc 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
@@ -558,16 +558,18 @@
     static FullscreenUnfoldTaskAnimator provideFullscreenUnfoldTaskAnimator(
             Context context,
             UnfoldBackgroundController unfoldBackgroundController,
+            ShellController shellController,
             DisplayInsetsController displayInsetsController
     ) {
         return new FullscreenUnfoldTaskAnimator(context, unfoldBackgroundController,
-                displayInsetsController);
+                shellController, displayInsetsController);
     }
 
     @Provides
     static SplitTaskUnfoldAnimator provideSplitTaskUnfoldAnimatorBase(
             Context context,
             UnfoldBackgroundController backgroundController,
+            ShellController shellController,
             @ShellMainThread ShellExecutor executor,
             Lazy<Optional<SplitScreenController>> splitScreenOptional,
             DisplayInsetsController displayInsetsController
@@ -577,7 +579,7 @@
         // controller directly once we refactor ShellTaskOrganizer to not depend on the unfold
         // animation controller directly.
         return new SplitTaskUnfoldAnimator(context, executor, splitScreenOptional,
-                backgroundController, displayInsetsController);
+                shellController, backgroundController, displayInsetsController);
     }
 
     @WMSingleton
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 fce0138..73a7403 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
@@ -85,7 +85,7 @@
     fun showDesktopApps() {
         ProtoLog.v(WM_SHELL_DESKTOP_MODE, "showDesktopApps")
         val wct = WindowContainerTransaction()
-        bringDesktopAppsToFront(wct, force = true)
+        bringDesktopAppsToFront(wct)
 
         // Execute transaction if there are pending operations
         if (!wct.isEmpty) {
@@ -156,19 +156,9 @@
             ?: WINDOWING_MODE_UNDEFINED
     }
 
-    private fun bringDesktopAppsToFront(wct: WindowContainerTransaction, force: Boolean = false) {
-        val activeTasks = desktopModeTaskRepository.getActiveTasks()
-
-        // Skip if all tasks are already visible
-        if (!force && activeTasks.all(desktopModeTaskRepository::isVisibleTask)) {
-            ProtoLog.d(
-                WM_SHELL_DESKTOP_MODE,
-                "bringDesktopAppsToFront: active tasks are already in front, skipping."
-            )
-            return
-        }
-
+    private fun bringDesktopAppsToFront(wct: WindowContainerTransaction) {
         ProtoLog.v(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront")
+        val activeTasks = desktopModeTaskRepository.getActiveTasks()
 
         // First move home to front and then other tasks on top of it
         moveHomeTaskToFront(wct)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropConstants.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropConstants.java
new file mode 100644
index 0000000..20da54e
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropConstants.java
@@ -0,0 +1,27 @@
+/*
+ * 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.draganddrop;
+
+/** Constants that can be used by both Shell and other users of the library, e.g. Launcher */
+public class DragAndDropConstants {
+
+    /**
+     * An Intent extra that Launcher can use to specify a region of the screen where Shell should
+     * ignore drag events.
+     */
+    public static final String EXTRA_DISALLOW_HIT_REGION = "DISALLOW_HIT_REGION";
+}
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 b59fe18..4cfaae6 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
@@ -36,6 +36,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 
 import android.content.ClipDescription;
+import android.content.ComponentCallbacks2;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.PixelFormat;
@@ -58,9 +59,9 @@
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.annotations.ExternalMainThread;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.splitscreen.SplitScreenController;
-import com.android.wm.shell.sysui.ConfigurationChangeListener;
 import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.sysui.ShellInit;
 
@@ -70,7 +71,7 @@
  * Handles the global drag and drop handling for the Shell.
  */
 public class DragAndDropController implements DisplayController.OnDisplaysChangedListener,
-        View.OnDragListener, ConfigurationChangeListener {
+        View.OnDragListener, ComponentCallbacks2 {
 
     private static final String TAG = DragAndDropController.class.getSimpleName();
 
@@ -119,7 +120,6 @@
         mMainExecutor.executeDelayed(() -> {
             mDisplayController.addDisplayWindowListener(this);
         }, 0);
-        mShellController.addConfigurationChangeListener(this);
     }
 
     /**
@@ -180,6 +180,7 @@
         try {
             wm.addView(rootView, layoutParams);
             addDisplayDropTarget(displayId, context, wm, rootView, dragLayout);
+            context.registerComponentCallbacks(this);
         } catch (WindowManager.InvalidDisplayException e) {
             Slog.w(TAG, "Unable to add view for display id: " + displayId);
         }
@@ -209,6 +210,7 @@
         if (pd == null) {
             return;
         }
+        pd.context.unregisterComponentCallbacks(this);
         pd.wm.removeViewImmediate(pd.rootView);
         mDisplayDropTargets.remove(displayId);
     }
@@ -328,18 +330,29 @@
         return mimeTypes;
     }
 
-    @Override
-    public void onThemeChanged() {
-        for (int i = 0; i < mDisplayDropTargets.size(); i++) {
-            mDisplayDropTargets.get(i).dragLayout.onThemeChange();
-        }
-    }
-
+    // Note: Component callbacks are always called on the main thread of the process
+    @ExternalMainThread
     @Override
     public void onConfigurationChanged(Configuration newConfig) {
-        for (int i = 0; i < mDisplayDropTargets.size(); i++) {
-            mDisplayDropTargets.get(i).dragLayout.onConfigChanged(newConfig);
-        }
+        mMainExecutor.execute(() -> {
+            for (int i = 0; i < mDisplayDropTargets.size(); i++) {
+                mDisplayDropTargets.get(i).dragLayout.onConfigChanged(newConfig);
+            }
+        });
+    }
+
+    // Note: Component callbacks are always called on the main thread of the process
+    @ExternalMainThread
+    @Override
+    public void onTrimMemory(int level) {
+        // Do nothing
+    }
+
+    // Note: Component callbacks are always called on the main thread of the process
+    @ExternalMainThread
+    @Override
+    public void onLowMemory() {
+        // Do nothing
     }
 
     private static class PerDisplay {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
index d93a901..df94b41 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
@@ -34,6 +34,7 @@
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
+import static com.android.wm.shell.draganddrop.DragAndDropConstants.EXTRA_DISALLOW_HIT_REGION;
 import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_FULLSCREEN;
 import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM;
 import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_LEFT;
@@ -53,6 +54,7 @@
 import android.content.pm.LauncherApps;
 import android.graphics.Insets;
 import android.graphics.Rect;
+import android.graphics.RectF;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -86,6 +88,7 @@
     private final Starter mStarter;
     private final SplitScreenController mSplitScreen;
     private final ArrayList<DragAndDropPolicy.Target> mTargets = new ArrayList<>();
+    private final RectF mDisallowHitRegion = new RectF();
 
     private InstanceId mLoggerSessionId;
     private DragSession mSession;
@@ -111,6 +114,12 @@
         mSession = new DragSession(mActivityTaskManager, displayLayout, data);
         // TODO(b/169894807): Also update the session data with task stack changes
         mSession.update();
+        RectF disallowHitRegion = (RectF) mSession.dragData.getExtra(EXTRA_DISALLOW_HIT_REGION);
+        if (disallowHitRegion == null) {
+            mDisallowHitRegion.setEmpty();
+        } else {
+            mDisallowHitRegion.set(disallowHitRegion);
+        }
     }
 
     /**
@@ -218,6 +227,9 @@
      */
     @Nullable
     Target getTargetAtLocation(int x, int y) {
+        if (mDisallowHitRegion.contains(x, y)) {
+            return null;
+        }
         for (int i = mTargets.size() - 1; i >= 0; i--) {
             DragAndDropPolicy.Target t = mTargets.get(i);
             if (t.hitRegion.contains(x, y)) {
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 3ade1ed..fe42822a 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
@@ -18,6 +18,8 @@
 
 import static android.app.StatusBarManager.DISABLE_NONE;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.content.pm.ActivityInfo.CONFIG_ASSETS_PATHS;
+import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
@@ -72,6 +74,7 @@
     private final SplitScreenController mSplitScreenController;
     private final IconProvider mIconProvider;
     private final StatusBarManager mStatusBarManager;
+    private final Configuration mLastConfiguration = new Configuration();
 
     private DragAndDropPolicy.Target mCurrentTarget = null;
     private DropZoneView mDropZoneView1;
@@ -92,6 +95,7 @@
         mIconProvider = iconProvider;
         mPolicy = new DragAndDropPolicy(context, splitScreenController);
         mStatusBarManager = context.getSystemService(StatusBarManager.class);
+        mLastConfiguration.setTo(context.getResources().getConfiguration());
 
         mDisplayMargin = context.getResources().getDimensionPixelSize(
                 R.dimen.drop_layout_display_margin);
@@ -118,7 +122,7 @@
 
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        mInsets = insets.getInsets(Type.systemBars() | Type.displayCutout());
+        mInsets = insets.getInsets(Type.tappableElement() | Type.displayCutout());
         recomputeDropTargets();
 
         final int orientation = getResources().getConfiguration().orientation;
@@ -132,11 +136,6 @@
         return super.onApplyWindowInsets(insets);
     }
 
-    public void onThemeChange() {
-        mDropZoneView1.onThemeChange();
-        mDropZoneView2.onThemeChange();
-    }
-
     public void onConfigChanged(Configuration newConfig) {
         if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE
                 && getOrientation() != HORIZONTAL) {
@@ -147,6 +146,15 @@
             setOrientation(LinearLayout.VERTICAL);
             updateContainerMargins(newConfig.orientation);
         }
+
+        final int diff = newConfig.diff(mLastConfiguration);
+        final boolean themeChanged = (diff & CONFIG_ASSETS_PATHS) != 0
+                || (diff & CONFIG_UI_MODE) != 0;
+        if (themeChanged) {
+            mDropZoneView1.onThemeChange();
+            mDropZoneView2.onThemeChange();
+        }
+        mLastConfiguration.setTo(newConfig);
     }
 
     private void updateContainerMarginsForSingleTask() {
@@ -369,7 +377,9 @@
 
         // Start animating the drop UI out with the drag surface
         hide(event, dropCompleteCallback);
-        hideDragSurface(dragSurface);
+        if (handledDrop) {
+            hideDragSurface(dragSurface);
+        }
         return handledDrop;
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
index 26f47fc..d094c22 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
@@ -108,6 +108,10 @@
         }
         if (!createdWindowDecor) {
             mSyncQueue.runInSync(t -> {
+                if (!leash.isValid()) {
+                    // Task vanished before sync completion
+                    return;
+                }
                 // Reset several properties back to fullscreen (PiP, for example, leaves all these
                 // properties in a bad state).
                 t.setWindowCrop(leash, null);
@@ -136,6 +140,10 @@
         final Point positionInParent = state.mTaskInfo.positionInParent;
         if (!oldPositionInParent.equals(state.mTaskInfo.positionInParent)) {
             mSyncQueue.runInSync(t -> {
+                if (!state.mLeash.isValid()) {
+                    // Task vanished before sync completion
+                    return;
+                }
                 t.setPosition(state.mLeash, positionInParent.x, positionInParent.y);
             });
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index d9ac76e..23f73f6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -209,7 +209,7 @@
     /**
      * Quietly cancel the animator by removing the listeners first.
      */
-    static void quietCancel(@NonNull ValueAnimator animator) {
+    public static void quietCancel(@NonNull ValueAnimator animator) {
         animator.removeAllUpdateListeners();
         animator.removeAllListeners();
         animator.cancel();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index ec34f73..fa3efeb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -715,6 +715,12 @@
 
     private void onDisplayChanged(DisplayLayout layout, boolean saveRestoreSnapFraction) {
         if (!mPipBoundsState.getDisplayLayout().isSameGeometry(layout)) {
+            PipAnimationController.PipTransitionAnimator animator =
+                    mPipAnimationController.getCurrentAnimator();
+            if (animator != null && animator.isRunning()) {
+                // cancel any running animator, as it is using stale display layout information
+                PipAnimationController.quietCancel(animator);
+            }
             onDisplayChangedUncheck(layout, saveRestoreSnapFraction);
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java
index 7619646..9729a40 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java
@@ -235,21 +235,14 @@
 
     /** Adds the magnetic target view to the WindowManager so it's ready to be animated in. */
     public void createOrUpdateDismissTarget() {
-        if (!mTargetViewContainer.isAttachedToWindow()) {
+        if (mTargetViewContainer.getParent() == null) {
             mTargetViewContainer.cancelAnimators();
 
             mTargetViewContainer.setVisibility(View.INVISIBLE);
             mTargetViewContainer.getViewTreeObserver().removeOnPreDrawListener(this);
             mHasDismissTargetSurface = false;
 
-            try {
-                mWindowManager.addView(mTargetViewContainer, getDismissTargetLayoutParams());
-            } catch (IllegalStateException e) {
-                // This shouldn't happen, but if the target is already added, just update its layout
-                // params.
-                mWindowManager.updateViewLayout(
-                        mTargetViewContainer, getDismissTargetLayoutParams());
-            }
+            mWindowManager.addView(mTargetViewContainer, getDismissTargetLayoutParams());
         } else {
             mWindowManager.updateViewLayout(mTargetViewContainer, getDismissTargetLayoutParams());
         }
@@ -306,7 +299,7 @@
      * Removes the dismiss target and cancels any pending callbacks to show it.
      */
     public void cleanUpDismissTarget() {
-        if (mTargetViewContainer.isAttachedToWindow()) {
+        if (mTargetViewContainer.getParent() != null) {
             mWindowManager.removeViewImmediate(mTargetViewContainer);
         }
     }
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 0c3eaf0..f102f8e 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
@@ -499,6 +499,11 @@
                             break;
                         }
                     }
+                } else if (mSideStage.getChildCount() != 0) {
+                    // There are chances the entering app transition got canceled by performing
+                    // rotation transition. Checks if there is any child task existed in split
+                    // screen before fallback to cancel entering flow.
+                    openingToSide = true;
                 }
 
                 if (isEnteringSplit && !openingToSide) {
@@ -515,7 +520,7 @@
                     }
                 }
 
-                if (!isEnteringSplit && openingToSide) {
+                if (!isEnteringSplit && apps != null) {
                     final WindowContainerTransaction evictWct = new WindowContainerTransaction();
                     prepareEvictNonOpeningChildTasks(position, apps, evictWct);
                     mSyncQueue.queue(evictWct);
@@ -598,6 +603,11 @@
                             break;
                         }
                     }
+                } else if (mSideStage.getChildCount() != 0) {
+                    // There are chances the entering app transition got canceled by performing
+                    // rotation transition. Checks if there is any child task existed in split
+                    // screen before fallback to cancel entering flow.
+                    openingToSide = true;
                 }
 
                 if (isEnteringSplit && !openingToSide && apps != null) {
@@ -624,7 +634,7 @@
                 }
 
 
-                if (!isEnteringSplit && openingToSide) {
+                if (!isEnteringSplit && apps != null) {
                     final WindowContainerTransaction evictWct = new WindowContainerTransaction();
                     prepareEvictNonOpeningChildTasks(position, apps, evictWct);
                     mSyncQueue.queue(evictWct);
@@ -926,7 +936,7 @@
                         new IRemoteAnimationFinishedCallback.Stub() {
                             @Override
                             public void onAnimationFinished() throws RemoteException {
-                                onRemoteAnimationFinishedOrCancelled(false /* cancel */, evictWct);
+                                onRemoteAnimationFinishedOrCancelled(evictWct);
                                 finishedCallback.onAnimationFinished();
                             }
                         };
@@ -942,7 +952,7 @@
 
             @Override
             public void onAnimationCancelled(boolean isKeyguardOccluded) {
-                onRemoteAnimationFinishedOrCancelled(true /* cancel */, evictWct);
+                onRemoteAnimationFinishedOrCancelled(evictWct);
                 try {
                     adapter.getRunner().onAnimationCancelled(isKeyguardOccluded);
                 } catch (RemoteException e) {
@@ -963,15 +973,14 @@
         }
     }
 
-    private void onRemoteAnimationFinishedOrCancelled(boolean cancel,
-            WindowContainerTransaction evictWct) {
+    private void onRemoteAnimationFinishedOrCancelled(WindowContainerTransaction evictWct) {
         mIsSplitEntering = false;
         mShouldUpdateRecents = true;
         mSplitRequest = null;
         // If any stage has no child after animation finished, it means that split will display
         // nothing, such status will happen if task and intent is same app but not support
         // multi-instance, we should exit split and expand that app as full screen.
-        if (!cancel && (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0)) {
+        if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) {
             mMainExecutor.execute(() ->
                     exitSplitScreen(mMainStage.getChildCount() == 0
                             ? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
@@ -1226,8 +1235,8 @@
             // Notify recents if we are exiting in a way that breaks the pair, and disable further
             // updates to splits in the recents until we enter split again
             if (shouldBreakPairedTaskInRecents(exitReason) && mShouldUpdateRecents) {
-                recentTasks.removeSplitPair(mMainStage.getLastVisibleTaskId());
-                recentTasks.removeSplitPair(mSideStage.getLastVisibleTaskId());
+                recentTasks.removeSplitPair(mMainStage.getTopVisibleChildTaskId());
+                recentTasks.removeSplitPair(mSideStage.getTopVisibleChildTaskId());
             }
         });
         mShouldUpdateRecents = false;
@@ -1685,9 +1694,7 @@
         }
 
         mSyncQueue.queue(wct);
-        mSyncQueue.runInSync(t -> {
-            setDividerVisibility(mainStageVisible, t);
-        });
+        setDividerVisibility(mainStageVisible, null);
     }
 
     private void setDividerVisibility(boolean visible, @Nullable SurfaceControl.Transaction t) {
@@ -1769,6 +1776,10 @@
 
                 @Override
                 public void onAnimationEnd(Animator animation) {
+                    if (dividerLeash != null && dividerLeash.isValid()) {
+                        transaction.setAlpha(dividerLeash, 1);
+                        transaction.apply();
+                    }
                     mTransactionPool.release(transaction);
                     mDividerFadeInAnimator = null;
                 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index 0359761..a841b7f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -92,7 +92,6 @@
     protected SurfaceControl mDimLayer;
     protected SparseArray<ActivityManager.RunningTaskInfo> mChildrenTaskInfo = new SparseArray<>();
     private final SparseArray<SurfaceControl> mChildrenLeashes = new SparseArray<>();
-    private int mLastVisibleTaskId = INVALID_TASK_ID;
     // TODO(b/204308910): Extracts SplitDecorManager related code to common package.
     private SplitDecorManager mSplitDecorManager;
 
@@ -124,13 +123,6 @@
     }
 
     /**
-     * Returns the last visible task's id.
-     */
-    int getLastVisibleTaskId() {
-        return mLastVisibleTaskId;
-    }
-
-    /**
      * Returns the top visible child task's id.
      */
     int getTopVisibleChildTaskId() {
@@ -229,9 +221,6 @@
                 return;
             }
             mChildrenTaskInfo.put(taskInfo.taskId, taskInfo);
-            if (taskInfo.isVisible && taskInfo.taskId != mLastVisibleTaskId) {
-                mLastVisibleTaskId = taskInfo.taskId;
-            }
             mCallbacks.onChildTaskStatusChanged(taskInfo.taskId, true /* present */,
                     taskInfo.isVisible);
             if (!ENABLE_SHELL_TRANSITIONS) {
@@ -264,9 +253,6 @@
         } else if (mChildrenTaskInfo.contains(taskId)) {
             mChildrenTaskInfo.remove(taskId);
             mChildrenLeashes.remove(taskId);
-            if (taskId == mLastVisibleTaskId) {
-                mLastVisibleTaskId = INVALID_TASK_ID;
-            }
             mCallbacks.onChildTaskStatusChanged(taskId, false /* present */, taskInfo.isVisible);
             if (ENABLE_SHELL_TRANSITIONS) {
                 // Status is managed/synchronized by the transition lifecycle.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java
index eab82f0..e0f3fcd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java
@@ -26,8 +26,10 @@
 import android.annotation.NonNull;
 import android.app.TaskInfo;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.graphics.Matrix;
 import android.graphics.Rect;
+import android.os.Trace;
 import android.util.SparseArray;
 import android.view.InsetsSource;
 import android.view.InsetsState;
@@ -36,6 +38,8 @@
 
 import com.android.internal.policy.ScreenDecorationsUtils;
 import com.android.wm.shell.common.DisplayInsetsController;
+import com.android.wm.shell.sysui.ConfigurationChangeListener;
+import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.unfold.UnfoldAnimationController;
 import com.android.wm.shell.unfold.UnfoldBackgroundController;
 
@@ -51,7 +55,7 @@
  * instances of FullscreenUnfoldTaskAnimator.
  */
 public class FullscreenUnfoldTaskAnimator implements UnfoldTaskAnimator,
-        DisplayInsetsController.OnInsetsChangedListener {
+        DisplayInsetsController.OnInsetsChangedListener, ConfigurationChangeListener {
 
     private static final float[] FLOAT_9 = new float[9];
     private static final TypeEvaluator<Rect> RECT_EVALUATOR = new RectEvaluator(new Rect());
@@ -63,17 +67,21 @@
 
     private final SparseArray<AnimationContext> mAnimationContextByTaskId = new SparseArray<>();
     private final int mExpandedTaskBarHeight;
-    private final float mWindowCornerRadiusPx;
     private final DisplayInsetsController mDisplayInsetsController;
     private final UnfoldBackgroundController mBackgroundController;
+    private final Context mContext;
+    private final ShellController mShellController;
 
     private InsetsSource mTaskbarInsetsSource;
+    private float mWindowCornerRadiusPx;
 
     public FullscreenUnfoldTaskAnimator(Context context,
             @NonNull UnfoldBackgroundController backgroundController,
-            DisplayInsetsController displayInsetsController) {
+            ShellController shellController, DisplayInsetsController displayInsetsController) {
+        mContext = context;
         mDisplayInsetsController = displayInsetsController;
         mBackgroundController = backgroundController;
+        mShellController = shellController;
         mExpandedTaskBarHeight = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.taskbar_frame_height);
         mWindowCornerRadiusPx = ScreenDecorationsUtils.getWindowCornerRadius(context);
@@ -81,6 +89,14 @@
 
     public void init() {
         mDisplayInsetsController.addInsetsChangedListener(DEFAULT_DISPLAY, this);
+        mShellController.addConfigurationChangeListener(this);
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfiguration) {
+        Trace.beginSection("FullscreenUnfoldTaskAnimator#onConfigurationChanged");
+        mWindowCornerRadiusPx = ScreenDecorationsUtils.getWindowCornerRadius(mContext);
+        Trace.endSection();
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java
index 6e10ebe..addd0a6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java
@@ -28,8 +28,10 @@
 import android.animation.TypeEvaluator;
 import android.app.TaskInfo;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.graphics.Insets;
 import android.graphics.Rect;
+import android.os.Trace;
 import android.util.SparseArray;
 import android.view.InsetsSource;
 import android.view.InsetsState;
@@ -42,6 +44,8 @@
 import com.android.wm.shell.splitscreen.SplitScreen;
 import com.android.wm.shell.splitscreen.SplitScreen.SplitScreenListener;
 import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.sysui.ConfigurationChangeListener;
+import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.unfold.UnfoldAnimationController;
 import com.android.wm.shell.unfold.UnfoldBackgroundController;
 
@@ -62,16 +66,18 @@
  * They use independent instances of SplitTaskUnfoldAnimator.
  */
 public class SplitTaskUnfoldAnimator implements UnfoldTaskAnimator,
-        DisplayInsetsController.OnInsetsChangedListener, SplitScreenListener {
+        DisplayInsetsController.OnInsetsChangedListener, SplitScreenListener,
+        ConfigurationChangeListener {
 
     private static final TypeEvaluator<Rect> RECT_EVALUATOR = new RectEvaluator(new Rect());
     private static final float CROPPING_START_MARGIN_FRACTION = 0.05f;
 
+    private final Context mContext;
     private final Executor mExecutor;
     private final DisplayInsetsController mDisplayInsetsController;
     private final SparseArray<AnimationContext> mAnimationContextByTaskId = new SparseArray<>();
     private final int mExpandedTaskBarHeight;
-    private final float mWindowCornerRadiusPx;
+    private final ShellController mShellController;
     private final Lazy<Optional<SplitScreenController>> mSplitScreenController;
     private final UnfoldBackgroundController mUnfoldBackgroundController;
 
@@ -79,6 +85,7 @@
     private final Rect mSideStageBounds = new Rect();
     private final Rect mRootStageBounds = new Rect();
 
+    private float mWindowCornerRadiusPx;
     private InsetsSource mTaskbarInsetsSource;
 
     @SplitPosition
@@ -88,10 +95,12 @@
 
     public SplitTaskUnfoldAnimator(Context context, Executor executor,
             Lazy<Optional<SplitScreenController>> splitScreenController,
-            UnfoldBackgroundController unfoldBackgroundController,
+            ShellController shellController, UnfoldBackgroundController unfoldBackgroundController,
             DisplayInsetsController displayInsetsController) {
         mDisplayInsetsController = displayInsetsController;
         mExecutor = executor;
+        mContext = context;
+        mShellController = shellController;
         mUnfoldBackgroundController = unfoldBackgroundController;
         mSplitScreenController = splitScreenController;
         mExpandedTaskBarHeight = context.getResources().getDimensionPixelSize(
@@ -103,6 +112,14 @@
     @Override
     public void init() {
         mDisplayInsetsController.addInsetsChangedListener(DEFAULT_DISPLAY, this);
+        mShellController.addConfigurationChangeListener(this);
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfiguration) {
+        Trace.beginSection("SplitTaskUnfoldAnimator#onConfigurationChanged");
+        mWindowCornerRadiusPx = ScreenDecorationsUtils.getWindowCornerRadius(mContext);
+        Trace.endSection();
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index 2981f5e..9224b3c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -174,7 +174,7 @@
         mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);
 
         final TaskPositioner taskPositioner =
-                new TaskPositioner(mTaskOrganizer, windowDecoration);
+                new TaskPositioner(mTaskOrganizer, windowDecoration, mDisplayController);
         final CaptionTouchEventListener touchEventListener =
                 new CaptionTouchEventListener(taskInfo, taskPositioner);
         windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
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 de5f2f4..8dfa18c 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
@@ -558,7 +558,8 @@
         mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);
 
         final TaskPositioner taskPositioner =
-                new TaskPositioner(mTaskOrganizer, windowDecoration, mDragStartListener);
+                new TaskPositioner(mTaskOrganizer, windowDecoration, mDisplayController,
+                        mDragStartListener);
         final DesktopModeTouchEventListener touchEventListener =
                 new DesktopModeTouchEventListener(taskInfo, taskPositioner);
         windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
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 245cc8d..0779f1d 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
@@ -213,6 +213,12 @@
         final View handle = caption.findViewById(R.id.caption_handle);
         handle.setOnTouchListener(mOnCaptionTouchListener);
         handle.setOnClickListener(mOnCaptionButtonClickListener);
+        if (DesktopModeStatus.isProto1Enabled()) {
+            final View back = caption.findViewById(R.id.back_button);
+            back.setOnClickListener(mOnCaptionButtonClickListener);
+            final View close = caption.findViewById(R.id.close_window);
+            close.setOnClickListener(mOnCaptionButtonClickListener);
+        }
         updateButtonVisibility();
     }
 
@@ -319,6 +325,14 @@
         final View handle = caption.findViewById(R.id.caption_handle);
         final Drawable handleBackground = handle.getBackground();
         handleBackground.setTintList(buttonTintColor);
+        if (DesktopModeStatus.isProto1Enabled()) {
+            final View back = caption.findViewById(R.id.back_button);
+            final Drawable backBackground = back.getBackground();
+            backBackground.setTintList(buttonTintColor);
+            final View close = caption.findViewById(R.id.close_window);
+            final Drawable closeBackground = close.getBackground();
+            closeBackground.setTintList(buttonTintColor);
+        }
     }
 
     private void closeDragResizeListener() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index 7d954ad..81c4176 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -215,6 +215,7 @@
 
     @Override
     public void close() {
+        mInputEventReceiver.dispose();
         mInputChannel.dispose();
         try {
             mWindowSession.remove(mFakeWindow);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java
index d3f9227..a3d364a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java
@@ -19,9 +19,11 @@
 import android.annotation.IntDef;
 import android.graphics.PointF;
 import android.graphics.Rect;
+import android.util.DisplayMetrics;
 import android.window.WindowContainerTransaction;
 
 import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayController;
 
 class TaskPositioner implements DragPositioningCallback {
 
@@ -35,6 +37,7 @@
     static final int CTRL_TYPE_BOTTOM = 8;
 
     private final ShellTaskOrganizer mTaskOrganizer;
+    private final DisplayController mDisplayController;
     private final WindowDecoration mWindowDecoration;
 
     private final Rect mTaskBoundsAtDragStart = new Rect();
@@ -45,14 +48,16 @@
     private int mCtrlType;
     private DragStartListener mDragStartListener;
 
-    TaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration) {
-        this(taskOrganizer, windowDecoration, dragStartListener -> {});
+    TaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration,
+            DisplayController displayController) {
+        this(taskOrganizer, windowDecoration, displayController, dragStartListener -> {});
     }
 
     TaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration,
-            DragStartListener dragStartListener) {
+            DisplayController displayController, DragStartListener dragStartListener) {
         mTaskOrganizer = taskOrganizer;
         mWindowDecoration = windowDecoration;
+        mDisplayController = displayController;
         mDragStartListener = dragStartListener;
     }
 
@@ -128,15 +133,44 @@
             mRepositionTaskBounds.offset((int) deltaX, (int) deltaY);
         }
 
+        // If width or height are negative or less than the minimum width or height, revert the
+        // respective bounds to use previous bound dimensions.
+        if (mRepositionTaskBounds.width() < getMinWidth()) {
+            mRepositionTaskBounds.right = oldRight;
+            mRepositionTaskBounds.left = oldLeft;
+        }
+        if (mRepositionTaskBounds.height() < getMinHeight()) {
+            mRepositionTaskBounds.top = oldTop;
+            mRepositionTaskBounds.bottom = oldBottom;
+        }
+        // If there are no changes to the bounds after checking new bounds against minimum width
+        // and height, do not set bounds and return false
         if (oldLeft == mRepositionTaskBounds.left && oldTop == mRepositionTaskBounds.top
                 && oldRight == mRepositionTaskBounds.right
                 && oldBottom == mRepositionTaskBounds.bottom) {
             return false;
         }
+
         wct.setBounds(mWindowDecoration.mTaskInfo.token, mRepositionTaskBounds);
         return true;
     }
 
+    private float getMinWidth() {
+        return mWindowDecoration.mTaskInfo.minWidth < 0 ? getDefaultMinSize()
+                : mWindowDecoration.mTaskInfo.minWidth;
+    }
+
+    private float getMinHeight() {
+        return mWindowDecoration.mTaskInfo.minHeight < 0 ? getDefaultMinSize()
+                : mWindowDecoration.mTaskInfo.minHeight;
+    }
+
+    private float getDefaultMinSize() {
+        float density =  mDisplayController.getDisplayLayout(mWindowDecoration.mTaskInfo.displayId)
+                .densityDpi() * DisplayMetrics.DENSITY_DEFAULT_SCALE;
+        return mWindowDecoration.mTaskInfo.defaultMinSize * density;
+    }
+
     interface DragStartListener {
         /**
          * Inform the implementing class that a drag resize has started
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DevicePostureControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DevicePostureControllerTest.java
new file mode 100644
index 0000000..f8ee300
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DevicePostureControllerTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.common;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.content.Context;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.sysui.ShellInit;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DevicePostureControllerTest {
+    @Mock
+    private Context mContext;
+
+    @Mock
+    private ShellInit mShellInit;
+
+    @Mock
+    private ShellExecutor mMainExecutor;
+
+    @Captor
+    private ArgumentCaptor<Integer> mDevicePostureCaptor;
+
+    @Mock
+    private DevicePostureController.OnDevicePostureChangedListener mOnDevicePostureChangedListener;
+
+    private DevicePostureController mDevicePostureController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mDevicePostureController = new DevicePostureController(mContext, mShellInit, mMainExecutor);
+    }
+
+    @Test
+    public void instantiateController_addInitCallback() {
+        verify(mShellInit, times(1)).addInitCallback(any(), eq(mDevicePostureController));
+    }
+
+    @Test
+    public void registerOnDevicePostureChangedListener_callbackCurrentPosture() {
+        mDevicePostureController.registerOnDevicePostureChangedListener(
+                mOnDevicePostureChangedListener);
+        verify(mOnDevicePostureChangedListener, times(1))
+                .onDevicePostureChanged(anyInt());
+    }
+
+    @Test
+    public void onDevicePostureChanged_differentPosture_callbackListener() {
+        mDevicePostureController.registerOnDevicePostureChangedListener(
+                mOnDevicePostureChangedListener);
+        verify(mOnDevicePostureChangedListener).onDevicePostureChanged(
+                mDevicePostureCaptor.capture());
+        clearInvocations(mOnDevicePostureChangedListener);
+
+        int differentDevicePosture = mDevicePostureCaptor.getValue() + 1;
+        mDevicePostureController.onDevicePostureChanged(differentDevicePosture);
+
+        verify(mOnDevicePostureChangedListener, times(1))
+                .onDevicePostureChanged(differentDevicePosture);
+    }
+
+    @Test
+    public void onDevicePostureChanged_samePosture_doesNotCallbackListener() {
+        mDevicePostureController.registerOnDevicePostureChangedListener(
+                mOnDevicePostureChangedListener);
+        verify(mOnDevicePostureChangedListener).onDevicePostureChanged(
+                mDevicePostureCaptor.capture());
+        clearInvocations(mOnDevicePostureChangedListener);
+
+        int sameDevicePosture = mDevicePostureCaptor.getValue();
+        mDevicePostureController.onDevicePostureChanged(sameDevicePosture);
+
+        verifyZeroInteractions(mOnDevicePostureChangedListener);
+    }
+}
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 b6dbcf2..523cb66 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
@@ -48,7 +48,6 @@
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.splitscreen.SplitScreenController;
 import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.sysui.ShellInit;
 
@@ -82,7 +81,7 @@
     @Mock
     private ShellExecutor mMainExecutor;
     @Mock
-    private SplitScreenController mSplitScreenController;
+    private WindowManager mWindowManager;
 
     private DragAndDropController mController;
 
@@ -100,11 +99,6 @@
     }
 
     @Test
-    public void instantiateController_registerConfigChangeListener() {
-        verify(mShellController, times(1)).addConfigurationChangeListener(any());
-    }
-
-    @Test
     public void testIgnoreNonDefaultDisplays() {
         final int nonDefaultDisplayId = 12345;
         final View dragLayout = mock(View.class);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/TaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/TaskPositionerTest.kt
index f185a8a..8f66f4e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/TaskPositionerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/TaskPositionerTest.kt
@@ -8,6 +8,8 @@
 import android.window.WindowContainerToken
 import android.window.WindowContainerTransaction.Change.CHANGE_DRAG_RESIZING
 import androidx.test.filters.SmallTest
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.DisplayLayout
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.windowdecor.TaskPositioner.CTRL_TYPE_RIGHT
@@ -45,6 +47,11 @@
     @Mock
     private lateinit var taskBinder: IBinder
 
+    @Mock
+    private lateinit var mockDisplayController: DisplayController
+    @Mock
+    private lateinit var mockDisplayLayout: DisplayLayout
+
     private lateinit var taskPositioner: TaskPositioner
 
     @Before
@@ -54,12 +61,21 @@
         taskPositioner = TaskPositioner(
                 mockShellTaskOrganizer,
                 mockWindowDecoration,
+                mockDisplayController,
                 mockDragStartListener
         )
+
         `when`(taskToken.asBinder()).thenReturn(taskBinder)
+        `when`(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout)
+        `when`(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI)
+
         mockWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply {
             taskId = TASK_ID
             token = taskToken
+            minWidth = MIN_WIDTH
+            minHeight = MIN_HEIGHT
+            defaultMinSize = DEFAULT_MIN
+            displayId = DISPLAY_ID
             configuration.windowConfiguration.bounds = STARTING_BOUNDS
         }
     }
@@ -209,8 +225,239 @@
         })
     }
 
+    @Test
+    fun testDragResize_resize_setBoundsDoesNotChangeHeightWhenLessThanMin() {
+        taskPositioner.onDragPositioningStart(
+                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
+                STARTING_BOUNDS.right.toFloat(),
+                STARTING_BOUNDS.top.toFloat()
+        )
+
+        // Resize to width of 95px and height of 5px with min width of 10px
+        val newX = STARTING_BOUNDS.right.toFloat() - 5
+        val newY = STARTING_BOUNDS.top.toFloat() + 95
+        taskPositioner.onDragPositioningMove(
+                newX,
+                newY
+        )
+
+        taskPositioner.onDragPositioningEnd(newX, newY)
+
+        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS)
+                                != 0) && change.configuration.windowConfiguration.bounds.top ==
+                        STARTING_BOUNDS.top &&
+                        change.configuration.windowConfiguration.bounds.bottom ==
+                        STARTING_BOUNDS.bottom
+            }
+        })
+    }
+
+    @Test
+    fun testDragResize_resize_setBoundsDoesNotChangeWidthWhenLessThanMin() {
+        taskPositioner.onDragPositioningStart(
+                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
+                STARTING_BOUNDS.right.toFloat(),
+                STARTING_BOUNDS.top.toFloat()
+        )
+
+        // Resize to height of 95px and width of 5px with min width of 10px
+        val newX = STARTING_BOUNDS.right.toFloat() - 95
+        val newY = STARTING_BOUNDS.top.toFloat() + 5
+        taskPositioner.onDragPositioningMove(
+                newX,
+                newY
+        )
+
+        taskPositioner.onDragPositioningEnd(newX, newY)
+
+        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS)
+                                != 0) && change.configuration.windowConfiguration.bounds.right ==
+                        STARTING_BOUNDS.right &&
+                        change.configuration.windowConfiguration.bounds.left ==
+                        STARTING_BOUNDS.left
+            }
+        })
+    }
+
+    @Test
+    fun testDragResize_resize_setBoundsDoesNotChangeHeightWhenNegative() {
+        taskPositioner.onDragPositioningStart(
+                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
+                STARTING_BOUNDS.right.toFloat(),
+                STARTING_BOUNDS.top.toFloat()
+        )
+
+        // Resize to height of -5px and width of 95px
+        val newX = STARTING_BOUNDS.right.toFloat() - 5
+        val newY = STARTING_BOUNDS.top.toFloat() + 105
+        taskPositioner.onDragPositioningMove(
+                newX,
+                newY
+        )
+
+        taskPositioner.onDragPositioningEnd(newX, newY)
+
+        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS)
+                                != 0) && change.configuration.windowConfiguration.bounds.top ==
+                        STARTING_BOUNDS.top &&
+                        change.configuration.windowConfiguration.bounds.bottom ==
+                        STARTING_BOUNDS.bottom
+            }
+        })
+    }
+
+    @Test
+    fun testDragResize_resize_setBoundsDoesNotChangeWidthWhenNegative() {
+        taskPositioner.onDragPositioningStart(
+                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
+                STARTING_BOUNDS.right.toFloat(),
+                STARTING_BOUNDS.top.toFloat()
+        )
+
+        // Resize to width of -5px and height of 95px
+        val newX = STARTING_BOUNDS.right.toFloat() - 105
+        val newY = STARTING_BOUNDS.top.toFloat() + 5
+        taskPositioner.onDragPositioningMove(
+                newX,
+                newY
+        )
+
+        taskPositioner.onDragPositioningEnd(newX, newY)
+
+        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS)
+                                != 0) && change.configuration.windowConfiguration.bounds.right ==
+                        STARTING_BOUNDS.right &&
+                        change.configuration.windowConfiguration.bounds.left ==
+                        STARTING_BOUNDS.left
+            }
+        })
+    }
+
+    @Test
+    fun testDragResize_resize_setBoundsRunsWhenResizeBoundsValid() {
+        taskPositioner.onDragPositioningStart(
+                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
+                STARTING_BOUNDS.right.toFloat(),
+                STARTING_BOUNDS.top.toFloat()
+        )
+
+        // Shrink to height 20px and width 20px with both min height/width equal to 10px
+        val newX = STARTING_BOUNDS.right.toFloat() - 80
+        val newY = STARTING_BOUNDS.top.toFloat() + 80
+        taskPositioner.onDragPositioningMove(
+                newX,
+                newY
+        )
+
+        taskPositioner.onDragPositioningEnd(newX, newY)
+
+        verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0)
+            }
+        })
+    }
+
+    @Test
+    fun testDragResize_resize_setBoundsDoesNotRunWithNegativeHeightAndWidth() {
+        taskPositioner.onDragPositioningStart(
+                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
+                STARTING_BOUNDS.right.toFloat(),
+                STARTING_BOUNDS.top.toFloat()
+        )
+
+        // Shrink to height 5px and width 5px with both min height/width equal to 10px
+        val newX = STARTING_BOUNDS.right.toFloat() - 95
+        val newY = STARTING_BOUNDS.top.toFloat() + 95
+        taskPositioner.onDragPositioningMove(
+                newX,
+                newY
+        )
+
+        taskPositioner.onDragPositioningEnd(newX, newY)
+
+        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0)
+            }
+        })
+    }
+
+    @Test
+    fun testDragResize_resize_useDefaultMinWhenMinWidthInvalid() {
+        mockWindowDecoration.mTaskInfo.minWidth = -1
+
+        taskPositioner.onDragPositioningStart(
+                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
+                STARTING_BOUNDS.right.toFloat(),
+                STARTING_BOUNDS.top.toFloat()
+        )
+
+        // Shrink to width and height of 3px with invalid minWidth = -1 and defaultMinSize = 5px
+        val newX = STARTING_BOUNDS.right.toFloat() - 97
+        val newY = STARTING_BOUNDS.top.toFloat() + 97
+        taskPositioner.onDragPositioningMove(
+                newX,
+                newY
+        )
+
+        taskPositioner.onDragPositioningEnd(newX, newY)
+
+        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0)
+            }
+        })
+    }
+
+    @Test
+    fun testDragResize_resize_useMinWidthWhenValid() {
+        taskPositioner.onDragPositioningStart(
+                CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, // Resize right and top
+                STARTING_BOUNDS.right.toFloat(),
+                STARTING_BOUNDS.top.toFloat()
+        )
+
+        // Shrink to width and height of 7px with valid minWidth = 10px and defaultMinSize = 5px
+        val newX = STARTING_BOUNDS.right.toFloat() - 93
+        val newY = STARTING_BOUNDS.top.toFloat() + 93
+        taskPositioner.onDragPositioningMove(
+                newX,
+                newY
+        )
+
+        taskPositioner.onDragPositioningEnd(newX, newY)
+
+        verify(mockShellTaskOrganizer, never()).applyTransaction(argThat { wct ->
+            return@argThat wct.changes.any { (token, change) ->
+                token == taskBinder &&
+                        ((change.windowSetMask and WindowConfiguration.WINDOW_CONFIG_BOUNDS) != 0)
+            }
+        })
+    }
+
     companion object {
         private const val TASK_ID = 5
+        private const val MIN_WIDTH = 10
+        private const val MIN_HEIGHT = 10
+        private const val DENSITY_DPI = 20
+        private const val DEFAULT_MIN = 40
+        private const val DISPLAY_ID = 1
         private val STARTING_BOUNDS = Rect(0, 0, 100, 100)
     }
 }
diff --git a/media/tests/MediaFrameworkTest/AndroidManifest.xml b/media/tests/MediaFrameworkTest/AndroidManifest.xml
index 33872ed..0da5de7 100644
--- a/media/tests/MediaFrameworkTest/AndroidManifest.xml
+++ b/media/tests/MediaFrameworkTest/AndroidManifest.xml
@@ -37,7 +37,6 @@
         </activity>
         <activity android:label="Camera2CtsActivity"
              android:name="Camera2SurfaceViewActivity"
-             android:screenOrientation="landscape"
              android:configChanges="keyboardHidden|orientation|screenSize">
         </activity>
     </application>
diff --git a/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java b/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java
index 2db0a8f..33fc37e 100644
--- a/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java
+++ b/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java
@@ -25,7 +25,7 @@
 import android.util.Log;
 
 import androidx.core.os.BuildCompat;
-import androidx.window.embedding.SplitController;
+import androidx.window.embedding.ActivityEmbeddingController;
 
 import com.android.settingslib.utils.BuildCompatUtils;
 
@@ -86,7 +86,7 @@
      * @param activity Activity that needs the check
      */
     public static boolean isActivityEmbedded(Activity activity) {
-        return SplitController.getInstance().isActivityEmbedded(activity);
+        return ActivityEmbeddingController.getInstance(activity).isActivityEmbedded(activity);
     }
 
     /**
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 87e61b5..d253dda 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -65,7 +65,7 @@
         "src/**/*.kt",
     ],
 
-    min_sdk_version: "29",
+    min_sdk_version: "30",
 
 }
 
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 3b90275..37ae2d4 100644
--- a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
+++ b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
@@ -55,6 +55,7 @@
 
     private int mMaxHeight = SIZE_UNSPECIFIED;
     private int mImageResId;
+    private boolean mCacheComposition = true;
     private boolean mIsAutoScale;
     private Uri mImageUri;
     private Drawable mImageDrawable;
@@ -133,6 +134,7 @@
         lp.width = screenWidth < screenHeight ? screenWidth : screenHeight;
         illustrationFrame.setLayoutParams(lp);
 
+        illustrationView.setCacheComposition(mCacheComposition);
         handleImageWithAnimation(illustrationView);
         handleImageFrameMaxHeight(backgroundView, illustrationView);
 
@@ -427,6 +429,8 @@
             TypedArray a = context.obtainStyledAttributes(attrs,
                     R.styleable.LottieAnimationView, 0 /*defStyleAttr*/, 0 /*defStyleRes*/);
             mImageResId = a.getResourceId(R.styleable.LottieAnimationView_lottie_rawRes, 0);
+            mCacheComposition = a.getBoolean(
+                    R.styleable.LottieAnimationView_lottie_cacheComposition, true);
 
             a = context.obtainStyledAttributes(attrs,
                     R.styleable.IllustrationPreference, 0 /*defStyleAttr*/, 0 /*defStyleRes*/);
diff --git a/packages/SettingsLib/res/values-af/arrays.xml b/packages/SettingsLib/res/values-af/arrays.xml
index a7e44d3..bcc2b67 100644
--- a/packages/SettingsLib/res/values-af/arrays.xml
+++ b/packages/SettingsLib/res/values-af/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Klein"</item>
+    <item msgid="1484561228522634915">"Verstek"</item>
+    <item msgid="4014311587094503943">"Groot"</item>
+    <item msgid="2904569270831156685">"Grootste"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-am/arrays.xml b/packages/SettingsLib/res/values-am/arrays.xml
index 7bef7fa..4e97d47 100644
--- a/packages/SettingsLib/res/values-am/arrays.xml
+++ b/packages/SettingsLib/res/values-am/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"ትንሽ"</item>
+    <item msgid="1484561228522634915">"ነባሪ"</item>
+    <item msgid="4014311587094503943">"ትልቅ"</item>
+    <item msgid="2904569270831156685">"በጣም ትልቅ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml
index 0720cf5..27a236b 100644
--- a/packages/SettingsLib/res/values-ar/arrays.xml
+++ b/packages/SettingsLib/res/values-ar/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"صغير"</item>
+    <item msgid="1484561228522634915">"تلقائي"</item>
+    <item msgid="4014311587094503943">"كبير"</item>
+    <item msgid="2904569270831156685">"أكبر حجمًا"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-as/arrays.xml b/packages/SettingsLib/res/values-as/arrays.xml
index cbacce8..1a35e7a 100644
--- a/packages/SettingsLib/res/values-as/arrays.xml
+++ b/packages/SettingsLib/res/values-as/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"সৰু"</item>
+    <item msgid="1484561228522634915">"ডিফ’ল্ট"</item>
+    <item msgid="4014311587094503943">"ডাঙৰ"</item>
+    <item msgid="2904569270831156685">"আটাইতকৈ ডাঙৰ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-az/arrays.xml b/packages/SettingsLib/res/values-az/arrays.xml
index d1f157a..105cc2c 100644
--- a/packages/SettingsLib/res/values-az/arrays.xml
+++ b/packages/SettingsLib/res/values-az/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Kiçik"</item>
+    <item msgid="1484561228522634915">"Defolt"</item>
+    <item msgid="4014311587094503943">"Böyük"</item>
+    <item msgid="2904569270831156685">"Ən böyük"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
index 63b08fa..0a2235a 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Malo"</item>
+    <item msgid="1484561228522634915">"Podrazumevano"</item>
+    <item msgid="4014311587094503943">"Veliko"</item>
+    <item msgid="2904569270831156685">"Najveće"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-be/arrays.xml b/packages/SettingsLib/res/values-be/arrays.xml
index f16e1c5..8dcf2b5 100644
--- a/packages/SettingsLib/res/values-be/arrays.xml
+++ b/packages/SettingsLib/res/values-be/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Дробны"</item>
+    <item msgid="1484561228522634915">"Стандартны"</item>
+    <item msgid="4014311587094503943">"Вялікі"</item>
+    <item msgid="2904569270831156685">"Найвялікшы"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-bg/arrays.xml b/packages/SettingsLib/res/values-bg/arrays.xml
index 849e694..4e22cd3 100644
--- a/packages/SettingsLib/res/values-bg/arrays.xml
+++ b/packages/SettingsLib/res/values-bg/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Малък"</item>
+    <item msgid="1484561228522634915">"По подразбиране"</item>
+    <item msgid="4014311587094503943">"Голям"</item>
+    <item msgid="2904569270831156685">"Най-голям"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-bn/arrays.xml b/packages/SettingsLib/res/values-bn/arrays.xml
index a3bc4fd..5a2333b 100644
--- a/packages/SettingsLib/res/values-bn/arrays.xml
+++ b/packages/SettingsLib/res/values-bn/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"কম"</item>
+    <item msgid="1484561228522634915">"ডিফল্ট"</item>
+    <item msgid="4014311587094503943">"বেশি"</item>
+    <item msgid="2904569270831156685">"সবচেয়ে বড়"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index 926ad84..4ef0981 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Malo"</item>
+    <item msgid="1484561228522634915">"Zadano"</item>
+    <item msgid="4014311587094503943">"Veliko"</item>
+    <item msgid="2904569270831156685">"Najveće"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index 3062e7d..d4cccbf 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Petit"</item>
+    <item msgid="1484561228522634915">"Predeterminat"</item>
+    <item msgid="4014311587094503943">"Gran"</item>
+    <item msgid="2904569270831156685">"Més gran possible"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-cs/arrays.xml b/packages/SettingsLib/res/values-cs/arrays.xml
index e1d033c..f6aae2b 100644
--- a/packages/SettingsLib/res/values-cs/arrays.xml
+++ b/packages/SettingsLib/res/values-cs/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Malé"</item>
+    <item msgid="1484561228522634915">"Výchozí"</item>
+    <item msgid="4014311587094503943">"Velké"</item>
+    <item msgid="2904569270831156685">"Největší"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml
index 48a33f6..fac21c7 100644
--- a/packages/SettingsLib/res/values-da/arrays.xml
+++ b/packages/SettingsLib/res/values-da/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Lille"</item>
+    <item msgid="1484561228522634915">"Standard"</item>
+    <item msgid="4014311587094503943">"Stor"</item>
+    <item msgid="2904569270831156685">"Størst"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-de/arrays.xml b/packages/SettingsLib/res/values-de/arrays.xml
index ca999db..ce759c8 100644
--- a/packages/SettingsLib/res/values-de/arrays.xml
+++ b/packages/SettingsLib/res/values-de/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Klein"</item>
+    <item msgid="1484561228522634915">"Normal"</item>
+    <item msgid="4014311587094503943">"Groß"</item>
+    <item msgid="2904569270831156685">"Extragroß"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-el/arrays.xml b/packages/SettingsLib/res/values-el/arrays.xml
index b95f6fc..80219e4 100644
--- a/packages/SettingsLib/res/values-el/arrays.xml
+++ b/packages/SettingsLib/res/values-el/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Μικρό"</item>
+    <item msgid="1484561228522634915">"Προεπιλογή"</item>
+    <item msgid="4014311587094503943">"Μεγάλο"</item>
+    <item msgid="2904569270831156685">"Μεγαλύτερο"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/arrays.xml b/packages/SettingsLib/res/values-en-rAU/arrays.xml
index 327e4e9..a75f05c 100644
--- a/packages/SettingsLib/res/values-en-rAU/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rAU/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Small"</item>
+    <item msgid="1484561228522634915">"Default"</item>
+    <item msgid="4014311587094503943">"Large"</item>
+    <item msgid="2904569270831156685">"Largest"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rCA/arrays.xml b/packages/SettingsLib/res/values-en-rCA/arrays.xml
index 8a57232..698245a 100644
--- a/packages/SettingsLib/res/values-en-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rCA/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Small"</item>
+    <item msgid="1484561228522634915">"Default"</item>
+    <item msgid="4014311587094503943">"Large"</item>
+    <item msgid="2904569270831156685">"Largest"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/arrays.xml b/packages/SettingsLib/res/values-en-rGB/arrays.xml
index 327e4e9..a75f05c 100644
--- a/packages/SettingsLib/res/values-en-rGB/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rGB/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Small"</item>
+    <item msgid="1484561228522634915">"Default"</item>
+    <item msgid="4014311587094503943">"Large"</item>
+    <item msgid="2904569270831156685">"Largest"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/arrays.xml b/packages/SettingsLib/res/values-en-rIN/arrays.xml
index 327e4e9..a75f05c 100644
--- a/packages/SettingsLib/res/values-en-rIN/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rIN/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Small"</item>
+    <item msgid="1484561228522634915">"Default"</item>
+    <item msgid="4014311587094503943">"Large"</item>
+    <item msgid="2904569270831156685">"Largest"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rXC/arrays.xml b/packages/SettingsLib/res/values-en-rXC/arrays.xml
index 8af0a4a..7b98795 100644
--- a/packages/SettingsLib/res/values-en-rXC/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rXC/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‎‎‎‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎‎‏‎‎‏‏‎Small‎‏‎‎‏‎"</item>
+    <item msgid="1484561228522634915">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‎‏‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎Default‎‏‎‎‏‎"</item>
+    <item msgid="4014311587094503943">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‎‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‎‎‎‎‎‎‏‎‏‎‎‎‏‎‎‎‎‎‎‏‏‏‎Large‎‏‎‎‏‎"</item>
+    <item msgid="2904569270831156685">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‎‏‏‎‏‎‎‏‎‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‎‎‏‏‎‏‏‏‎‎‏‏‎‏‎Largest‎‏‎‎‏‎"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/arrays.xml b/packages/SettingsLib/res/values-es-rUS/arrays.xml
index 3813808..96bca9d 100644
--- a/packages/SettingsLib/res/values-es-rUS/arrays.xml
+++ b/packages/SettingsLib/res/values-es-rUS/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Pequeño"</item>
+    <item msgid="1484561228522634915">"Predeterminado"</item>
+    <item msgid="4014311587094503943">"Grande"</item>
+    <item msgid="2904569270831156685">"Máxima"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index b23f883..0792f7f 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -582,7 +582,7 @@
     <string name="user_add_user_type_title" msgid="551279664052914497">"Agregar"</string>
     <string name="user_new_user_name" msgid="60979820612818840">"Usuario nuevo"</string>
     <string name="user_new_profile_name" msgid="2405500423304678841">"Perfil nuevo"</string>
-    <string name="user_info_settings_title" msgid="6351390762733279907">"Datos de usuario"</string>
+    <string name="user_info_settings_title" msgid="6351390762733279907">"Datos del usuario"</string>
     <string name="profile_info_settings_title" msgid="105699672534365099">"Datos del perfil"</string>
     <string name="user_need_lock_message" msgid="4311424336209509301">"Para poder crear un perfil restringido, debes configurar un bloqueo de pantalla que proteja tus aplicaciones y datos personales."</string>
     <string name="user_set_lock_button" msgid="1427128184982594856">"Configurar bloqueo"</string>
diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml
index 4924407..2788a3f 100644
--- a/packages/SettingsLib/res/values-es/arrays.xml
+++ b/packages/SettingsLib/res/values-es/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Pequeño"</item>
+    <item msgid="1484561228522634915">"Predeterminado"</item>
+    <item msgid="4014311587094503943">"Grande"</item>
+    <item msgid="2904569270831156685">"El más grande"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index fe97f34..753ce73 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -182,7 +182,7 @@
     <string name="unknown" msgid="3544487229740637809">"Desconocido"</string>
     <string name="running_process_item_user_label" msgid="3988506293099805796">"Usuario: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="3631650616557252926">"Se han establecido algunos valores predeterminados"</string>
-    <string name="launch_defaults_none" msgid="8049374306261262709">"No se han establecido valores predeterminados"</string>
+    <string name="launch_defaults_none" msgid="8049374306261262709">"No hay valores predeterminados"</string>
     <string name="tts_settings" msgid="8130616705989351312">"Ajustes de conversión de texto a voz"</string>
     <string name="tts_settings_title" msgid="7602210956640483039">"Salida de conversión de texto a voz"</string>
     <string name="tts_default_rate_title" msgid="3964187817364304022">"Velocidad de la voz"</string>
diff --git a/packages/SettingsLib/res/values-et/arrays.xml b/packages/SettingsLib/res/values-et/arrays.xml
index 0402ac2..9e494c9 100644
--- a/packages/SettingsLib/res/values-et/arrays.xml
+++ b/packages/SettingsLib/res/values-et/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Väike"</item>
+    <item msgid="1484561228522634915">"Vaikeseade"</item>
+    <item msgid="4014311587094503943">"Suur"</item>
+    <item msgid="2904569270831156685">"Suurim"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index d15712a..8d23aca 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Txikia"</item>
+    <item msgid="1484561228522634915">"Lehenetsia"</item>
+    <item msgid="4014311587094503943">"Handia"</item>
+    <item msgid="2904569270831156685">"Handiena"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml
index 41410cb..ca4d1c9 100644
--- a/packages/SettingsLib/res/values-fa/arrays.xml
+++ b/packages/SettingsLib/res/values-fa/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"کوچک"</item>
+    <item msgid="1484561228522634915">"پیش‌فرض"</item>
+    <item msgid="4014311587094503943">"بزرگ"</item>
+    <item msgid="2904569270831156685">"بزرگ‌ترین"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml
index 842fb8f..cd4e16a 100644
--- a/packages/SettingsLib/res/values-fi/arrays.xml
+++ b/packages/SettingsLib/res/values-fi/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Pieni"</item>
+    <item msgid="1484561228522634915">"Oletus"</item>
+    <item msgid="4014311587094503943">"Suuri"</item>
+    <item msgid="2904569270831156685">"Suurin"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/arrays.xml b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
index dfa6db3..69669dd 100644
--- a/packages/SettingsLib/res/values-fr-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Petite"</item>
+    <item msgid="1484561228522634915">"Par défaut"</item>
+    <item msgid="4014311587094503943">"Grande"</item>
+    <item msgid="2904569270831156685">"La plus grande"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml
index 92546da..4111508 100644
--- a/packages/SettingsLib/res/values-fr/arrays.xml
+++ b/packages/SettingsLib/res/values-fr/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Petit"</item>
+    <item msgid="1484561228522634915">"Par défaut"</item>
+    <item msgid="4014311587094503943">"Grand"</item>
+    <item msgid="2904569270831156685">"Très grand"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-gl/arrays.xml b/packages/SettingsLib/res/values-gl/arrays.xml
index fb8e5f2..2744a70 100644
--- a/packages/SettingsLib/res/values-gl/arrays.xml
+++ b/packages/SettingsLib/res/values-gl/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Pequeno"</item>
+    <item msgid="1484561228522634915">"Predeterminado"</item>
+    <item msgid="4014311587094503943">"Grande"</item>
+    <item msgid="2904569270831156685">"O máis grande"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-gu/arrays.xml b/packages/SettingsLib/res/values-gu/arrays.xml
index e527d81..e1cd056 100644
--- a/packages/SettingsLib/res/values-gu/arrays.xml
+++ b/packages/SettingsLib/res/values-gu/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"નાનું"</item>
+    <item msgid="1484561228522634915">"ડિફૉલ્ટ"</item>
+    <item msgid="4014311587094503943">"મોટું"</item>
+    <item msgid="2904569270831156685">"સૌથી મોટું"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml
index 9b8d83e..be92797 100644
--- a/packages/SettingsLib/res/values-hi/arrays.xml
+++ b/packages/SettingsLib/res/values-hi/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"छोटा"</item>
+    <item msgid="1484561228522634915">"डिफ़ॉल्ट"</item>
+    <item msgid="4014311587094503943">"बड़ा"</item>
+    <item msgid="2904569270831156685">"सबसे बड़ा"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-hr/arrays.xml b/packages/SettingsLib/res/values-hr/arrays.xml
index 559383a..119ec6b 100644
--- a/packages/SettingsLib/res/values-hr/arrays.xml
+++ b/packages/SettingsLib/res/values-hr/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Malo"</item>
+    <item msgid="1484561228522634915">"Zadano"</item>
+    <item msgid="4014311587094503943">"Veliko"</item>
+    <item msgid="2904569270831156685">"Najveće"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-hu/arrays.xml b/packages/SettingsLib/res/values-hu/arrays.xml
index 409d600..58b65d1 100644
--- a/packages/SettingsLib/res/values-hu/arrays.xml
+++ b/packages/SettingsLib/res/values-hu/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Kicsi"</item>
+    <item msgid="1484561228522634915">"Alapértelmezett"</item>
+    <item msgid="4014311587094503943">"Nagy"</item>
+    <item msgid="2904569270831156685">"Legnagyobb"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml
index 009875d..9fa4a10 100644
--- a/packages/SettingsLib/res/values-hy/arrays.xml
+++ b/packages/SettingsLib/res/values-hy/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Փոքր"</item>
+    <item msgid="1484561228522634915">"Կանխադրված"</item>
+    <item msgid="4014311587094503943">"Մեծ"</item>
+    <item msgid="2904569270831156685">"Շատ մեծ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index 9527417..eadba8e 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Kecil"</item>
+    <item msgid="1484561228522634915">"Default"</item>
+    <item msgid="4014311587094503943">"Besar"</item>
+    <item msgid="2904569270831156685">"Terbesar"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index abdbf06..6dc9b40 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -345,7 +345,7 @@
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Aktifkan aplikasi terminal yang menawarkan akses kerangka lokal"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Pemeriksaan HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Setel perilaku pemeriksaan HDCP"</string>
-    <string name="debug_debugging_category" msgid="535341063709248842">"Debugging"</string>
+    <string name="debug_debugging_category" msgid="535341063709248842">"Proses debug"</string>
     <string name="debug_app" msgid="8903350241392391766">"Pilih aplikasi debug"</string>
     <string name="debug_app_not_set" msgid="1934083001283807188">"Tidak ada aplikasi debug yang disetel"</string>
     <string name="debug_app_set" msgid="6599535090477753651">"Aplikasi debug: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-is/arrays.xml b/packages/SettingsLib/res/values-is/arrays.xml
index 0b5b978..dc08b1f 100644
--- a/packages/SettingsLib/res/values-is/arrays.xml
+++ b/packages/SettingsLib/res/values-is/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Lítið"</item>
+    <item msgid="1484561228522634915">"Sjálfgefið"</item>
+    <item msgid="4014311587094503943">"Stórt"</item>
+    <item msgid="2904569270831156685">"Stærst"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-it/arrays.xml b/packages/SettingsLib/res/values-it/arrays.xml
index ae1e515..e91a7bf 100644
--- a/packages/SettingsLib/res/values-it/arrays.xml
+++ b/packages/SettingsLib/res/values-it/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Piccolo"</item>
+    <item msgid="1484561228522634915">"Predefinito"</item>
+    <item msgid="4014311587094503943">"Grande"</item>
+    <item msgid="2904569270831156685">"Più grande"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-iw/arrays.xml b/packages/SettingsLib/res/values-iw/arrays.xml
index 5d72aff..c19b821 100644
--- a/packages/SettingsLib/res/values-iw/arrays.xml
+++ b/packages/SettingsLib/res/values-iw/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"קטן"</item>
+    <item msgid="1484561228522634915">"ברירת מחדל"</item>
+    <item msgid="4014311587094503943">"גדול"</item>
+    <item msgid="2904569270831156685">"הכי גדול"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index 775e31c..41ec7ab 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"小"</item>
+    <item msgid="1484561228522634915">"デフォルト"</item>
+    <item msgid="4014311587094503943">"大"</item>
+    <item msgid="2904569270831156685">"最大"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ka/arrays.xml b/packages/SettingsLib/res/values-ka/arrays.xml
index f3545b6..5406679 100644
--- a/packages/SettingsLib/res/values-ka/arrays.xml
+++ b/packages/SettingsLib/res/values-ka/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"პატარა"</item>
+    <item msgid="1484561228522634915">"ნაგულისხმევი"</item>
+    <item msgid="4014311587094503943">"დიდი"</item>
+    <item msgid="2904569270831156685">"უდიდესი"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml
index 3fd1b50..68caf96 100644
--- a/packages/SettingsLib/res/values-kk/arrays.xml
+++ b/packages/SettingsLib/res/values-kk/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Кіші"</item>
+    <item msgid="1484561228522634915">"Әдепкі"</item>
+    <item msgid="4014311587094503943">"Үлкен"</item>
+    <item msgid="2904569270831156685">"Ең үлкен"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-km/arrays.xml b/packages/SettingsLib/res/values-km/arrays.xml
index 2269df1..2f22084 100644
--- a/packages/SettingsLib/res/values-km/arrays.xml
+++ b/packages/SettingsLib/res/values-km/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"តូច"</item>
+    <item msgid="1484561228522634915">"លំនាំដើម"</item>
+    <item msgid="4014311587094503943">"ធំ"</item>
+    <item msgid="2904569270831156685">"ធំបំផុត"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-kn/arrays.xml b/packages/SettingsLib/res/values-kn/arrays.xml
index 975f60f..b4fbb39 100644
--- a/packages/SettingsLib/res/values-kn/arrays.xml
+++ b/packages/SettingsLib/res/values-kn/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"ಚಿಕ್ಕದು"</item>
+    <item msgid="1484561228522634915">"ಡೀಫಾಲ್ಟ್"</item>
+    <item msgid="4014311587094503943">"ದೊಡ್ಡದು"</item>
+    <item msgid="2904569270831156685">"ಅತಿ ದೊಡ್ಡದು"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml
index 16b840b..02b3e80 100644
--- a/packages/SettingsLib/res/values-ko/arrays.xml
+++ b/packages/SettingsLib/res/values-ko/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"작게"</item>
+    <item msgid="1484561228522634915">"기본"</item>
+    <item msgid="4014311587094503943">"크게"</item>
+    <item msgid="2904569270831156685">"가장 크게"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ky/arrays.xml b/packages/SettingsLib/res/values-ky/arrays.xml
index 700aae1..08781db 100644
--- a/packages/SettingsLib/res/values-ky/arrays.xml
+++ b/packages/SettingsLib/res/values-ky/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Кичине"</item>
+    <item msgid="1484561228522634915">"Демейки"</item>
+    <item msgid="4014311587094503943">"Чоң"</item>
+    <item msgid="2904569270831156685">"Эң чоң"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-lo/arrays.xml b/packages/SettingsLib/res/values-lo/arrays.xml
index f116e6f..4468b37 100644
--- a/packages/SettingsLib/res/values-lo/arrays.xml
+++ b/packages/SettingsLib/res/values-lo/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"ນ້ອຍ"</item>
+    <item msgid="1484561228522634915">"ຄ່າເລີ່ມຕົ້ນ"</item>
+    <item msgid="4014311587094503943">"ໃຫຍ່"</item>
+    <item msgid="2904569270831156685">"ໃຫຍ່ທີ່ສຸດ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-lt/arrays.xml b/packages/SettingsLib/res/values-lt/arrays.xml
index c0aafdc..75f97d01 100644
--- a/packages/SettingsLib/res/values-lt/arrays.xml
+++ b/packages/SettingsLib/res/values-lt/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Mažas"</item>
+    <item msgid="1484561228522634915">"Numatytasis"</item>
+    <item msgid="4014311587094503943">"Didelis"</item>
+    <item msgid="2904569270831156685">"Didžiausias"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-lv/arrays.xml b/packages/SettingsLib/res/values-lv/arrays.xml
index 0f9ee52..2758dd6 100644
--- a/packages/SettingsLib/res/values-lv/arrays.xml
+++ b/packages/SettingsLib/res/values-lv/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Mazs"</item>
+    <item msgid="1484561228522634915">"Noklusējuma"</item>
+    <item msgid="4014311587094503943">"Liels"</item>
+    <item msgid="2904569270831156685">"Vislielākais"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml
index 41427c1..3c7b350 100644
--- a/packages/SettingsLib/res/values-mk/arrays.xml
+++ b/packages/SettingsLib/res/values-mk/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Мал"</item>
+    <item msgid="1484561228522634915">"Стандарден"</item>
+    <item msgid="4014311587094503943">"Голем"</item>
+    <item msgid="2904569270831156685">"Најголем"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ml/arrays.xml b/packages/SettingsLib/res/values-ml/arrays.xml
index 98e3bd6..8659393 100644
--- a/packages/SettingsLib/res/values-ml/arrays.xml
+++ b/packages/SettingsLib/res/values-ml/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"ചെറുത്"</item>
+    <item msgid="1484561228522634915">"ഡിഫോൾട്ട്"</item>
+    <item msgid="4014311587094503943">"വലുത്"</item>
+    <item msgid="2904569270831156685">"ഏറ്റവും വലുത്"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml
index f3c10d7..e376367 100644
--- a/packages/SettingsLib/res/values-mn/arrays.xml
+++ b/packages/SettingsLib/res/values-mn/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Жижиг"</item>
+    <item msgid="1484561228522634915">"Өгөгдмөл"</item>
+    <item msgid="4014311587094503943">"Том"</item>
+    <item msgid="2904569270831156685">"Хамгийн том"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml
index c37baaa2..f3e78ce 100644
--- a/packages/SettingsLib/res/values-mr/arrays.xml
+++ b/packages/SettingsLib/res/values-mr/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"लहान"</item>
+    <item msgid="1484561228522634915">"डीफॉल्ट"</item>
+    <item msgid="4014311587094503943">"मोठा"</item>
+    <item msgid="2904569270831156685">"सर्वात मोठा"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ms/arrays.xml b/packages/SettingsLib/res/values-ms/arrays.xml
index b19f038..825ace7 100644
--- a/packages/SettingsLib/res/values-ms/arrays.xml
+++ b/packages/SettingsLib/res/values-ms/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Kecil"</item>
+    <item msgid="1484561228522634915">"Lalai"</item>
+    <item msgid="4014311587094503943">"Besar"</item>
+    <item msgid="2904569270831156685">"Terbesar"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-my/arrays.xml b/packages/SettingsLib/res/values-my/arrays.xml
index 3398c5b..fdf64e1 100644
--- a/packages/SettingsLib/res/values-my/arrays.xml
+++ b/packages/SettingsLib/res/values-my/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"သေး"</item>
+    <item msgid="1484561228522634915">"မူရင်း"</item>
+    <item msgid="4014311587094503943">"ကြီး"</item>
+    <item msgid="2904569270831156685">"အကြီးဆုံး"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-nb/arrays.xml b/packages/SettingsLib/res/values-nb/arrays.xml
index 928ebc3..a763074 100644
--- a/packages/SettingsLib/res/values-nb/arrays.xml
+++ b/packages/SettingsLib/res/values-nb/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Liten"</item>
+    <item msgid="1484561228522634915">"Standard"</item>
+    <item msgid="4014311587094503943">"Stor"</item>
+    <item msgid="2904569270831156685">"Størst"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml
index ac1f187..b079227 100644
--- a/packages/SettingsLib/res/values-ne/arrays.xml
+++ b/packages/SettingsLib/res/values-ne/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"सानो"</item>
+    <item msgid="1484561228522634915">"डिफल्ट"</item>
+    <item msgid="4014311587094503943">"ठुलो"</item>
+    <item msgid="2904569270831156685">"सबैभन्दा ठुलो"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml
index 7c90eab..2dc1075 100644
--- a/packages/SettingsLib/res/values-nl/arrays.xml
+++ b/packages/SettingsLib/res/values-nl/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Klein"</item>
+    <item msgid="1484561228522634915">"Standaard"</item>
+    <item msgid="4014311587094503943">"Groot"</item>
+    <item msgid="2904569270831156685">"Grootst"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-or/arrays.xml b/packages/SettingsLib/res/values-or/arrays.xml
index a6c40b0..b86d4f2 100644
--- a/packages/SettingsLib/res/values-or/arrays.xml
+++ b/packages/SettingsLib/res/values-or/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"ଛୋଟ"</item>
+    <item msgid="1484561228522634915">"ଡିଫଲ୍ଟ"</item>
+    <item msgid="4014311587094503943">"ବଡ଼"</item>
+    <item msgid="2904569270831156685">"ସବୁଠାରୁ ବଡ଼"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml
index 0fd5c56..4135a30 100644
--- a/packages/SettingsLib/res/values-pa/arrays.xml
+++ b/packages/SettingsLib/res/values-pa/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"ਛੋਟਾ"</item>
+    <item msgid="1484561228522634915">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ"</item>
+    <item msgid="4014311587094503943">"ਵੱਡਾ"</item>
+    <item msgid="2904569270831156685">"ਸਭ ਤੋਂ ਵੱਡਾ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml
index 71ecd46..830c732 100644
--- a/packages/SettingsLib/res/values-pl/arrays.xml
+++ b/packages/SettingsLib/res/values-pl/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Mały"</item>
+    <item msgid="1484561228522634915">"Domyślny"</item>
+    <item msgid="4014311587094503943">"Duży"</item>
+    <item msgid="2904569270831156685">"Największy"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/arrays.xml b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
index f218fab..5cbca90 100644
--- a/packages/SettingsLib/res/values-pt-rBR/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Pequeno"</item>
+    <item msgid="1484561228522634915">"Padrão"</item>
+    <item msgid="4014311587094503943">"Grande"</item>
+    <item msgid="2904569270831156685">"Maior"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/arrays.xml b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
index e323455..8b63f7f 100644
--- a/packages/SettingsLib/res/values-pt-rPT/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
@@ -50,8 +50,8 @@
   </string-array>
   <string-array name="hdcp_checking_titles">
     <item msgid="2377230797542526134">"Nunca verificar"</item>
-    <item msgid="3919638466823112484">"Verificar apenas conteúdo DRM"</item>
-    <item msgid="9048424957228926377">"Verificar sempre"</item>
+    <item msgid="3919638466823112484">"Rever apenas conteúdo DRM"</item>
+    <item msgid="9048424957228926377">"Rever sempre"</item>
   </string-array>
   <string-array name="hdcp_checking_summaries">
     <item msgid="4045840870658484038">"Nunca utilizar a verificação HDCP"</item>
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Pequeno"</item>
+    <item msgid="1484561228522634915">"Predefinição"</item>
+    <item msgid="4014311587094503943">"Grande"</item>
+    <item msgid="2904569270831156685">"O maior"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index d241f38..d9116fe 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -151,7 +151,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"A sincronização concede acesso aos seus contactos e ao histórico de chamadas quando tem uma ligação estabelecida."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Não foi possível sincronizar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Não foi possível sincronizar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g> devido a PIN ou chave de acesso incorreto."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Não foi possível sincronizar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g> devido a PIN ou token de acesso incorreto."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Não é possível comunicar com <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Emparelhamento rejeitado por <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Computador"</string>
@@ -335,8 +335,8 @@
     <string name="adb_keys_warning_message" msgid="2968555274488101220">"Revogar acesso à depuração USB de todos os computadores anteriormente autorizados?"</string>
     <string name="dev_settings_warning_title" msgid="8251234890169074553">"Permitir definições de programação?"</string>
     <string name="dev_settings_warning_message" msgid="37741686486073668">"Estas definições destinam-se apenas a programação. Podem fazer com que o seu aparelho e as aplicações nele existentes falhem ou funcionem mal."</string>
-    <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Verificar apps por USB"</string>
-    <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Verificar as aplicações instaladas via ADB/ADT para detetar comportamento perigoso"</string>
+    <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Rever apps por USB"</string>
+    <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Rever as aplicações instaladas via ADB/ADT para detetar comportamento perigoso"</string>
     <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"São apresentados os dispositivos Bluetooth sem nomes (apenas endereços MAC)"</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Desativa a funcionalidade de volume absoluto do Bluetooth caso existam problemas de volume com dispositivos remotos, como um volume insuportavelmente alto ou a ausência de controlo"</string>
     <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Ativa a pilha de funcionalidades Bluetooth Gabeldorche."</string>
@@ -349,7 +349,7 @@
     <string name="debug_app" msgid="8903350241392391766">"Selecionar a aplicação a depurar"</string>
     <string name="debug_app_not_set" msgid="1934083001283807188">"Nenhuma aplicação a depurar definida"</string>
     <string name="debug_app_set" msgid="6599535090477753651">"A depurar aplicação: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="select_application" msgid="2543228890535466325">"Selecionar aplicação"</string>
+    <string name="select_application" msgid="2543228890535466325">"Selecionar app"</string>
     <string name="no_application" msgid="9038334538870247690">"Nenhuma"</string>
     <string name="wait_for_debugger" msgid="7461199843335409809">"Aguarde pelo depurador"</string>
     <string name="wait_for_debugger_summary" msgid="6846330006113363286">"A aplicação depurada aguarda a anexação do depurador antes da execução"</string>
diff --git a/packages/SettingsLib/res/values-pt/arrays.xml b/packages/SettingsLib/res/values-pt/arrays.xml
index f218fab..5cbca90 100644
--- a/packages/SettingsLib/res/values-pt/arrays.xml
+++ b/packages/SettingsLib/res/values-pt/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Pequeno"</item>
+    <item msgid="1484561228522634915">"Padrão"</item>
+    <item msgid="4014311587094503943">"Grande"</item>
+    <item msgid="2904569270831156685">"Maior"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index faa15c2..743fae20 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Mic"</item>
+    <item msgid="1484561228522634915">"Prestabilit"</item>
+    <item msgid="4014311587094503943">"Mare"</item>
+    <item msgid="2904569270831156685">"Cel mai mare"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ru/arrays.xml b/packages/SettingsLib/res/values-ru/arrays.xml
index 4b6e692..53194f6 100644
--- a/packages/SettingsLib/res/values-ru/arrays.xml
+++ b/packages/SettingsLib/res/values-ru/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Мелкий"</item>
+    <item msgid="1484561228522634915">"По умолчанию"</item>
+    <item msgid="4014311587094503943">"Крупный"</item>
+    <item msgid="2904569270831156685">"Самый крупный"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-si/arrays.xml b/packages/SettingsLib/res/values-si/arrays.xml
index eaacfb8..62b0e4c 100644
--- a/packages/SettingsLib/res/values-si/arrays.xml
+++ b/packages/SettingsLib/res/values-si/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"කුඩා"</item>
+    <item msgid="1484561228522634915">"පෙරනිමි"</item>
+    <item msgid="4014311587094503943">"විශාල"</item>
+    <item msgid="2904569270831156685">"විශාලතම"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sk/arrays.xml b/packages/SettingsLib/res/values-sk/arrays.xml
index bbfe969..6c76469 100644
--- a/packages/SettingsLib/res/values-sk/arrays.xml
+++ b/packages/SettingsLib/res/values-sk/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Malé"</item>
+    <item msgid="1484561228522634915">"Predvolené"</item>
+    <item msgid="4014311587094503943">"Veľké"</item>
+    <item msgid="2904569270831156685">"Najväčšie"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml
index b2003e5..ea96c2f 100644
--- a/packages/SettingsLib/res/values-sl/arrays.xml
+++ b/packages/SettingsLib/res/values-sl/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Majhna"</item>
+    <item msgid="1484561228522634915">"Privzeta"</item>
+    <item msgid="4014311587094503943">"Velika"</item>
+    <item msgid="2904569270831156685">"Največja"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sq/arrays.xml b/packages/SettingsLib/res/values-sq/arrays.xml
index ed86380..e818fb5 100644
--- a/packages/SettingsLib/res/values-sq/arrays.xml
+++ b/packages/SettingsLib/res/values-sq/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"I vogël"</item>
+    <item msgid="1484561228522634915">"Parazgjedhja"</item>
+    <item msgid="4014311587094503943">"I madh"</item>
+    <item msgid="2904569270831156685">"Më i madhi"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sr/arrays.xml b/packages/SettingsLib/res/values-sr/arrays.xml
index a95e47b..b0506a1 100644
--- a/packages/SettingsLib/res/values-sr/arrays.xml
+++ b/packages/SettingsLib/res/values-sr/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Мало"</item>
+    <item msgid="1484561228522634915">"Подразумевано"</item>
+    <item msgid="4014311587094503943">"Велико"</item>
+    <item msgid="2904569270831156685">"Највеће"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sv/arrays.xml b/packages/SettingsLib/res/values-sv/arrays.xml
index c63465c..5d1fa21 100644
--- a/packages/SettingsLib/res/values-sv/arrays.xml
+++ b/packages/SettingsLib/res/values-sv/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Liten"</item>
+    <item msgid="1484561228522634915">"Standard"</item>
+    <item msgid="4014311587094503943">"Stor"</item>
+    <item msgid="2904569270831156685">"Störst"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml
index 6ed4d5a..49e3a24 100644
--- a/packages/SettingsLib/res/values-sw/arrays.xml
+++ b/packages/SettingsLib/res/values-sw/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Ndogo"</item>
+    <item msgid="1484561228522634915">"Chaguomsingi"</item>
+    <item msgid="4014311587094503943">"Kubwa"</item>
+    <item msgid="2904569270831156685">"Kubwa zaidi"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ta/arrays.xml b/packages/SettingsLib/res/values-ta/arrays.xml
index 236f899..aa80661 100644
--- a/packages/SettingsLib/res/values-ta/arrays.xml
+++ b/packages/SettingsLib/res/values-ta/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"சிறியது"</item>
+    <item msgid="1484561228522634915">"இயல்பு"</item>
+    <item msgid="4014311587094503943">"பெரியது"</item>
+    <item msgid="2904569270831156685">"மிகப் பெரியது"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index fb4cff1..0fceab5 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"చిన్నది"</item>
+    <item msgid="1484561228522634915">"ఆటోమేటిక్ సెట్టింగ్"</item>
+    <item msgid="4014311587094503943">"పెద్దది"</item>
+    <item msgid="2904569270831156685">"అతి పెద్దది"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml
index 782e95e..8c23e6b 100644
--- a/packages/SettingsLib/res/values-th/arrays.xml
+++ b/packages/SettingsLib/res/values-th/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"เล็ก"</item>
+    <item msgid="1484561228522634915">"ค่าเริ่มต้น"</item>
+    <item msgid="4014311587094503943">"ใหญ่"</item>
+    <item msgid="2904569270831156685">"ใหญ่ที่สุด"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml
index 19d3423..2b5f595 100644
--- a/packages/SettingsLib/res/values-tl/arrays.xml
+++ b/packages/SettingsLib/res/values-tl/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Maliit"</item>
+    <item msgid="1484561228522634915">"Default"</item>
+    <item msgid="4014311587094503943">"Malaki"</item>
+    <item msgid="2904569270831156685">"Pinakamalaki"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-tr/arrays.xml b/packages/SettingsLib/res/values-tr/arrays.xml
index 37891ae..8ce7fa7 100644
--- a/packages/SettingsLib/res/values-tr/arrays.xml
+++ b/packages/SettingsLib/res/values-tr/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Küçük"</item>
+    <item msgid="1484561228522634915">"Varsayılan"</item>
+    <item msgid="4014311587094503943">"Büyük"</item>
+    <item msgid="2904569270831156685">"En büyük"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml
index c32da85..9fc3536 100644
--- a/packages/SettingsLib/res/values-uk/arrays.xml
+++ b/packages/SettingsLib/res/values-uk/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Малий"</item>
+    <item msgid="1484561228522634915">"За умовчанням"</item>
+    <item msgid="4014311587094503943">"Великий"</item>
+    <item msgid="2904569270831156685">"Найбільший"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ur/arrays.xml b/packages/SettingsLib/res/values-ur/arrays.xml
index db9941e..c837c3c 100644
--- a/packages/SettingsLib/res/values-ur/arrays.xml
+++ b/packages/SettingsLib/res/values-ur/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"چھوٹا"</item>
+    <item msgid="1484561228522634915">"ڈیفالٹ"</item>
+    <item msgid="4014311587094503943">"بڑا"</item>
+    <item msgid="2904569270831156685">"سب سے بڑا"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-uz/arrays.xml b/packages/SettingsLib/res/values-uz/arrays.xml
index edbd180..27259f7 100644
--- a/packages/SettingsLib/res/values-uz/arrays.xml
+++ b/packages/SettingsLib/res/values-uz/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Kichik"</item>
+    <item msgid="1484561228522634915">"Birlamchi"</item>
+    <item msgid="4014311587094503943">"Yirik"</item>
+    <item msgid="2904569270831156685">"Eng katta"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml
index ee599d6..22065ea 100644
--- a/packages/SettingsLib/res/values-vi/arrays.xml
+++ b/packages/SettingsLib/res/values-vi/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Nhỏ"</item>
+    <item msgid="1484561228522634915">"Mặc định"</item>
+    <item msgid="4014311587094503943">"Lớn"</item>
+    <item msgid="2904569270831156685">"Lớn nhất"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
index 2a85d31..c1fcda2 100644
--- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"小"</item>
+    <item msgid="1484561228522634915">"默认"</item>
+    <item msgid="4014311587094503943">"大"</item>
+    <item msgid="2904569270831156685">"最大"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/arrays.xml b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
index a84f0e2..932011c 100644
--- a/packages/SettingsLib/res/values-zh-rHK/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"小"</item>
+    <item msgid="1484561228522634915">"預設"</item>
+    <item msgid="4014311587094503943">"大"</item>
+    <item msgid="2904569270831156685">"最大"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/arrays.xml b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
index b69fd53..e8c530d 100644
--- a/packages/SettingsLib/res/values-zh-rTW/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"小"</item>
+    <item msgid="1484561228522634915">"預設"</item>
+    <item msgid="4014311587094503943">"大"</item>
+    <item msgid="2904569270831156685">"最大"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-zu/arrays.xml b/packages/SettingsLib/res/values-zu/arrays.xml
index 0494f1c..bcc0da0 100644
--- a/packages/SettingsLib/res/values-zu/arrays.xml
+++ b/packages/SettingsLib/res/values-zu/arrays.xml
@@ -273,4 +273,10 @@
   </string-array>
   <string-array name="avatar_image_descriptions">
   </string-array>
+  <string-array name="entries_font_size">
+    <item msgid="9181293769180886675">"Esincane"</item>
+    <item msgid="1484561228522634915">"Okuzenzakalelayo"</item>
+    <item msgid="4014311587094503943">"kobukhulu"</item>
+    <item msgid="2904569270831156685">"Obukhulukazi"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
index 2614644..688fc72 100644
--- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
@@ -55,6 +55,7 @@
         public ComponentName settingsComponentName;
         public CharSequence description;
         public Drawable previewImage;
+        public boolean supportsComplications = false;
 
         @Override
         public String toString() {
@@ -175,6 +176,7 @@
             if (dreamMetadata != null) {
                 dreamInfo.settingsComponentName = dreamMetadata.settingsActivity;
                 dreamInfo.previewImage = dreamMetadata.previewImage;
+                dreamInfo.supportsComplications = dreamMetadata.showComplications;
             }
             dreamInfos.add(dreamInfo);
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java
index 6a1cee3..562d20d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java
@@ -224,6 +224,9 @@
                     mMetricsLogger.logOnConditionSelected();
                     updateAlarmWarningText(tag.condition);
                 }
+                tag.line1.setStateDescription(
+                        isChecked ? buttonView.getContext().getString(
+                                com.android.internal.R.string.selected) : null);
             }
         });
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java
index 87e97b1..abbdaa7 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java
@@ -196,6 +196,9 @@
                 if (isChecked) {
                     tag.rb.setChecked(true);
                 }
+                tag.line1.setStateDescription(
+                        isChecked ? buttonView.getContext().getString(
+                                com.android.internal.R.string.selected) : null);
             }
         });
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java
index 59d5674..6b81c1a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java
@@ -16,6 +16,8 @@
 
 package com.android.settingslib.notification;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
@@ -78,6 +80,8 @@
         mController.mForeverId =  Condition.newId(mContext).appendPath("forever").build();
         when(mContext.getString(com.android.internal.R.string.zen_mode_forever))
                 .thenReturn("testSummary");
+        when(mContext.getString(com.android.internal.R.string.selected))
+                .thenReturn("selected");
         NotificationManager.Policy alarmsEnabledPolicy = new NotificationManager.Policy(
                 NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS, 0, 0, 0);
         doReturn(alarmsEnabledPolicy).when(mNotificationManager).getNotificationPolicy();
@@ -190,4 +194,25 @@
         // alarm warning should NOT be null
         assertNotNull(mController.computeAlarmWarningText(null));
     }
+
+    @Test
+    public void testAccessibility() {
+        mController.bindConditions(null);
+        EnableZenModeDialog.ConditionTag forever = mController.getConditionTagAt(
+                ZenDurationDialog.FOREVER_CONDITION_INDEX);
+        EnableZenModeDialog.ConditionTag countdown = mController.getConditionTagAt(
+                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
+        EnableZenModeDialog.ConditionTag alwaysAsk = mController.getConditionTagAt(
+                ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX);
+
+        forever.rb.setChecked(true);
+        assertThat(forever.line1.getStateDescription().toString()).isEqualTo("selected");
+        assertThat(countdown.line1.getStateDescription()).isNull();
+        assertThat(alwaysAsk.line1.getStateDescription()).isNull();
+
+        alwaysAsk.rb.setChecked(true);
+        assertThat(forever.line1.getStateDescription()).isNull();
+        assertThat(countdown.line1.getStateDescription()).isNull();
+        assertThat(alwaysAsk.line1.getStateDescription().toString()).isEqualTo("selected");
+    }
 }
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/ZenDurationDialogTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/ZenDurationDialogTest.java
index 437c0d4..fc45e89 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/ZenDurationDialogTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/ZenDurationDialogTest.java
@@ -16,6 +16,8 @@
 
 package com.android.settingslib.notification;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
@@ -205,4 +207,27 @@
                 ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
         assertEquals(120, tag.countdownZenDuration);
     }
+
+    @Test
+    public void testAccessibility() {
+        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
+                Settings.Secure.ZEN_DURATION_FOREVER);
+        mController.setupDialog(mBuilder);
+        ZenDurationDialog.ConditionTag forever = mController.getConditionTagAt(
+                ZenDurationDialog.FOREVER_CONDITION_INDEX);
+        ZenDurationDialog.ConditionTag countdown = mController.getConditionTagAt(
+                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
+        ZenDurationDialog.ConditionTag alwaysAsk = mController.getConditionTagAt(
+                ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX);
+
+        forever.rb.setChecked(true);
+        assertThat(forever.line1.getStateDescription().toString()).isEqualTo("selected");
+        assertThat(countdown.line1.getStateDescription()).isNull();
+        assertThat(alwaysAsk.line1.getStateDescription()).isNull();
+
+        alwaysAsk.rb.setChecked(true);
+        assertThat(forever.line1.getStateDescription()).isNull();
+        assertThat(countdown.line1.getStateDescription()).isNull();
+        assertThat(alwaysAsk.line1.getStateDescription().toString()).isEqualTo("selected");
+    }
 }
\ No newline at end of file
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 2afcf71..b5eaa4b 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -131,6 +131,7 @@
         Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO,
         Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
         Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS,
+        Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD,
         Settings.Secure.VR_DISPLAY_MODE,
         Settings.Secure.NOTIFICATION_BADGING,
         Settings.Secure.NOTIFICATION_DISMISS_RTL,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 53ae926..534e31a 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -191,6 +191,8 @@
                 ANY_STRING_VALIDATOR);
         VALIDATORS.put(Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS,
                 ANY_STRING_VALIDATOR);
+        VALIDATORS.put(Secure.ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD,
+                ANY_STRING_VALIDATOR);
         VALIDATORS.put(Secure.ASSIST_GESTURE_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.ASSIST_GESTURE_SILENCE_ALERTS_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.ASSIST_GESTURE_WAKE_ENABLED, BOOLEAN_VALIDATOR);
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
index 774255b..b98b9221 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
@@ -35,8 +35,7 @@
      *
      * Note that calls to [View.setTransitionVisibility] shouldn't be blocked.
      *
-     * @param block whether we should block/postpone all calls to `setVisibility` and
-     * `setTransitionVisibility`.
+     * @param block whether we should block/postpone all calls to `setVisibility`.
      */
     fun setShouldBlockVisibilityChanges(block: Boolean)
 }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableImageView.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableImageView.kt
index a1d9d90..e42b589 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableImageView.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableImageView.kt
@@ -24,7 +24,7 @@
 import com.android.systemui.animation.LaunchableViewDelegate
 
 /** An [ImageView] that also implements [LaunchableView]. */
-class LaunchableImageView : ImageView, LaunchableView {
+open class LaunchableImageView : ImageView, LaunchableView {
     private val delegate =
         LaunchableViewDelegate(
             this,
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableTextView.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableTextView.kt
index 286996d..1476695 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableTextView.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableTextView.kt
@@ -24,7 +24,7 @@
 import com.android.systemui.animation.LaunchableViewDelegate
 
 /** A [TextView] that also implements [LaunchableView]. */
-class LaunchableTextView : TextView, LaunchableView {
+open class LaunchableTextView : TextView, LaunchableView {
     private val delegate =
         LaunchableViewDelegate(
             this,
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt
index 442c6fa..bd91c65 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt
@@ -68,7 +68,7 @@
     private fun applyConfigToShader() {
         with(rippleShader) {
             setCenter(config.centerX, config.centerY)
-            setMaxSize(config.maxWidth, config.maxHeight)
+            rippleSize.setMaxSize(config.maxWidth, config.maxHeight)
             pixelDensity = config.pixelDensity
             color = ColorUtils.setAlphaComponent(config.color, config.opacity)
             sparkleStrength = config.sparkleStrength
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt
index 61ca90a..0b842ad 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt
@@ -15,9 +15,10 @@
  */
 package com.android.systemui.surfaceeffects.ripple
 
-import android.graphics.PointF
 import android.graphics.RuntimeShader
+import android.util.Log
 import android.util.MathUtils
+import androidx.annotation.VisibleForTesting
 import com.android.systemui.animation.Interpolators
 import com.android.systemui.surfaceeffects.shaderutil.SdfShaderLibrary
 import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary
@@ -44,6 +45,8 @@
     }
     // language=AGSL
     companion object {
+        private val TAG = RippleShader::class.simpleName
+
         // Default fade in/ out values. The value range is [0,1].
         const val DEFAULT_FADE_IN_START = 0f
         const val DEFAULT_FADE_OUT_END = 1f
@@ -99,7 +102,7 @@
             vec4 main(vec2 p) {
                 float sparkleRing = soften(roundedBoxRing(p-in_center, in_size, in_cornerRadius,
                     in_thickness), in_blur);
-                float inside = soften(sdRoundedBox(p-in_center, in_size * 1.2, in_cornerRadius),
+                float inside = soften(sdRoundedBox(p-in_center, in_size * 1.25, in_cornerRadius),
                     in_blur);
                 float sparkle = sparkles(p - mod(p, in_pixelDensity * 0.8), in_time * 0.00175)
                     * (1.-sparkleRing) * in_fadeSparkle;
@@ -184,12 +187,17 @@
         setFloatUniform("in_center", x, y)
     }
 
-    /** Max width of the ripple. */
-    private var maxSize: PointF = PointF()
-    fun setMaxSize(width: Float, height: Float) {
-        maxSize.x = width
-        maxSize.y = height
-    }
+    /**
+     * Blur multipliers for the ripple.
+     *
+     * <p>It interpolates from [blurStart] to [blurEnd] based on the [progress]. Increase number to
+     * add more blur.
+     */
+    var blurStart: Float = 1.25f
+    var blurEnd: Float = 0.5f
+
+    /** Size of the ripple. */
+    val rippleSize = RippleSize()
 
     /**
      * Linear progress of the ripple. Float value between [0, 1].
@@ -209,15 +217,19 @@
     /** Progress with Standard easing curve applied. */
     private var progress: Float = 0.0f
         set(value) {
-            currentWidth = maxSize.x * value
-            currentHeight = maxSize.y * value
-            setFloatUniform("in_size", currentWidth, currentHeight)
+            field = value
 
-            setFloatUniform("in_thickness", maxSize.y * value * 0.5f)
-            // radius should not exceed width and height values.
-            setFloatUniform("in_cornerRadius", Math.min(maxSize.x, maxSize.y) * value)
+            rippleSize.update(value)
 
-            setFloatUniform("in_blur", MathUtils.lerp(1.25f, 0.5f, value))
+            setFloatUniform("in_size", rippleSize.currentWidth, rippleSize.currentHeight)
+            setFloatUniform("in_thickness", rippleSize.currentHeight * 0.5f)
+            // Corner radius is always max of the min between the current width and height.
+            setFloatUniform(
+                "in_cornerRadius",
+                Math.min(rippleSize.currentWidth, rippleSize.currentHeight)
+            )
+
+            setFloatUniform("in_blur", MathUtils.lerp(blurStart, blurEnd, value))
         }
 
     /** Play time since the start of the effect. */
@@ -264,12 +276,6 @@
             setFloatUniform("in_pixelDensity", value)
         }
 
-    var currentWidth: Float = 0f
-        private set
-
-    var currentHeight: Float = 0f
-        private set
-
     /** Parameters that are used to fade in/ out of the sparkle ring. */
     val sparkleRingFadeParams =
         FadeParams(
@@ -342,4 +348,102 @@
         /** The endpoint of the fade out, given that the animation goes from 0 to 1. */
         var fadeOutEnd: Float = DEFAULT_FADE_OUT_END,
     )
+
+    /**
+     * Desired size of the ripple at a point t in [progress].
+     *
+     * <p>Note that [progress] is curved and normalized. Below is an example usage:
+     * SizeAtProgress(t= 0f, width= 0f, height= 0f), SizeAtProgress(t= 0.2f, width= 500f, height=
+     * 700f), SizeAtProgress(t= 1f, width= 100f, height= 300f)
+     *
+     * <p>For simple ripple effects, you will want to use [setMaxSize] as it is translated into:
+     * SizeAtProgress(t= 0f, width= 0f, height= 0f), SizeAtProgress(t= 1f, width= maxWidth, height=
+     * maxHeight)
+     */
+    data class SizeAtProgress(
+        /** Time t in [0,1] progress range. */
+        var t: Float,
+        /** Target width size of the ripple at time [t]. */
+        var width: Float,
+        /** Target height size of the ripple at time [t]. */
+        var height: Float
+    )
+
+    /** Updates and stores the ripple size. */
+    inner class RippleSize {
+        @VisibleForTesting var sizes = mutableListOf<SizeAtProgress>()
+        @VisibleForTesting var currentSizeIndex = 0
+        @VisibleForTesting val initialSize = SizeAtProgress(0f, 0f, 0f)
+
+        var currentWidth: Float = 0f
+            private set
+        var currentHeight: Float = 0f
+            private set
+
+        /**
+         * Sets the max size of the ripple.
+         *
+         * <p>Use this if the ripple shape simply changes linearly.
+         */
+        fun setMaxSize(width: Float, height: Float) {
+            setSizeAtProgresses(initialSize, SizeAtProgress(1f, width, height))
+        }
+
+        /**
+         * Sets the list of [sizes].
+         *
+         * <p>Note that setting this clears the existing sizes.
+         */
+        fun setSizeAtProgresses(vararg sizes: SizeAtProgress) {
+            // Reset everything.
+            this.sizes.clear()
+            currentSizeIndex = 0
+
+            this.sizes.addAll(sizes)
+            this.sizes.sortBy { it.t }
+        }
+
+        /**
+         * Updates the current ripple size based on the progress.
+         *
+         * <p>Should be called when progress updates.
+         */
+        fun update(progress: Float) {
+            val targetIndex = updateTargetIndex(progress)
+            val prevIndex = Math.max(targetIndex - 1, 0)
+
+            val targetSize = sizes[targetIndex]
+            val prevSize = sizes[prevIndex]
+
+            val subProgress = subProgress(prevSize.t, targetSize.t, progress)
+
+            currentWidth = targetSize.width * subProgress + prevSize.width
+            currentHeight = targetSize.height * subProgress + prevSize.height
+        }
+
+        private fun updateTargetIndex(progress: Float): Int {
+            if (sizes.isEmpty()) {
+                // It could be empty on init.
+                if (progress > 0f) {
+                    Log.e(
+                        TAG,
+                        "Did you forget to set the ripple size? Use [setMaxSize] or " +
+                            "[setSizeAtProgresses] before playing the animation."
+                    )
+                }
+                // If there's no size is set, we set everything to 0 and return early.
+                setSizeAtProgresses(initialSize)
+                return currentSizeIndex
+            }
+
+            var candidate = sizes[currentSizeIndex]
+
+            while (progress > candidate.t) {
+                currentSizeIndex = Math.min(currentSizeIndex + 1, sizes.size - 1)
+                candidate = sizes[currentSizeIndex]
+            }
+
+            return currentSizeIndex
+        }
+    }
 }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt
index 3c9328c..4c7c435 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt
@@ -45,12 +45,8 @@
 
     var duration: Long = 1750
 
-    private var maxWidth: Float = 0.0f
-    private var maxHeight: Float = 0.0f
     fun setMaxSize(maxWidth: Float, maxHeight: Float) {
-        this.maxWidth = maxWidth
-        this.maxHeight = maxHeight
-        rippleShader.setMaxSize(maxWidth, maxHeight)
+        rippleShader.rippleSize.setMaxSize(maxWidth, maxHeight)
     }
 
     private var centerX: Float = 0.0f
@@ -84,6 +80,106 @@
         ripplePaint.shader = rippleShader
     }
 
+    /**
+     * Sets the fade parameters for the base ring.
+     *
+     * <p>Base ring indicates a blurred ring below the sparkle ring. See
+     * [RippleShader.baseRingFadeParams].
+     */
+    @JvmOverloads
+    fun setBaseRingFadeParams(
+        fadeInStart: Float = rippleShader.baseRingFadeParams.fadeInStart,
+        fadeInEnd: Float = rippleShader.baseRingFadeParams.fadeInEnd,
+        fadeOutStart: Float = rippleShader.baseRingFadeParams.fadeOutStart,
+        fadeOutEnd: Float = rippleShader.baseRingFadeParams.fadeOutEnd
+    ) {
+        setFadeParams(
+            rippleShader.baseRingFadeParams,
+            fadeInStart,
+            fadeInEnd,
+            fadeOutStart,
+            fadeOutEnd
+        )
+    }
+
+    /**
+     * Sets the fade parameters for the sparkle ring.
+     *
+     * <p>Sparkle ring refers to the ring that's drawn on top of the base ring. See
+     * [RippleShader.sparkleRingFadeParams].
+     */
+    @JvmOverloads
+    fun setSparkleRingFadeParams(
+        fadeInStart: Float = rippleShader.sparkleRingFadeParams.fadeInStart,
+        fadeInEnd: Float = rippleShader.sparkleRingFadeParams.fadeInEnd,
+        fadeOutStart: Float = rippleShader.sparkleRingFadeParams.fadeOutStart,
+        fadeOutEnd: Float = rippleShader.sparkleRingFadeParams.fadeOutEnd
+    ) {
+        setFadeParams(
+            rippleShader.sparkleRingFadeParams,
+            fadeInStart,
+            fadeInEnd,
+            fadeOutStart,
+            fadeOutEnd
+        )
+    }
+
+    /**
+     * Sets the fade parameters for the center fill.
+     *
+     * <p>One common use case is set all the params to 1, which completely removes the center fill.
+     * See [RippleShader.centerFillFadeParams].
+     */
+    @JvmOverloads
+    fun setCenterFillFadeParams(
+        fadeInStart: Float = rippleShader.centerFillFadeParams.fadeInStart,
+        fadeInEnd: Float = rippleShader.centerFillFadeParams.fadeInEnd,
+        fadeOutStart: Float = rippleShader.centerFillFadeParams.fadeOutStart,
+        fadeOutEnd: Float = rippleShader.centerFillFadeParams.fadeOutEnd
+    ) {
+        setFadeParams(
+            rippleShader.centerFillFadeParams,
+            fadeInStart,
+            fadeInEnd,
+            fadeOutStart,
+            fadeOutEnd
+        )
+    }
+
+    private fun setFadeParams(
+        fadeParams: RippleShader.FadeParams,
+        fadeInStart: Float,
+        fadeInEnd: Float,
+        fadeOutStart: Float,
+        fadeOutEnd: Float
+    ) {
+        with(fadeParams) {
+            this.fadeInStart = fadeInStart
+            this.fadeInEnd = fadeInEnd
+            this.fadeOutStart = fadeOutStart
+            this.fadeOutEnd = fadeOutEnd
+        }
+    }
+
+    /**
+     * Sets blur multiplier at start and end of the progress.
+     *
+     * <p>It interpolates between [start] and [end]. No need to set it if using default blur.
+     */
+    fun setBlur(start: Float, end: Float) {
+        rippleShader.blurStart = start
+        rippleShader.blurEnd = end
+    }
+
+    /**
+     * Sets the list of [RippleShader.SizeAtProgress].
+     *
+     * <p>Note that this clears the list before it sets with the new data.
+     */
+    fun setSizeAtProgresses(vararg targetSizes: RippleShader.SizeAtProgress) {
+        rippleShader.rippleSize.setSizeAtProgresses(*targetSizes)
+    }
+
     @JvmOverloads
     fun startRipple(onAnimationEnd: Runnable? = null) {
         if (animator.isRunning) {
@@ -133,13 +229,13 @@
         }
         // To reduce overdraw, we mask the effect to a circle or a rectangle that's bigger than the
         // active effect area. Values here should be kept in sync with the animation implementation
-        // in the ripple shader. (Twice bigger)
+        // in the ripple shader.
         if (rippleShape == RippleShape.CIRCLE) {
-            val maskRadius = rippleShader.currentWidth
+            val maskRadius = rippleShader.rippleSize.currentWidth
             canvas.drawCircle(centerX, centerY, maskRadius, ripplePaint)
-        } else {
-            val maskWidth = rippleShader.currentWidth * 2
-            val maskHeight = rippleShader.currentHeight * 2
+        } else if (rippleShape == RippleShape.ELLIPSE) {
+            val maskWidth = rippleShader.rippleSize.currentWidth * 2
+            val maskHeight = rippleShader.rippleSize.currentHeight * 2
             canvas.drawRect(
                 /* left= */ centerX - maskWidth,
                 /* top= */ centerY - maskHeight,
@@ -147,6 +243,10 @@
                 /* bottom= */ centerY + maskHeight,
                 ripplePaint
             )
+        } else { // RippleShape.RoundedBox
+            // No masking for the rounded box, as it has more blur which requires larger bounds.
+            // Masking creates sharp bounds even when the masking is 4 times bigger.
+            canvas.drawPaint(ripplePaint)
         }
     }
 }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/SdfShaderLibrary.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/SdfShaderLibrary.kt
index 8b2f466..7889893 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/SdfShaderLibrary.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/SdfShaderLibrary.kt
@@ -50,9 +50,9 @@
 
             float roundedBoxRing(vec2 p, vec2 size, float cornerRadius,
                 float borderThickness) {
-                float outerRoundBox = sdRoundedBox(p, size, cornerRadius);
-                float innerRoundBox = sdRoundedBox(p, size - vec2(borderThickness),
-                    cornerRadius - borderThickness);
+                float outerRoundBox = sdRoundedBox(p, size + vec2(borderThickness),
+                    cornerRadius + borderThickness);
+                float innerRoundBox = sdRoundedBox(p, size, cornerRadius);
                 return subtract(outerRoundBox, innerRoundBox);
             }
         """
@@ -69,10 +69,13 @@
 
             vec2 u = wh*p, v = wh*wh;
 
-            float U1 = u.y/2.0;  float U5 = 4.0*U1;
-            float U2 = v.y-v.x;  float U6 = 6.0*U1;
-            float U3 = u.x-U2;   float U7 = 3.0*U3;
+            float U1 = u.y/2.0;
+            float U2 = v.y-v.x;
+            float U3 = u.x-U2;
             float U4 = u.x+U2;
+            float U5 = 4.0*U1;
+            float U6 = 6.0*U1;
+            float U7 = 3.0*U3;
 
             float t = 0.5;
             for (int i = 0; i < 3; i ++) {
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/DumpableNotRegisteredDetector.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/DumpableNotRegisteredDetector.kt
new file mode 100644
index 0000000..30e2a25
--- /dev/null
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/DumpableNotRegisteredDetector.kt
@@ -0,0 +1,127 @@
+/*
+ * 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.internal.systemui.lint
+
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Context
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Location
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.intellij.psi.PsiMethod
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UClass
+
+/**
+ * Checks if any class has implemented the `Dumpable` interface but has not registered itself with
+ * the `DumpManager`.
+ */
+@Suppress("UnstableApiUsage")
+class DumpableNotRegisteredDetector : Detector(), SourceCodeScanner {
+
+    private var isDumpable: Boolean = false
+    private var isCoreStartable: Boolean = false
+    private var hasRegisterCall: Boolean = false
+    private var classLocation: Location? = null
+
+    override fun beforeCheckFile(context: Context) {
+        isDumpable = false
+        isCoreStartable = false
+        hasRegisterCall = false
+        classLocation = null
+    }
+
+    override fun applicableSuperClasses(): List<String> {
+        return listOf(DUMPABLE_CLASS_NAME)
+    }
+
+    override fun getApplicableMethodNames(): List<String> {
+        return listOf("registerDumpable", "registerNormalDumpable", "registerCriticalDumpable")
+    }
+
+    override fun visitClass(context: JavaContext, declaration: UClass) {
+        if (declaration.isInterface || context.evaluator.isAbstract(declaration)) {
+            // Don't require interfaces or abstract classes to call `register` (assume the full
+            // implementations will call it). This also means that we correctly don't warn for the
+            // `Dumpable` interface itself.
+            return
+        }
+
+        classLocation = context.getNameLocation(declaration)
+
+        val superTypeClassNames = declaration.superTypes.mapNotNull { it.resolve()?.qualifiedName }
+        isDumpable = superTypeClassNames.contains(DUMPABLE_CLASS_NAME)
+        isCoreStartable = superTypeClassNames.contains(CORE_STARTABLE_CLASS_NAME)
+    }
+
+    override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+        if (context.evaluator.isMemberInSubClassOf(method, DUMP_MANAGER_CLASS_NAME)) {
+            hasRegisterCall = true
+        }
+    }
+
+    override fun afterCheckFile(context: Context) {
+        if (!isDumpable) {
+            return
+        }
+        if (isDumpable && isCoreStartable) {
+            // CoreStartables will be automatically registered, so classes that implement
+            // CoreStartable do not need a `register` call.
+            return
+        }
+
+        if (!hasRegisterCall) {
+            context.report(
+                issue = ISSUE,
+                location = classLocation!!,
+                message =
+                    "Any class implementing `Dumpable` must call " +
+                        "`DumpManager.registerNormalDumpable` or " +
+                        "`DumpManager.registerCriticalDumpable`",
+            )
+        }
+    }
+
+    companion object {
+        @JvmField
+        val ISSUE: Issue =
+            Issue.create(
+                id = "DumpableNotRegistered",
+                briefDescription = "Dumpable not registered with DumpManager.",
+                explanation =
+                    """
+                    This class has implemented the `Dumpable` interface, but it has not registered \
+                    itself with the `DumpManager`. This means that the class will never actually \
+                    be dumped. Please call `DumpManager.registerNormalDumpable` or \
+                    `DumpManager.registerCriticalDumpable` in the class's constructor or \
+                    initialization method.""",
+                category = Category.CORRECTNESS,
+                priority = 8,
+                severity = Severity.WARNING,
+                implementation =
+                    Implementation(DumpableNotRegisteredDetector::class.java, Scope.JAVA_FILE_SCOPE)
+            )
+
+        private const val DUMPABLE_CLASS_NAME = "com.android.systemui.Dumpable"
+        private const val CORE_STARTABLE_CLASS_NAME = "com.android.systemui.CoreStartable"
+        private const val DUMP_MANAGER_CLASS_NAME = "com.android.systemui.dump.DumpManager"
+    }
+}
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
index 254a6fb..84f7050 100644
--- a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
@@ -32,6 +32,7 @@
                 BindServiceOnMainThreadDetector.ISSUE,
                 BroadcastSentViaContextDetector.ISSUE,
                 CleanArchitectureDependencyViolationDetector.ISSUE,
+                DumpableNotRegisteredDetector.ISSUE,
                 SlowUserQueryDetector.ISSUE_SLOW_USER_ID_QUERY,
                 SlowUserQueryDetector.ISSUE_SLOW_USER_INFO_QUERY,
                 NonInjectedMainThreadDetector.ISSUE,
diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DumpableNotRegisteredDetectorTest.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DumpableNotRegisteredDetectorTest.kt
new file mode 100644
index 0000000..3d6cbc7
--- /dev/null
+++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DumpableNotRegisteredDetectorTest.kt
@@ -0,0 +1,328 @@
+/*
+ * 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.internal.systemui.lint
+
+import com.android.tools.lint.checks.infrastructure.TestFiles
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+import org.junit.Test
+
+@Suppress("UnstableApiUsage")
+class DumpableNotRegisteredDetectorTest : SystemUILintDetectorTest() {
+    override fun getDetector(): Detector = DumpableNotRegisteredDetector()
+
+    override fun getIssues(): List<Issue> = listOf(DumpableNotRegisteredDetector.ISSUE)
+
+    @Test
+    fun classIsNotDumpable_noViolation() {
+        lint()
+            .files(
+                TestFiles.java(
+                    """
+                    package test.pkg;
+
+                    class SomeClass() {
+                    }
+                """.trimIndent()
+                ),
+                *stubs,
+            )
+            .issues(DumpableNotRegisteredDetector.ISSUE)
+            .run()
+            .expectClean()
+    }
+
+    @Test
+    fun classIsDumpable_andRegisterIsCalled_noViolation() {
+        lint()
+            .files(
+                TestFiles.java(
+                    """
+                    package test.pkg;
+
+                    import com.android.systemui.Dumpable;
+                    import com.android.systemui.dump.DumpManager;
+
+                    public class SomeClass implements Dumpable {
+                        SomeClass(DumpManager dumpManager) {
+                            dumpManager.registerDumpable(this);
+                        }
+
+                        @Override
+                        void dump(PrintWriter pw, String[] args) {
+                            pw.println("testDump");
+                        }
+                    }
+                """.trimIndent()
+                ),
+                *stubs,
+            )
+            .issues(DumpableNotRegisteredDetector.ISSUE)
+            .run()
+            .expectClean()
+    }
+
+    @Test
+    fun classIsDumpable_andRegisterNormalIsCalled_noViolation() {
+        lint()
+            .files(
+                TestFiles.java(
+                    """
+                    package test.pkg;
+
+                    import com.android.systemui.Dumpable;
+                    import com.android.systemui.dump.DumpManager;
+
+                    public class SomeClass implements Dumpable {
+                        SomeClass(DumpManager dumpManager) {
+                            dumpManager.registerNormalDumpable(this);
+                        }
+
+                        @Override
+                        void dump(PrintWriter pw, String[] args) {
+                            pw.println("testDump");
+                        }
+                    }
+                """.trimIndent()
+                ),
+                *stubs,
+            )
+            .issues(DumpableNotRegisteredDetector.ISSUE)
+            .run()
+            .expectClean()
+    }
+
+    @Test
+    fun classIsDumpable_andRegisterCriticalIsCalled_noViolation() {
+        lint()
+            .files(
+                TestFiles.java(
+                    """
+                    package test.pkg;
+
+                    import com.android.systemui.Dumpable;
+                    import com.android.systemui.dump.DumpManager;
+
+                    public class SomeClass implements Dumpable {
+                        SomeClass(DumpManager dumpManager) {
+                            dumpManager.registerCriticalDumpable(this);
+                        }
+
+                        @Override
+                        void dump(PrintWriter pw, String[] args) {
+                            pw.println("testDump");
+                        }
+                    }
+                """.trimIndent()
+                ),
+                *stubs,
+            )
+            .issues(DumpableNotRegisteredDetector.ISSUE)
+            .run()
+            .expectClean()
+    }
+
+    @Test
+    fun classIsDumpable_noRegister_violation() {
+        lint()
+            .files(
+                TestFiles.java(
+                        """
+                    package test.pkg;
+
+                    import com.android.systemui.Dumpable;
+
+                    public class SomeClass implements Dumpable {
+                        @Override
+                        public void dump() {
+                        }
+                    }
+                """
+                    )
+                    .indented(),
+                *stubs,
+            )
+            .issues(DumpableNotRegisteredDetector.ISSUE)
+            .run()
+            .expect(
+                ("""
+                src/test/pkg/SomeClass.java:5: Warning: Any class implementing Dumpable must call DumpManager.registerNormalDumpable or DumpManager.registerCriticalDumpable [DumpableNotRegistered]
+                public class SomeClass implements Dumpable {
+                             ~~~~~~~~~
+                0 errors, 1 warnings
+                """)
+                    .trimIndent()
+            )
+    }
+
+    @Test
+    fun classIsDumpable_usesNotDumpManagerMethod_violation() {
+        lint()
+            .files(
+                TestFiles.java(
+                        """
+                    package test.pkg;
+
+                    import com.android.systemui.Dumpable;
+                    import com.android.systemui.OtherRegistrationObject;
+
+                    public class SomeClass implements Dumpable {
+                        public SomeClass(OtherRegistrationObject otherRegistrationObject) {
+                            otherRegistrationObject.registerDumpable(this);
+                        }
+                        @Override
+                        public void dump() {
+                        }
+                    }
+                """
+                    )
+                    .indented(),
+                *stubs,
+            )
+            .issues(DumpableNotRegisteredDetector.ISSUE)
+            .run()
+            .expect(
+                ("""
+                src/test/pkg/SomeClass.java:6: Warning: Any class implementing Dumpable must call DumpManager.registerNormalDumpable or DumpManager.registerCriticalDumpable [DumpableNotRegistered]
+                public class SomeClass implements Dumpable {
+                             ~~~~~~~~~
+                0 errors, 1 warnings
+                """)
+                    .trimIndent()
+            )
+    }
+
+    @Test
+    fun classIsDumpableAndCoreStartable_noRegister_noViolation() {
+        lint()
+            .files(
+                TestFiles.java(
+                        """
+                    package test.pkg;
+
+                    import com.android.systemui.Dumpable;
+                    import com.android.systemui.CoreStartable;
+
+                    public class SomeClass implements Dumpable, CoreStartable {
+                        @Override
+                        public void start() {
+                        }
+
+                        @Override
+                        public void dump() {
+                        }
+                    }
+                """
+                    )
+                    .indented(),
+                *stubs,
+            )
+            .issues(DumpableNotRegisteredDetector.ISSUE)
+            .run()
+            .expectClean()
+    }
+
+    @Test
+    fun classIsAbstract_noRegister_noViolation() {
+        lint()
+            .files(
+                TestFiles.java(
+                        """
+                    package test.pkg;
+
+                    import com.android.systemui.Dumpable;
+
+                    public abstract class SomeClass implements Dumpable {
+                        void abstractMethodHere();
+
+                        @Override
+                        public void dump() {
+                        }
+                    }
+                """
+                    )
+                    .indented(),
+                *stubs,
+            )
+            .issues(DumpableNotRegisteredDetector.ISSUE)
+            .run()
+            .expectClean()
+    }
+
+    companion object {
+        private val DUMPABLE_STUB =
+            TestFiles.java(
+                    """
+                    package com.android.systemui;
+
+                    import com.android.systemui.dump.DumpManager;
+                    import java.io.PrintWriter;
+
+                    public interface Dumpable {
+                        void dump();
+                    }
+                """
+                )
+                .indented()
+
+        private val DUMP_MANAGER_STUB =
+            TestFiles.java(
+                    """
+                    package com.android.systemui.dump;
+
+                    public interface DumpManager {
+                        void registerDumpable(Dumpable module);
+                        void registerNormalDumpable(Dumpable module);
+                        void registerCriticalDumpable(Dumpable module);
+                    }
+                """
+                )
+                .indented()
+
+        private val OTHER_REGISTRATION_OBJECT_STUB =
+            TestFiles.java(
+                    """
+                    package com.android.systemui;
+
+                    public interface OtherRegistrationObject {
+                        void registerDumpable(Dumpable module);
+                    }
+                """
+                )
+                .indented()
+
+        private val CORE_STARTABLE_STUB =
+            TestFiles.java(
+                    """
+                    package com.android.systemui;
+
+                    public interface CoreStartable {
+                        void start();
+                    }
+                """
+                )
+                .indented()
+
+        private val stubs =
+            arrayOf(
+                DUMPABLE_STUB,
+                DUMP_MANAGER_STUB,
+                OTHER_REGISTRATION_OBJECT_STUB,
+                CORE_STARTABLE_STUB,
+            )
+    }
+}
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 ab36d58..00c0a0b 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
@@ -38,6 +38,7 @@
 
 private val TAG = ClockRegistry::class.simpleName!!
 private const val DEBUG = true
+private val KEY_TIMESTAMP = "appliedTimestamp"
 
 /** ClockRegistry aggregates providers and plugins */
 open class ClockRegistry(
@@ -134,9 +135,9 @@
         assertNotMainThread()
 
         try {
-            value?._applied_timestamp = System.currentTimeMillis()
-            val json = ClockSettings.serialize(value)
+            value?.metadata?.put(KEY_TIMESTAMP, System.currentTimeMillis())
 
+            val json = ClockSettings.serialize(value)
             if (handleAllUsers) {
                 Settings.Secure.putStringForUser(
                     context.contentResolver,
@@ -172,7 +173,7 @@
         clockChangeListeners.forEach(func)
     }
 
-    private fun mutateSetting(mutator: (ClockSettings) -> ClockSettings) {
+    public fun mutateSetting(mutator: (ClockSettings) -> ClockSettings) {
         scope.launch(bgDispatcher) { applySettings(mutator(settings ?: ClockSettings())) }
     }
 
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
index 2a40f5c..4df7a44 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
@@ -95,7 +95,7 @@
 
     open inner class DefaultClockFaceController(
         override val view: AnimatableClockView,
-        val seedColor: Int?,
+        var seedColor: Int?,
     ) : ClockFaceController {
 
         // MAGENTA is a placeholder, and will be assigned correctly in initialize
@@ -111,9 +111,9 @@
 
         init {
             if (seedColor != null) {
-                currentColor = seedColor
+                currentColor = seedColor!!
             }
-            view.setColors(currentColor, currentColor)
+            view.setColors(DOZE_COLOR, currentColor)
         }
 
         override val events =
@@ -141,7 +141,7 @@
         fun updateColor() {
             val color =
                 if (seedColor != null) {
-                    seedColor
+                    seedColor!!
                 } else if (isRegionDark) {
                     resources.getColor(android.R.color.system_accent1_100)
                 } else {
@@ -194,6 +194,14 @@
             smallClock.updateColor()
         }
 
+        override fun onSeedColorChanged(seedColor: Int?) {
+            largeClock.seedColor = seedColor
+            smallClock.seedColor = seedColor
+
+            largeClock.updateColor()
+            smallClock.updateColor()
+        }
+
         override fun onLocaleChanged(locale: Locale) {
             val nf = NumberFormat.getInstance(locale)
             if (nf.format(FORMAT_NUMBER.toLong()) == burmeseNumerals) {
diff --git a/packages/SystemUI/docs/device-entry/quickaffordance.md b/packages/SystemUI/docs/device-entry/quickaffordance.md
index 79d5718..d662649 100644
--- a/packages/SystemUI/docs/device-entry/quickaffordance.md
+++ b/packages/SystemUI/docs/device-entry/quickaffordance.md
@@ -52,6 +52,11 @@
 * Unselect an already-selected quick affordance from a slot
 * Unselect all already-selected quick affordances from a slot
 
+## Device Policy
+Returning `DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL` or
+`DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL` from
+`DevicePolicyManager#getKeyguardDisabledFeatures` will disable the keyguard quick affordance feature on the device.
+
 ## Testing
 * Add a unit test for your implementation of `KeyguardQuickAffordanceConfig`
 * Manually verify that your implementation works in multi-user environments from both the main user and a secondary user
diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
index e0cc8f4..e0d0184 100644
--- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
+++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
@@ -118,12 +118,6 @@
         void setPrimaryTextColor(int color);
 
         /**
-         * When the view is displayed on Dream, set the flag to true, immediately after the view is
-         * created.
-         */
-        void setIsDreaming(boolean isDreaming);
-
-        /**
          * Set the UI surface for the cards. Should be called immediately after the view is created.
          */
         void setUiSurface(String uiSurface);
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
index 1c2f38b..babe5700 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
@@ -112,8 +112,11 @@
     /** Call whenever the color palette should update */
     fun onColorPaletteChanged(resources: Resources) {}
 
+    /** Call if the seed color has changed and should be updated */
+    fun onSeedColorChanged(seedColor: Int?) {}
+
     /** Call whenever the weather data should update */
-    fun onWeatherDataChanged(data: Weather) {}
+    fun onWeatherDataChanged(data: WeatherData) {}
 }
 
 /** Methods which trigger various clock animations */
@@ -189,12 +192,13 @@
     val clockId: ClockId? = null,
     val seedColor: Int? = null,
 ) {
-    var _applied_timestamp: Long? = null
+    // Exclude metadata from equality checks
+    var metadata: JSONObject = JSONObject()
 
     companion object {
         private val KEY_CLOCK_ID = "clockId"
         private val KEY_SEED_COLOR = "seedColor"
-        private val KEY_TIMESTAMP = "_applied_timestamp"
+        private val KEY_METADATA = "metadata"
 
         fun serialize(setting: ClockSettings?): String {
             if (setting == null) {
@@ -204,7 +208,7 @@
             return JSONObject()
                 .put(KEY_CLOCK_ID, setting.clockId)
                 .put(KEY_SEED_COLOR, setting.seedColor)
-                .put(KEY_TIMESTAMP, setting._applied_timestamp)
+                .put(KEY_METADATA, setting.metadata)
                 .toString()
         }
 
@@ -216,11 +220,11 @@
             val json = JSONObject(jsonStr)
             val result =
                 ClockSettings(
-                    json.getString(KEY_CLOCK_ID),
+                    if (!json.isNull(KEY_CLOCK_ID)) json.getString(KEY_CLOCK_ID) else null,
                     if (!json.isNull(KEY_SEED_COLOR)) json.getInt(KEY_SEED_COLOR) else null
                 )
-            if (!json.isNull(KEY_TIMESTAMP)) {
-                result._applied_timestamp = json.getLong(KEY_TIMESTAMP)
+            if (!json.isNull(KEY_METADATA)) {
+                result.metadata = json.getJSONObject(KEY_METADATA)
             }
             return result
         }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/Weather.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/Weather.kt
deleted file mode 100644
index 302f175..0000000
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/Weather.kt
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.android.systemui.plugins
-
-import android.os.Bundle
-
-class Weather(val conditions: WeatherStateIcon, val temperature: Int, val isCelsius: Boolean) {
-    companion object {
-        private const val TAG = "Weather"
-        private const val WEATHER_STATE_ICON_KEY = "weather_state_icon_extra_key"
-        private const val TEMPERATURE_VALUE_KEY = "temperature_value_extra_key"
-        private const val TEMPERATURE_UNIT_KEY = "temperature_unit_extra_key"
-        private const val INVALID_TEMPERATURE = Int.MIN_VALUE
-
-        fun fromBundle(extras: Bundle): Weather? {
-            val icon =
-                WeatherStateIcon.fromInt(
-                    extras.getInt(WEATHER_STATE_ICON_KEY, WeatherStateIcon.UNKNOWN_ICON.id)
-                )
-            if (icon == null || icon == WeatherStateIcon.UNKNOWN_ICON) {
-                return null
-            }
-            val temperature = extras.getInt(TEMPERATURE_VALUE_KEY, INVALID_TEMPERATURE)
-            if (temperature == INVALID_TEMPERATURE) {
-                return null
-            }
-            return Weather(icon, temperature, extras.getBoolean(TEMPERATURE_UNIT_KEY))
-        }
-    }
-
-    enum class WeatherStateIcon(val id: Int) {
-        UNKNOWN_ICON(0),
-
-        // Clear, day & night.
-        SUNNY(1),
-        CLEAR_NIGHT(2),
-
-        // Mostly clear, day & night.
-        MOSTLY_SUNNY(3),
-        MOSTLY_CLEAR_NIGHT(4),
-
-        // Partly cloudy, day & night.
-        PARTLY_CLOUDY(5),
-        PARTLY_CLOUDY_NIGHT(6),
-
-        // Mostly cloudy, day & night.
-        MOSTLY_CLOUDY_DAY(7),
-        MOSTLY_CLOUDY_NIGHT(8),
-        CLOUDY(9),
-        HAZE_FOG_DUST_SMOKE(10),
-        DRIZZLE(11),
-        HEAVY_RAIN(12),
-        SHOWERS_RAIN(13),
-
-        // Scattered showers, day & night.
-        SCATTERED_SHOWERS_DAY(14),
-        SCATTERED_SHOWERS_NIGHT(15),
-
-        // Isolated scattered thunderstorms, day & night.
-        ISOLATED_SCATTERED_TSTORMS_DAY(16),
-        ISOLATED_SCATTERED_TSTORMS_NIGHT(17),
-        STRONG_TSTORMS(18),
-        BLIZZARD(19),
-        BLOWING_SNOW(20),
-        FLURRIES(21),
-        HEAVY_SNOW(22),
-
-        // Scattered snow showers, day & night.
-        SCATTERED_SNOW_SHOWERS_DAY(23),
-        SCATTERED_SNOW_SHOWERS_NIGHT(24),
-        SNOW_SHOWERS_SNOW(25),
-        MIXED_RAIN_HAIL_RAIN_SLEET(26),
-        SLEET_HAIL(27),
-        TORNADO(28),
-        TROPICAL_STORM_HURRICANE(29),
-        WINDY_BREEZY(30),
-        WINTRY_MIX_RAIN_SNOW(31);
-
-        companion object {
-            fun fromInt(value: Int) = values().firstOrNull { it.id == value }
-        }
-    }
-
-    override fun toString(): String {
-        return "$conditions $temperature${if (isCelsius) "C" else "F"}"
-    }
-}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/WeatherData.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/WeatherData.kt
new file mode 100644
index 0000000..52dfc55
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/WeatherData.kt
@@ -0,0 +1,107 @@
+package com.android.systemui.plugins
+
+import android.os.Bundle
+import androidx.annotation.VisibleForTesting
+
+class WeatherData
+private constructor(
+    val description: String,
+    val state: WeatherStateIcon,
+    val useCelsius: Boolean,
+    val temperature: Int,
+) {
+    companion object {
+        private const val TAG = "WeatherData"
+        @VisibleForTesting const val DESCRIPTION_KEY = "description"
+        @VisibleForTesting const val STATE_KEY = "state"
+        @VisibleForTesting const val USE_CELSIUS_KEY = "use_celsius"
+        @VisibleForTesting const val TEMPERATURE_KEY = "temperature"
+        private const val INVALID_WEATHER_ICON_STATE = -1
+
+        fun fromBundle(extras: Bundle): WeatherData? {
+            val description = extras.getString(DESCRIPTION_KEY)
+            val state =
+                WeatherStateIcon.fromInt(extras.getInt(STATE_KEY, INVALID_WEATHER_ICON_STATE))
+            val temperature = readIntFromBundle(extras, TEMPERATURE_KEY)
+            return if (
+                description == null ||
+                    state == null ||
+                    !extras.containsKey(USE_CELSIUS_KEY) ||
+                    temperature == null
+            )
+                null
+            else
+                WeatherData(
+                    description = description,
+                    state = state,
+                    useCelsius = extras.getBoolean(USE_CELSIUS_KEY),
+                    temperature = temperature
+                )
+        }
+
+        private fun readIntFromBundle(extras: Bundle, key: String): Int? =
+            try {
+                extras.getString(key).toInt()
+            } catch (e: Exception) {
+                null
+            }
+    }
+
+    enum class WeatherStateIcon(val id: Int) {
+        UNKNOWN_ICON(0),
+
+        // Clear, day & night.
+        SUNNY(1),
+        CLEAR_NIGHT(2),
+
+        // Mostly clear, day & night.
+        MOSTLY_SUNNY(3),
+        MOSTLY_CLEAR_NIGHT(4),
+
+        // Partly cloudy, day & night.
+        PARTLY_CLOUDY(5),
+        PARTLY_CLOUDY_NIGHT(6),
+
+        // Mostly cloudy, day & night.
+        MOSTLY_CLOUDY_DAY(7),
+        MOSTLY_CLOUDY_NIGHT(8),
+        CLOUDY(9),
+        HAZE_FOG_DUST_SMOKE(10),
+        DRIZZLE(11),
+        HEAVY_RAIN(12),
+        SHOWERS_RAIN(13),
+
+        // Scattered showers, day & night.
+        SCATTERED_SHOWERS_DAY(14),
+        SCATTERED_SHOWERS_NIGHT(15),
+
+        // Isolated scattered thunderstorms, day & night.
+        ISOLATED_SCATTERED_TSTORMS_DAY(16),
+        ISOLATED_SCATTERED_TSTORMS_NIGHT(17),
+        STRONG_TSTORMS(18),
+        BLIZZARD(19),
+        BLOWING_SNOW(20),
+        FLURRIES(21),
+        HEAVY_SNOW(22),
+
+        // Scattered snow showers, day & night.
+        SCATTERED_SNOW_SHOWERS_DAY(23),
+        SCATTERED_SNOW_SHOWERS_NIGHT(24),
+        SNOW_SHOWERS_SNOW(25),
+        MIXED_RAIN_HAIL_RAIN_SLEET(26),
+        SLEET_HAIL(27),
+        TORNADO(28),
+        TROPICAL_STORM_HURRICANE(29),
+        WINDY_BREEZY(30),
+        WINTRY_MIX_RAIN_SNOW(31);
+
+        companion object {
+            fun fromInt(value: Int) = values().firstOrNull { it.id == value }
+        }
+    }
+
+    override fun toString(): String {
+        val unit = if (useCelsius) "C" else "F"
+        return "$state (\"$description\") $temperature°$unit"
+    }
+}
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml
deleted file mode 100644
index 8497ff0..0000000
--- a/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License")
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- This is the host view that generally contains two sub views: the widget view
-    and the security view. -->
-<com.android.keyguard.KeyguardHostView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/keyguard_host_view"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:clipChildren="false"
-    android:clipToPadding="false"
-    android:paddingTop="@dimen/keyguard_lock_padding"
-    android:importantForAccessibility="yes"> <!-- Needed because TYPE_WINDOW_STATE_CHANGED is sent
-                                                  from this view when bouncer is shown -->
-
-    <com.android.keyguard.KeyguardSecurityContainer
-        android:id="@+id/keyguard_security_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:clipChildren="false"
-        android:clipToPadding="false"
-        android:padding="0dp"
-        android:fitsSystemWindows="true"
-        android:layout_gravity="center">
-        <com.android.keyguard.KeyguardSecurityViewFlipper
-            android:id="@+id/view_flipper"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:clipChildren="false"
-            android:clipToPadding="false"
-            android:paddingTop="@dimen/keyguard_security_view_top_margin"
-            android:layout_gravity="center"
-            android:gravity="center">
-        </com.android.keyguard.KeyguardSecurityViewFlipper>
-    </com.android.keyguard.KeyguardSecurityContainer>
-
-</com.android.keyguard.KeyguardHostView>
-
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml
new file mode 100644
index 0000000..426cfaf
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+
+<com.android.keyguard.KeyguardSecurityContainer
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/keyguard_security_container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:clipChildren="false"
+    android:clipToPadding="false"
+    android:paddingTop="@dimen/keyguard_lock_padding"
+    android:importantForAccessibility="yes"> <!-- Needed because TYPE_WINDOW_STATE_CHANGED is sent
+                                                  from this view when bouncer is shown -->
+    <com.android.keyguard.KeyguardSecurityViewFlipper
+        android:id="@+id/view_flipper"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:clipChildren="false"
+        android:clipToPadding="false"
+        android:paddingTop="@dimen/keyguard_security_view_top_margin"
+        android:layout_gravity="center"
+        android:gravity="center">
+    </com.android.keyguard.KeyguardSecurityViewFlipper>
+</com.android.keyguard.KeyguardSecurityContainer>
+
diff --git a/packages/SystemUI/res/drawable/controls_panel_background.xml b/packages/SystemUI/res/drawable/controls_panel_background.xml
index 9092877..fc108a5 100644
--- a/packages/SystemUI/res/drawable/controls_panel_background.xml
+++ b/packages/SystemUI/res/drawable/controls_panel_background.xml
@@ -18,5 +18,5 @@
 
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
     <solid android:color="#1F1F1F" />
-    <corners android:radius="@dimen/notification_corner_radius" />
+    <corners android:radius="@dimen/controls_panel_corner_radius" />
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_footer_edit_circle.xml b/packages/SystemUI/res/drawable/qs_footer_edit_circle.xml
new file mode 100644
index 0000000..2e29cae
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_footer_edit_circle.xml
@@ -0,0 +1,36 @@
+<?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.
+  -->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+       android:inset="@dimen/qs_footer_action_inset">
+    <ripple
+        android:color="?android:attr/colorControlHighlight">
+        <item android:id="@android:id/mask">
+            <!-- We make this shape a rounded rectangle instead of a oval so that it can animate -->
+            <!-- properly into an app/dialog. -->
+            <shape android:shape="rectangle">
+                <solid android:color="@android:color/white"/>
+                <corners android:radius="@dimen/qs_footer_action_corner_radius"/>
+            </shape>
+        </item>
+        <item>
+            <shape android:shape="rectangle">
+                <corners android:radius="@dimen/qs_footer_action_corner_radius"/>
+            </shape>
+        </item>
+
+    </ripple>
+</inset>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/statusbar_chip_bg.xml b/packages/SystemUI/res/drawable/statusbar_chip_bg.xml
new file mode 100644
index 0000000..d7de16d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/statusbar_chip_bg.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+    <solid android:color="?androidprv:attr/colorAccentPrimary" />
+    <corners android:radius="@dimen/ongoing_appops_chip_bg_corner_radius" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/privacy_chip_bg.xml b/packages/SystemUI/res/drawable/statusbar_privacy_chip_bg.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/privacy_chip_bg.xml
rename to packages/SystemUI/res/drawable/statusbar_privacy_chip_bg.xml
diff --git a/packages/SystemUI/res/layout/battery_status_chip.xml b/packages/SystemUI/res/layout/battery_status_chip.xml
new file mode 100644
index 0000000..ff68ac0
--- /dev/null
+++ b/packages/SystemUI/res/layout/battery_status_chip.xml
@@ -0,0 +1,43 @@
+<?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.
+-->
+
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"
+    android:layout_gravity="center_vertical|end"
+    tools:parentTag="com.android.systemui.statusbar.BatteryStatusChip">
+
+    <LinearLayout
+        android:id="@+id/rounded_container"
+        android:layout_width="wrap_content"
+        android:layout_height="@dimen/ongoing_appops_chip_height"
+        android:layout_gravity="center"
+        android:background="@drawable/statusbar_chip_bg"
+        android:clipToOutline="true"
+        android:gravity="center"
+        android:maxWidth="@dimen/ongoing_appops_chip_max_width"
+        android:minWidth="@dimen/ongoing_appops_chip_min_width">
+
+        <com.android.systemui.battery.BatteryMeterView
+            android:id="@+id/battery_meter_view"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_marginHorizontal="10dp" />
+
+    </LinearLayout>
+</merge>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/combined_qs_header.xml b/packages/SystemUI/res/layout/combined_qs_header.xml
index d689828..dffe40b 100644
--- a/packages/SystemUI/res/layout/combined_qs_header.xml
+++ b/packages/SystemUI/res/layout/combined_qs_header.xml
@@ -141,11 +141,14 @@
         android:layout_width="wrap_content"
         android:layout_height="@dimen/large_screen_shade_header_min_height"
         android:gravity="center"
-        app:layout_constraintEnd_toEndOf="@id/end_guide"
-        app:layout_constraintTop_toTopOf="@id/date"
         app:layout_constraintBottom_toBottomOf="@id/date"
-        >
-        <include layout="@layout/ongoing_privacy_chip"/>
+        app:layout_constraintEnd_toEndOf="@id/end_guide"
+        app:layout_constraintTop_toTopOf="@id/date">
+
+        <com.android.systemui.privacy.OngoingPrivacyChip
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent" />
+
     </FrameLayout>
 
 </com.android.systemui.util.NoRemeasureMotionLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/controls_fullscreen.xml b/packages/SystemUI/res/layout/controls_fullscreen.xml
index e08e63b..fa70303 100644
--- a/packages/SystemUI/res/layout/controls_fullscreen.xml
+++ b/packages/SystemUI/res/layout/controls_fullscreen.xml
@@ -15,19 +15,11 @@
      limitations under the License.
 -->
 
-<FrameLayout
+<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/control_detail_root"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical">
 
-
-    <LinearLayout
-        android:id="@+id/global_actions_controls"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical"
-        android:paddingHorizontal="@dimen/controls_padding_horizontal" />
-
-</FrameLayout>
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/controls_with_favorites.xml b/packages/SystemUI/res/layout/controls_with_favorites.xml
index aa211bf..71561c0 100644
--- a/packages/SystemUI/res/layout/controls_with_favorites.xml
+++ b/packages/SystemUI/res/layout/controls_with_favorites.xml
@@ -13,82 +13,94 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<merge
-    xmlns:android="http://schemas.android.com/apk/res/android">
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:orientation="vertical"
+    tools:parentTag="android.widget.LinearLayout">
 
-  <LinearLayout
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:orientation="horizontal"
-      android:layout_marginBottom="@dimen/controls_header_bottom_margin">
-
-    <!-- make sure the header stays centered in the layout by adding a spacer -->
-    <Space
-        android:id="@+id/controls_spacer"
-        android:layout_width="@dimen/controls_header_menu_size"
-        android:layout_height="1dp"
-        android:visibility="gone" />
-
-    <ImageView
-        android:id="@+id/controls_close"
-        android:contentDescription="@string/accessibility_desc_close"
-        android:src="@drawable/ic_close"
-        android:background="?android:attr/selectableItemBackgroundBorderless"
-        android:tint="@color/control_primary_text"
-        android:layout_width="@dimen/controls_header_menu_size"
-        android:layout_height="@dimen/controls_header_menu_size"
-        android:padding="12dp"
-        android:visibility="gone" />
-    <!-- need to keep this outer view in order to have a correctly sized anchor
-         for the dropdown menu, as well as dropdown background in the right place -->
     <LinearLayout
-        android:id="@+id/controls_header"
-        android:orientation="horizontal"
-        android:layout_width="0dp"
-        android:layout_weight="1"
-        android:minHeight="48dp"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:gravity="center">
-      <TextView
-          style="@style/Control.Spinner.Header"
-          android:clickable="false"
-          android:id="@+id/app_or_structure_spinner"
-          android:layout_width="wrap_content"
-          android:layout_height="wrap_content"
-          android:layout_gravity="center" />
-    </LinearLayout>
-    <ImageView
-        android:id="@+id/controls_more"
-        android:src="@drawable/ic_more_vert"
-        android:layout_width="@dimen/controls_header_menu_size"
-        android:layout_height="@dimen/controls_header_menu_size"
-        android:padding="12dp"
-        android:tint="@color/control_more_vert"
-        android:layout_gravity="center"
-        android:contentDescription="@string/accessibility_menu"
-        android:background="?android:attr/selectableItemBackgroundBorderless" />
-  </LinearLayout>
+        android:paddingHorizontal="@dimen/controls_header_horizontal_padding"
+        android:layout_marginBottom="@dimen/controls_header_bottom_margin"
+        android:orientation="horizontal">
 
-  <ScrollView
+        <!-- make sure the header stays centered in the layout by adding a spacer -->
+        <Space
+            android:id="@+id/controls_spacer"
+            android:layout_width="@dimen/controls_header_menu_button_size"
+            android:layout_height="1dp"
+            android:visibility="gone" />
+
+        <ImageView
+            android:id="@+id/controls_close"
+            android:layout_width="@dimen/controls_header_menu_button_size"
+            android:layout_height="@dimen/controls_header_menu_button_size"
+            android:layout_gravity="center_vertical"
+            android:background="?android:attr/selectableItemBackgroundBorderless"
+            android:contentDescription="@string/accessibility_desc_close"
+            android:padding="12dp"
+            android:src="@drawable/ic_close"
+            android:tint="@color/control_primary_text"
+            android:visibility="gone"
+            tools:visibility="visible" />
+
+        <!-- need to keep this outer view in order to have a correctly sized anchor
+             for the dropdown menu, as well as dropdown background in the right place -->
+        <LinearLayout
+            android:id="@+id/controls_header"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_weight="1"
+            android:gravity="center"
+            android:minHeight="48dp"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/app_or_structure_spinner"
+                style="@style/Control.Spinner.Header"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:clickable="false"
+                tools:text="Test app" />
+        </LinearLayout>
+
+        <ImageView
+            android:id="@+id/controls_more"
+            android:layout_width="@dimen/controls_header_menu_button_size"
+            android:layout_height="@dimen/controls_header_menu_button_size"
+            android:layout_gravity="center_vertical"
+            android:background="?android:attr/selectableItemBackgroundBorderless"
+            android:contentDescription="@string/accessibility_menu"
+            android:padding="12dp"
+            android:src="@drawable/ic_more_vert"
+            android:tint="@color/control_more_vert" />
+    </LinearLayout>
+
+    <ScrollView
         android:id="@+id/controls_scroll_view"
         android:layout_width="match_parent"
         android:layout_height="0dp"
+        android:layout_marginHorizontal="@dimen/controls_content_margin_horizontal"
         android:layout_weight="1"
-        android:orientation="vertical"
         android:clipChildren="true"
+        android:orientation="vertical"
         android:paddingHorizontal="16dp"
         android:scrollbars="none">
-    <include layout="@layout/global_actions_controls_list_view" />
 
-  </ScrollView>
+        <include layout="@layout/global_actions_controls_list_view" />
 
-  <FrameLayout
-      android:id="@+id/controls_panel"
-      android:layout_width="match_parent"
-      android:layout_height="0dp"
-      android:layout_weight="1"
-      android:background="@drawable/controls_panel_background"
-      android:visibility="gone"
-      />
+    </ScrollView>
+
+    <FrameLayout
+        android:id="@+id/controls_panel"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_marginHorizontal="@dimen/controls_content_margin_horizontal"
+        android:layout_weight="1"
+        android:background="@drawable/controls_panel_background"
+        android:visibility="gone"
+        tools:visibility="visible" />
 </merge>
diff --git a/packages/SystemUI/res/layout/large_screen_shade_header.xml b/packages/SystemUI/res/layout/large_screen_shade_header.xml
deleted file mode 100644
index 3029a27..0000000
--- a/packages/SystemUI/res/layout/large_screen_shade_header.xml
+++ /dev/null
@@ -1,100 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/split_shade_status_bar"
-    android:layout_width="match_parent"
-    android:layout_height="@dimen/large_screen_shade_header_height"
-    android:minHeight="@dimen/large_screen_shade_header_min_height"
-    android:clickable="false"
-    android:focusable="true"
-    android:paddingLeft="@dimen/large_screen_shade_header_left_padding"
-    android:paddingRight="@dimen/qs_panel_padding"
-    android:visibility="gone"
-    android:theme="@style/Theme.SystemUI.QuickSettings.Header">
-
-    <com.android.systemui.statusbar.policy.Clock
-        android:id="@+id/clock"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:minWidth="48dp"
-        android:minHeight="@dimen/large_screen_shade_header_min_height"
-        android:gravity="start|center_vertical"
-        android:paddingStart="@dimen/status_bar_left_clock_starting_padding"
-        android:paddingEnd="@dimen/status_bar_left_clock_end_padding"
-        android:singleLine="true"
-        android:textAppearance="@style/TextAppearance.QS.Status" />
-
-    <com.android.systemui.statusbar.policy.DateView
-        android:id="@+id/date"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="start|center_vertical"
-        android:gravity="center_vertical"
-        android:singleLine="true"
-        android:textAppearance="@style/TextAppearance.QS.Status"
-        systemui:datePattern="@string/abbrev_wday_month_day_no_year_alarm" />
-
-    <FrameLayout
-        android:id="@+id/rightLayout"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:gravity="end">
-
-        <LinearLayout
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_gravity="end|center_vertical">
-
-            <include
-                android:id="@+id/carrier_group"
-                layout="@layout/qs_carrier_group"
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                android:layout_gravity="end|center_vertical"
-                android:layout_marginStart="8dp"
-                android:focusable="false"
-                android:minHeight="@dimen/large_screen_shade_header_min_height"
-                android:minWidth="48dp" />
-
-            <com.android.systemui.statusbar.phone.StatusIconContainer
-                android:id="@+id/statusIcons"
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                android:paddingEnd="@dimen/signal_cluster_battery_padding" />
-
-            <com.android.systemui.battery.BatteryMeterView
-                android:id="@+id/batteryRemainingIcon"
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                systemui:textAppearance="@style/TextAppearance.QS.Status" />
-            <FrameLayout
-                android:id="@+id/privacy_container"
-                android:layout_width="0dp"
-                android:layout_height="match_parent"
-                android:minHeight="48dp"
-                android:layout_weight="1"
-                android:paddingStart="16dp">
-
-                <include layout="@layout/ongoing_privacy_chip" />
-
-            </FrameLayout>
-        </LinearLayout>
-    </FrameLayout>
-
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
index d1a2cf4..2c7467d 100644
--- a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
+++ b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
@@ -16,16 +16,15 @@
 -->
 
 
-<com.android.systemui.privacy.OngoingPrivacyChip
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/privacy_chip"
+    xmlns:tools="http://schemas.android.com/tools"
     android:layout_height="match_parent"
     android:layout_width="wrap_content"
     android:layout_gravity="center_vertical|end"
-    android:focusable="true"
     android:clipChildren="false"
     android:clipToPadding="false"
-    android:paddingStart="8dp"
+    tools:parentTag="com.android.systemui.privacy.OngoingPrivacyChip">
     >
 
         <LinearLayout
@@ -35,8 +34,9 @@
             android:paddingStart="10dp"
             android:paddingEnd="10dp"
             android:gravity="center"
+            android:clipToOutline="true"
+            android:clipToPadding="false"
             android:layout_gravity="center"
             android:minWidth="@dimen/ongoing_appops_chip_min_width"
-            android:maxWidth="@dimen/ongoing_appops_chip_max_width"
-            />
-</com.android.systemui.privacy.OngoingPrivacyChip>
\ No newline at end of file
+            android:maxWidth="@dimen/ongoing_appops_chip_max_width" />
+</merge>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml
index b1d3ed05..745cfc6 100644
--- a/packages/SystemUI/res/layout/qs_footer_impl.xml
+++ b/packages/SystemUI/res/layout/qs_footer_impl.xml
@@ -64,7 +64,7 @@
                     android:layout_width="@dimen/qs_footer_action_button_size"
                     android:layout_height="@dimen/qs_footer_action_button_size"
                     android:layout_gravity="center_vertical|end"
-                    android:background="?android:attr/selectableItemBackground"
+                    android:background="@drawable/qs_footer_edit_circle"
                     android:clickable="true"
                     android:contentDescription="@string/accessibility_quick_settings_edit"
                     android:focusable="true"
diff --git a/packages/SystemUI/res/layout/quick_qs_status_icons.xml b/packages/SystemUI/res/layout/quick_qs_status_icons.xml
deleted file mode 100644
index 542a1c9..0000000
--- a/packages/SystemUI/res/layout/quick_qs_status_icons.xml
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/quick_qs_status_icons"
-    android:layout_width="match_parent"
-    android:layout_height="@*android:dimen/quick_qs_offset_height"
-    android:clipChildren="false"
-    android:clipToPadding="false"
-    android:minHeight="@dimen/qs_header_row_min_height"
-    android:clickable="false"
-    android:focusable="true"
-    android:theme="@style/Theme.SystemUI.QuickSettings.Header">
-
-    <LinearLayout
-        android:id="@+id/clock_container"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:orientation="horizontal"
-        android:layout_gravity="center_vertical|start"
-        android:gravity="center_vertical|start"
-        >
-
-        <com.android.systemui.statusbar.policy.Clock
-            android:id="@+id/clock"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:minHeight="@dimen/qs_header_row_min_height"
-            android:gravity="center_vertical|start"
-            android:paddingStart="@dimen/status_bar_left_clock_starting_padding"
-            android:paddingEnd="@dimen/status_bar_left_clock_end_padding"
-            android:singleLine="true"
-            android:textAppearance="@style/TextAppearance.QS.Status" />
-
-        <com.android.systemui.statusbar.policy.VariableDateView
-            android:id="@+id/date_clock"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_marginStart="@dimen/status_bar_left_clock_end_padding"
-            android:gravity="center_vertical|start"
-            android:singleLine="true"
-            android:textAppearance="@style/TextAppearance.QS.Status"
-            systemui:longDatePattern="@string/abbrev_wday_month_day_no_year_alarm"
-            systemui:shortDatePattern="@string/abbrev_month_day_no_year"
-        />
-    </LinearLayout>
-
-    <include layout="@layout/qs_carrier_group"
-        android:id="@+id/carrier_group"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:minHeight="@dimen/qs_header_row_min_height"
-        android:minWidth="48dp"
-        android:layout_marginStart="8dp"
-        android:layout_gravity="end|center_vertical"
-        android:focusable="false"/>
-
-    <View
-        android:id="@+id/separator"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:layout_marginStart="8dp"
-        android:layout_marginEnd="8dp"
-        android:visibility="gone"
-        />
-
-    <FrameLayout
-        android:id="@+id/rightLayout"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:gravity="end"
-        >
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_gravity="center_vertical|end"
-        >
-        <com.android.systemui.statusbar.phone.StatusIconContainer
-            android:id="@+id/statusIcons"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:paddingEnd="@dimen/signal_cluster_battery_padding" />
-
-        <com.android.systemui.battery.BatteryMeterView
-            android:id="@+id/batteryRemainingIcon"
-            android:layout_height="match_parent"
-            android:layout_width="0dp"
-            android:layout_weight="1"
-            systemui:textAppearance="@style/TextAppearance.QS.Status"
-            android:paddingEnd="2dp" />
-
-    </LinearLayout>
-    </FrameLayout>
-
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index 9fc3f40..1749ed4 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -33,32 +33,16 @@
     android:paddingStart="0dp"
     android:elevation="4dp" >
 
-    <!-- Date and privacy. Only visible in QS when not in split shade -->
-    <include layout="@layout/quick_status_bar_header_date_privacy"/>
-
-    <RelativeLayout
-        android:id="@+id/qs_container"
+    <com.android.systemui.qs.QuickQSPanel
+        android:id="@+id/quick_qs_panel"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_gravity="top"
+        android:layout_marginTop="@dimen/qqs_layout_margin_top"
         android:clipChildren="false"
-        android:clipToPadding="false">
-        <!-- Time, icons and Carrier (only in QS when not in split shade) -->
-        <include layout="@layout/quick_qs_status_icons"/>
-
-        <com.android.systemui.qs.QuickQSPanel
-            android:id="@+id/quick_qs_panel"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/quick_qs_status_icons"
-            android:layout_marginTop="@dimen/qqs_layout_margin_top"
-            android:accessibilityTraversalAfter="@id/quick_qs_status_icons"
-            android:clipChildren="false"
-            android:clipToPadding="false"
-            android:focusable="true"
-            android:paddingBottom="@dimen/qqs_layout_padding_bottom"
-            android:importantForAccessibility="no">
-        </com.android.systemui.qs.QuickQSPanel>
-    </RelativeLayout>
+        android:clipToPadding="false"
+        android:focusable="true"
+        android:paddingBottom="@dimen/qqs_layout_padding_bottom"
+        android:importantForAccessibility="no">
+    </com.android.systemui.qs.QuickQSPanel>
 
 </com.android.systemui.qs.QuickStatusBarHeader>
diff --git a/packages/SystemUI/res/layout/quick_status_bar_header_date_privacy.xml b/packages/SystemUI/res/layout/quick_status_bar_header_date_privacy.xml
deleted file mode 100644
index 8b5d953..0000000
--- a/packages/SystemUI/res/layout/quick_status_bar_header_date_privacy.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-** Copyright 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.
--->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/quick_status_bar_date_privacy"
-    android:layout_width="match_parent"
-    android:layout_height="@*android:dimen/quick_qs_offset_height"
-    android:clipChildren="false"
-    android:clipToPadding="false"
-    android:gravity="center"
-    android:layout_gravity="top"
-    android:orientation="horizontal"
-    android:importantForAccessibility="no"
-    android:clickable="true"
-    android:minHeight="48dp">
-
-    <FrameLayout
-        android:id="@+id/date_container"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:minHeight="48dp"
-        android:layout_weight="1"
-        android:gravity="center_vertical|start" >
-
-        <com.android.systemui.statusbar.policy.VariableDateView
-            android:id="@+id/date"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="start|center_vertical"
-            android:gravity="center_vertical"
-            android:singleLine="true"
-            android:textAppearance="@style/TextAppearance.QS.Status"
-            systemui:longDatePattern="@string/abbrev_wday_month_day_no_year_alarm"
-            systemui:shortDatePattern="@string/abbrev_month_day_no_year"
-        />
-    </FrameLayout>
-
-    <!-- We want this to be centered (to align with notches). In order to do that, the following
-         has to hold (in portrait):
-         * date_container and privacy_container must have the same width and weight
-         -->
-    <android.widget.Space
-        android:id="@+id/space"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_gravity="center_vertical|center_horizontal"
-        android:visibility="gone" />
-
-    <FrameLayout
-        android:id="@+id/privacy_container"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:minHeight="48dp"
-        android:layout_weight="1"
-        android:gravity="center_vertical|end" >
-
-        <include layout="@layout/ongoing_privacy_chip" />
-
-    </FrameLayout>
-</LinearLayout>
diff --git a/packages/SystemUI/res/raw/biometricprompt_rear_landscape_base.json b/packages/SystemUI/res/raw/biometricprompt_rear_landscape_base.json
new file mode 100644
index 0000000..49c1c40
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_rear_landscape_base.json
@@ -0,0 +1 @@
+{"v":"5.8.1","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"BiometricPrompt_Rear_Landscape_Base_Foldable","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 18","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[169.478,169.749,0],"ix":2,"l":2},"a":{"a":0,"k":[-48.123,-30.19,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".grey400","cl":"grey400","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"black circle matte","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey904","cl":"grey904","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,35.536,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.552,0.087],[0,0]],"o":[[0,0],[0,-3.287],[0,0],[0,0]],"v":[[-2.301,8.869],[-2.301,-3.772],[2.301,-9.806],[2.301,9.806]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"black circle matte 2","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue401","cl":"blue401","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,-27.655,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,3.286],[0,0],[-2.552,0.086],[0,0]],"o":[[0,0],[0,-3.286],[0,0],[-2.552,-0.086]],"v":[[-2.301,16.282],[-2.301,-16.281],[2.301,-22.313],[2.301,22.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"black circle matte 3","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":-129,"s":[-67]},{"t":-29,"s":[0]}],"ix":10},"p":{"a":0,"k":[-75.352,41.307,0],"ix":2,"l":2},"a":{"a":0,"k":[94.648,211.307,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.72,-5.642],[0,0],[-9.394,-0.562],[-0.298,-0.038]],"o":[[-5.153,4.329],[3.882,-16.05],[0.31,0.019],[-0.044,0.75]],"v":[[0.863,12.222],[-8.931,14.755],[8.005,-15.108],[8.931,-15.021]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[81.486,130.081],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 9","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.459,6.045],[-5.153,4.329],[-0.044,0.75],[3.116,-24.664],[5.23,-22.052],[8.666,11.92],[-2.9,9.135]],"o":[[0,0],[6.72,-5.642],[12.723,1.335],[-2.369,18.762],[-13.993,-5.333],[2.255,-5.502],[1.843,-5.815]],"v":[[-9.99,-18.348],[-0.196,-20.881],[7.872,-48.124],[21.578,-9.331],[12.104,48.124],[-22.574,21.555],[-14.791,-0.206]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[82.545,163.184],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 8","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"black circle matte 4","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey903","cl":"grey903","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-18.345,-92.442,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[24.07,0],[0,0],[-8.27,0],[0,0]],"o":[[0,0],[0,8.269],[0,0],[-14.024,-17.379]],"v":[[-29.778,-14.252],[-29.778,-0.721],[-14.805,14.252],[29.778,14.252]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"black circle matte 5","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".grey902","cl":"grey902","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-15.947,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[154.053,139.81,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.3,0.367],[0,0],[-2.364,0.157],[0,0]],"o":[[0,0],[2.3,-0.367],[0,0],[-2.364,-0.157]],"v":[[-3.5,75.533],[-3.5,-75.533],[3.5,-76.312],[3.5,76.312]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[113.225,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 7","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,8.269],[0,0],[2.181,-0.187],[0,0],[-2.23,0],[0,42.252],[10.593,13.127],[0,0]],"o":[[0,0],[-2.23,0],[0,0],[2.181,0.187],[42.252,0],[0,-18.182],[0,0],[-8.27,0]],"v":[[-34.946,-62.973],[-34.946,-76.504],[-41.558,-76.201],[-41.558,76.201],[-34.946,76.504],[41.558,0],[24.61,-48],[-19.973,-48]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[156.824,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 5","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".black 2","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-48.123,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.833],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.167],"y":[0,0,0]},"t":-129,"s":[0,0,100]},{"t":-79,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".grey700","cl":"grey700","parent":15,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-56.481,-59.936,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.767,0],[0,0],[0,-3.767],[0,0],[-3.767,0],[0,0],[0,3.767],[0,0]],"o":[[0,0],[-3.767,0],[0,0],[0,3.767],[0,0],[3.767,0],[0,0],[0,-3.767]],"v":[[46.055,-14.479],[-46.056,-14.479],[-52.876,-7.659],[-52.876,7.658],[-46.056,14.479],[46.055,14.479],[52.876,7.658],[52.876,-7.659]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".grey901","cl":"grey901","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[16.485,2.727,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[50,50,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.184,0],[0,0],[0,0],[0,0],[0,-4.375]],"o":[[0,4.184],[0,0],[0,0],[0,0],[4.375,0],[0,0]],"v":[[114.116,92.129],[106.54,99.705],[7.788,99.705],[7.788,-99.704],[106.161,-99.704],[114.116,-91.749]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[5.707,0],[0,0],[1.894,-1.05],[0.886,0.346],[0,0],[2.166,0],[0,0],[0,-5.707],[0,0],[0,-1.46],[0,0],[-1.133,-0.038],[0,0],[0,-1.459],[0,0],[-1.133,-0.038],[0,0],[-5.708,0],[0,0],[-1.894,1.05],[-0.846,-0.289],[0,0],[-2.166,0],[0,0],[0,5.706],[0,0]],"o":[[0,0],[-2.166,0],[-0.883,0.354],[0,0],[-1.895,-1.05],[0,0],[-5.708,0],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[0,5.707],[0,0],[2.165,0],[0.833,-0.334],[0,0],[1.894,1.05],[0,0],[5.707,0],[0,0],[0,-5.707]],"v":[[106.16,-102.082],[8.455,-102.082],[2.265,-100.48],[-0.488,-100.468],[-0.519,-100.48],[-6.71,-102.082],[-104.116,-102.082],[-114.45,-91.748],[-114.45,-36.119],[-116.494,-33.44],[-116.494,-18.979],[-114.45,-16.3],[-114.45,-0.877],[-116.494,1.802],[-116.494,28.704],[-114.45,31.383],[-114.45,91.749],[-104.116,102.083],[-6.495,102.083],[-0.305,100.481],[2.294,100.425],[2.395,100.481],[9.872,102.083],[106.161,102.083],[116.494,91.75],[116.494,-91.748]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.529411792755,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_rear_portrait_base.json b/packages/SystemUI/res/raw/biometricprompt_rear_portrait_base.json
new file mode 100644
index 0000000..9ea0d35
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_rear_portrait_base.json
@@ -0,0 +1 @@
+{"v":"5.8.1","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"BiometricPrompt_Rear_Portrait_Base_Foldable","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 18","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[169.478,169.749,0],"ix":2,"l":2},"a":{"a":0,"k":[-48.123,-30.19,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".grey400","cl":"grey400","parent":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"black circle matte","parent":14,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey904","cl":"grey904","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,35.536,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.552,0.087],[0,0]],"o":[[0,0],[0,-3.287],[0,0],[0,0]],"v":[[-2.301,8.869],[-2.301,-3.772],[2.301,-9.806],[2.301,9.806]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"black circle matte 2","parent":14,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue401","cl":"blue401","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,-27.655,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,3.286],[0,0],[-2.552,0.086],[0,0]],"o":[[0,0],[0,-3.286],[0,0],[-2.552,-0.086]],"v":[[-2.301,16.282],[-2.301,-16.281],[2.301,-22.313],[2.301,22.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"black circle matte 3","parent":14,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Finger 3","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-2,"ix":10},"p":{"a":0,"k":[260.134,83.782,0],"ix":2,"l":2},"a":{"a":0,"k":[302.634,38.782,0],"ix":1,"l":2},"s":{"a":0,"k":[178,178,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.262,5.076],[0,0],[-0.424,-7.095],[-0.028,-0.225]],"o":[[3.269,-3.892],[-12.123,2.932],[0.015,0.234],[0.567,-0.034]],"v":[[9.232,0.652],[11.145,-6.746],[-11.412,6.046],[-11.346,6.746]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[241.281,55.033],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 5","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.565,-1.102],[3.269,-3.892],[0.566,-0.033],[-18.63,2.353],[-16.656,3.951],[9.004,6.546],[6.9,-2.19]],"o":[[0,0],[-4.262,5.076],[1.008,9.61],[14.171,-1.79],[-4.028,-10.569],[-4.156,1.703],[-4.392,1.392]],"v":[[-13.858,-7.546],[-15.771,-0.148],[-36.349,5.946],[-7.047,16.299],[36.349,9.142],[16.281,-17.051],[-0.156,-11.172]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[266.285,55.833],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 4","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"black circle matte 4","parent":14,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".grey903","cl":"grey903","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-18.345,-92.442,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[24.07,0],[0,0],[-8.27,0],[0,0]],"o":[[0,0],[0,8.269],[0,0],[-14.024,-17.379]],"v":[[-29.778,-14.252],[-29.778,-0.721],[-14.805,14.252],[29.778,14.252]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"black circle matte 5","parent":14,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".grey902","cl":"grey902","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-15.947,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[154.053,139.81,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.3,0.367],[0,0],[-2.364,0.157],[0,0]],"o":[[0,0],[2.3,-0.367],[0,0],[-2.364,-0.157]],"v":[[-3.5,75.533],[-3.5,-75.533],[3.5,-76.312],[3.5,76.312]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[113.225,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 7","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,8.269],[0,0],[2.181,-0.187],[0,0],[-2.23,0],[0,42.252],[10.593,13.127],[0,0]],"o":[[0,0],[-2.23,0],[0,0],[2.181,0.187],[42.252,0],[0,-18.182],[0,0],[-8.27,0]],"v":[[-34.946,-62.973],[-34.946,-76.504],[-41.558,-76.201],[-41.558,76.201],[-34.946,76.504],[41.558,0],[24.61,-48],[-19.973,-48]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[156.824,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 5","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".black 2","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-48.123,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.833],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.167],"y":[0,0,0]},"t":-129,"s":[0,0,100]},{"t":-79,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".grey700","cl":"grey700","parent":16,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-56.481,-59.936,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.767,0],[0,0],[0,-3.767],[0,0],[-3.767,0],[0,0],[0,3.767],[0,0]],"o":[[0,0],[-3.767,0],[0,0],[0,3.767],[0,0],[3.767,0],[0,0],[0,-3.767]],"v":[[46.055,-14.479],[-46.056,-14.479],[-52.876,-7.659],[-52.876,7.658],[-46.056,14.479],[46.055,14.479],[52.876,7.658],[52.876,-7.659]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".grey901","cl":"grey901","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[16.485,2.727,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[50,50,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.184,0],[0,0],[0,0],[0,0],[0,-4.375]],"o":[[0,4.184],[0,0],[0,0],[0,0],[4.375,0],[0,0]],"v":[[114.116,92.129],[106.54,99.705],[7.788,99.705],[7.788,-99.704],[106.161,-99.704],[114.116,-91.749]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[5.707,0],[0,0],[1.894,-1.05],[0.886,0.346],[0,0],[2.166,0],[0,0],[0,-5.707],[0,0],[0,-1.46],[0,0],[-1.133,-0.038],[0,0],[0,-1.459],[0,0],[-1.133,-0.038],[0,0],[-5.708,0],[0,0],[-1.894,1.05],[-0.846,-0.289],[0,0],[-2.166,0],[0,0],[0,5.706],[0,0]],"o":[[0,0],[-2.166,0],[-0.883,0.354],[0,0],[-1.895,-1.05],[0,0],[-5.708,0],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[0,5.707],[0,0],[2.165,0],[0.833,-0.334],[0,0],[1.894,1.05],[0,0],[5.707,0],[0,0],[0,-5.707]],"v":[[106.16,-102.082],[8.455,-102.082],[2.265,-100.48],[-0.488,-100.468],[-0.519,-100.48],[-6.71,-102.082],[-104.116,-102.082],[-114.45,-91.748],[-114.45,-36.119],[-116.494,-33.44],[-116.494,-18.979],[-114.45,-16.3],[-114.45,-0.877],[-116.494,1.802],[-116.494,28.704],[-114.45,31.383],[-114.45,91.749],[-104.116,102.083],[-6.495,102.083],[-0.305,100.481],[2.294,100.425],[2.395,100.481],[9.872,102.083],[106.161,102.083],[116.494,91.75],[116.494,-91.748]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.529411792755,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_rear_portrait_reverse_base.json b/packages/SystemUI/res/raw/biometricprompt_rear_portrait_reverse_base.json
new file mode 100644
index 0000000..f2b2593
--- /dev/null
+++ b/packages/SystemUI/res/raw/biometricprompt_rear_portrait_reverse_base.json
@@ -0,0 +1 @@
+{"v":"5.8.1","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"BiometricPrompt_Rear_Portrait_Reverse_Base_Foldable","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 18","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":270,"ix":10},"p":{"a":0,"k":[169.478,169.749,0],"ix":2,"l":2},"a":{"a":0,"k":[-48.123,-30.19,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".grey400","cl":"grey400","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"black circle matte","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey904","cl":"grey904","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,35.536,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.552,0.087],[0,0]],"o":[[0,0],[0,-3.287],[0,0],[0,0]],"v":[[-2.301,8.869],[-2.301,-3.772],[2.301,-9.806],[2.301,9.806]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"black circle matte 2","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue401","cl":"blue401","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,-27.655,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,3.286],[0,0],[-2.552,0.086],[0,0]],"o":[[0,0],[0,-3.286],[0,0],[-2.552,-0.086]],"v":[[-2.301,16.282],[-2.301,-16.281],[2.301,-22.313],[2.301,22.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"black circle matte 3","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-75.352,41.307,0],"ix":2,"l":2},"a":{"a":0,"k":[94.648,211.307,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.72,-5.642],[0,0],[-9.394,-0.562],[-0.298,-0.038]],"o":[[-5.153,4.329],[3.882,-16.05],[0.31,0.019],[-0.044,0.75]],"v":[[0.863,12.222],[-8.931,14.755],[8.005,-15.108],[8.931,-15.021]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[81.486,130.081],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 9","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.459,6.045],[-5.153,4.329],[-0.044,0.75],[3.116,-24.664],[5.23,-22.052],[8.666,11.92],[-2.9,9.135]],"o":[[0,0],[6.72,-5.642],[12.723,1.335],[-2.369,18.762],[-13.993,-5.333],[2.255,-5.502],[1.843,-5.815]],"v":[[-9.99,-18.348],[-0.196,-20.881],[7.872,-48.124],[21.578,-9.331],[12.104,48.124],[-22.574,21.555],[-14.791,-0.206]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[82.545,163.184],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 8","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"black circle matte 4","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey903","cl":"grey903","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-18.345,-92.442,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[24.07,0],[0,0],[-8.27,0],[0,0]],"o":[[0,0],[0,8.269],[0,0],[-14.024,-17.379]],"v":[[-29.778,-14.252],[-29.778,-0.721],[-14.805,14.252],[29.778,14.252]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"black circle matte 5","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".grey902","cl":"grey902","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-15.947,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[154.053,139.81,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.3,0.367],[0,0],[-2.364,0.157],[0,0]],"o":[[0,0],[2.3,-0.367],[0,0],[-2.364,-0.157]],"v":[[-3.5,75.533],[-3.5,-75.533],[3.5,-76.312],[3.5,76.312]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[113.225,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 7","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,8.269],[0,0],[2.181,-0.187],[0,0],[-2.23,0],[0,42.252],[10.593,13.127],[0,0]],"o":[[0,0],[-2.23,0],[0,0],[2.181,0.187],[42.252,0],[0,-18.182],[0,0],[-8.27,0]],"v":[[-34.946,-62.973],[-34.946,-76.504],[-41.558,-76.201],[-41.558,76.201],[-34.946,76.504],[41.558,0],[24.61,-48],[-19.973,-48]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[156.824,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 5","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".black 2","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-48.123,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.833],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.167],"y":[0,0,0]},"t":-129,"s":[0,0,100]},{"t":-79,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".grey700","cl":"grey700","parent":15,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-56.481,-59.936,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.767,0],[0,0],[0,-3.767],[0,0],[-3.767,0],[0,0],[0,3.767],[0,0]],"o":[[0,0],[-3.767,0],[0,0],[0,3.767],[0,0],[3.767,0],[0,0],[0,-3.767]],"v":[[46.055,-14.479],[-46.056,-14.479],[-52.876,-7.659],[-52.876,7.658],[-46.056,14.479],[46.055,14.479],[52.876,7.658],[52.876,-7.659]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".grey901","cl":"grey901","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[16.485,2.727,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[50,50,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.184,0],[0,0],[0,0],[0,0],[0,-4.375]],"o":[[0,4.184],[0,0],[0,0],[0,0],[4.375,0],[0,0]],"v":[[114.116,92.129],[106.54,99.705],[7.788,99.705],[7.788,-99.704],[106.161,-99.704],[114.116,-91.749]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[5.707,0],[0,0],[1.894,-1.05],[0.886,0.346],[0,0],[2.166,0],[0,0],[0,-5.707],[0,0],[0,-1.46],[0,0],[-1.133,-0.038],[0,0],[0,-1.459],[0,0],[-1.133,-0.038],[0,0],[-5.708,0],[0,0],[-1.894,1.05],[-0.846,-0.289],[0,0],[-2.166,0],[0,0],[0,5.706],[0,0]],"o":[[0,0],[-2.166,0],[-0.883,0.354],[0,0],[-1.895,-1.05],[0,0],[-5.708,0],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[0,5.707],[0,0],[2.165,0],[0.833,-0.334],[0,0],[1.894,1.05],[0,0],[5.707,0],[0,0],[0,-5.707]],"v":[[106.16,-102.082],[8.455,-102.082],[2.265,-100.48],[-0.488,-100.468],[-0.519,-100.48],[-6.71,-102.082],[-104.116,-102.082],[-114.45,-91.748],[-114.45,-36.119],[-116.494,-33.44],[-116.494,-18.979],[-114.45,-16.3],[-114.45,-0.877],[-116.494,1.802],[-116.494,28.704],[-114.45,31.383],[-114.45,91.749],[-104.116,102.083],[-6.495,102.083],[-0.305,100.481],[2.294,100.425],[2.395,100.481],[9.872,102.083],[106.161,102.083],[116.494,91.75],[116.494,-91.748]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.529411792755,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]}
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 65c2417..4a73390 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Kennisgewingskerm."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Vinnige instellings."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Sluitskerm."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Werksluitskerm"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Maak toe"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Helderheid"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Kleuromkering"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Kleurregstelling"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Lettergrootte"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Bestuur gebruikers"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Klaar"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Maak toe"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"skermopname"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Titelloos"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Bystandmodus"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Lettergrootte"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Maak kleiner"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Maak groter"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Vergrotingvenster"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Vergrotingvensterkontroles"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoem in"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Kan nie uitsaai nie"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kan nie stoor nie. Probeer weer."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kan nie stoor nie."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Gebruik minstens 4 karakters"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Gebruik minder as 16 karakters"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Bounommer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Bounommer is na knipbord gekopieer."</string>
     <string name="basic_status" msgid="2315371112182658176">"Maak gesprek oop"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Minstens een toestel beskikbaar is"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Raak en hou kortpad"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Kanselleer"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Draai nou om"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Vou foon oop vir ’n beter selfie"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Draai om na voorste skerm vir ’n beter selfie?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gebruik die agterste kamera vir ’n breër foto met ’n hoër resolusie."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Hierdie skerm sal afskakel"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Wissel skerms nou"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Ontvou foon"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Wissel skerms?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Gebruik die agterste kamera vir hoër resolusie"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Keer die foon om vir hoër resolusie"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Voubare toestel word ontvou"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Voubare toestel word omgekeer"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batterykrag oor"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Skakel oor na werkprofiel"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Maak toe"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Sluitskerminstellings"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-fi is nie beskikbaar nie"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera is geblokkeer"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera en mikrofoon is geblokkeer"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofoon is geblokkeer"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioriteitmodus is aan"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-af/tiles_states_strings.xml b/packages/SystemUI/res/values-af/tiles_states_strings.xml
index e60f233..662aa71 100644
--- a/packages/SystemUI/res/values-af/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-af/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Af"</item>
     <item msgid="5966994759929723339">"Aan"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Onbeskikbaar"</item>
+    <item msgid="2478289035899842865">"Af"</item>
+    <item msgid="5137565285664080143">"Aan"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index d2d7e64..101382e 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"የማሳወቂያ ጥላ።"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ፈጣን ቅንብሮች።"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ማያ ገጽ ቆልፍ።"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"የስራ ማያ ገጽ ቁልፍ"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ዝጋ"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ብሩህነት"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ተቃራኒ ቀለም"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"የቀለም ማስተካከያ"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"የቅርጸ-ቁምፊ መጠን"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ተጠቃሚዎችን ያስተዳድሩ"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"ተከናውኗል"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ዝጋ"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ማያን መቅረጽ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"ርዕስ የለም"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ተጠባባቂ"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"የቅርጸ-ቁምፊ መጠን"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"አሳንስ"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"ተለቅ አድርግ"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"የማጉያ መስኮት"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"የማጉያ መስኮት መቆጣጠሪያዎች"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"አጉላ"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"መሰራጨት አይችልም"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ማስቀመጥ አልተቻለም። እንደገና ይሞክሩ።"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ማስቀመጥ አልተቻለም።"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"ቢያንስ 4 ቁምፊዎችን ይጠቀሙ"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"ከ16 የሚያንሱ ቁምፊዎችን ይጠቀሙ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"የግንብ ቁጥር"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"የገንባ ቁጥር ወደ ቅንጥብ ሰሌዳ ተቀድቷል።"</string>
     <string name="basic_status" msgid="2315371112182658176">"ውይይት ይክፈቱ"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ቢያንስ አንድ መሣሪያ ይገኛል"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"የይንኩ እና ይያዙ አቋራጭ"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ይቅር"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"አሁን ገልበጥ"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ለተሻለ የራስ ፎቶ ስልክን ይዘርጉ"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ለተሻለ የራስ ፎቶ ወደፊት ማሳያ ይገልበጥ?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ከፍተኛ ጥራት ላለው ሰፊ ፎቶ የኋለኛውን ካሜራ ይጠቀሙ።"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ይህ ማያ ገጽ ይጠፋል"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"ማያ ገፆችን አሁን ይቀይሩ"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"ስልክን ይዘርጉ"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"ማያ ገፆች ይቀየሩ?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"ለከፍተኛ ጥራት የኋላ ካሜራውን ይጠቀሙ"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ለከፍተኛ ጥራት ስልኩን ይቀይሩ"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"መታጠፍ የሚችል መሣሪያ እየተዘረጋ ነው"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"መታጠፍ የሚችል መሣሪያ እየተገለበጠ ነው"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ባትሪ ይቀራል"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ወደ የሥራ መገለጫ ቀይር"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ዝጋ"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"የማያ ገጽ ቁልፍ ቅንብሮች"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi አይገኝም"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"ካሜራ ታግዷል"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"ካሜራ እና ማይክሮፎን ታግደዋል"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"ማይክሮፎን ታግዷል"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"የቅድሚያ ሁነታ በርቷል"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/tiles_states_strings.xml b/packages/SystemUI/res/values-am/tiles_states_strings.xml
index bbf2d23..e5d68d9 100644
--- a/packages/SystemUI/res/values-am/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-am/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"ጠፍቷል"</item>
     <item msgid="5966994759929723339">"በርቷል"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"አይገኝም"</item>
+    <item msgid="2478289035899842865">"ጠፍቷል"</item>
+    <item msgid="5137565285664080143">"በርቷል"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 66279d3..f629387 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"مركز الإشعارات."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"الإعدادات السريعة."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"شاشة القفل."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"شاشة قفل بيانات العمل"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"إغلاق"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"السطوع"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"قلب الألوان"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"تصحيح الألوان"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"حجم الخط"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"إدارة المستخدمين"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"تم"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"إغلاق"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"تسجيل محتوى الشاشة"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"بلا عنوان"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"وضع الاستعداد"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"حجم الخط"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"تصغير الحجم"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"تكبير الحجم"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"نافذة التكبير"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"عناصر التحكم في نافذة التكبير"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"تكبير"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"حدث خطأ. يُرجى إعادة المحاولة."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"جارٍ التحميل"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"جهاز لوحي"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"بثّ الوسائط"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"جارٍ بثّ \"<xliff:g id="APP_LABEL">%1$s</xliff:g>\""</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"غير نشط، تحقّق من التطبيق."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"لم يتم العثور عليه."</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"عنصر التحكّم غير متوفّر"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"يتعذّر البث"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"لا يمكن إجراء الحفظ. يُرجى إعادة المحاولة."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"لا يمكن إجراء الحفظ."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"يجب استخدام 4 أحرف على الأقل."</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"يجب أن يحتوي الرمز على أقل من 16 حرفًا."</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"رقم الإصدار"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"تم نسخ رقم الإصدار إلى الحافظة."</string>
     <string name="basic_status" msgid="2315371112182658176">"محادثة مفتوحة"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• توفُّر جهاز واحد على الأقل"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"انقر مع الاستمرار على الاختصار."</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"إلغاء"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"قلب الجهاز الآن"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"عليك فتح الهاتف لالتقاط صورة ذاتية بشكل أفضل."</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"أتريد استخدام الكاميرا الأمامية لصورة ذاتية أفضل؟"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"استخدِم الكاميرا الخلفية لالتقاط صورة أعرض وبدرجة دقة أعلى."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* سيتم إطفاء هذه الشاشة."</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"تبديل الشاشتَين الآن"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"فتح الهاتف"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"هل تريد تبديل الشاشتَين؟"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"للحصول على درجة دقة أعلى، استخدِم الكاميرا الخلفية."</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"للحصول على درجة دقة أعلى، اقلِب الهاتف."</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"جهاز قابل للطي يجري فتحه"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"جهاز قابل للطي يجري قلبه"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"النسبة المئوية المتبقية من شحن البطارية: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"التبديل إلى الملف الشخصي للعمل"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"إغلاق"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"إعدادات شاشة القفل"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ar/tiles_states_strings.xml b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
index 44b58f9..31d9707 100644
--- a/packages/SystemUI/res/values-ar/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"غير مفعّلة"</item>
     <item msgid="5966994759929723339">"مفعَّلة"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"الخيار غير متوفّر"</item>
+    <item msgid="2478289035899842865">"الخيار غير مفعَّل"</item>
+    <item msgid="5137565285664080143">"الخيار مفعَّل"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 688025b..aa19842 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"জাননী পেনেল।"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ক্ষিপ্ৰ ছেটিং।"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"বন্ধ স্ক্ৰীন।"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"কৰ্মস্থানৰ প্ৰ\'ফাইলৰ লক স্ক্ৰীন"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"বন্ধ কৰক"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"উজ্জ্বলতা"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ৰং বিপৰীতকৰণ"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"ৰং শুধৰণী"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"ফণ্টৰ আকাৰ"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ব্যৱহাৰকাৰী পৰিচালনা কৰক"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"সম্পন্ন কৰা হ’ল"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"বন্ধ কৰক"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"স্ক্ৰীন ৰেকৰ্ডিং"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"কোনো শিৰোনাম নাই"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ষ্টেণ্ডবাই"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ফণ্টৰ আকাৰ"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"সৰু কৰক"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"ডাঙৰ কৰক"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"বিবৰ্ধন ৱিণ্ড’"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"বিবৰ্ধন ৱিণ্ড’ৰ নিয়ন্ত্ৰণসমূহ"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"জুম ইন কৰক"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"কিবা ভুল হ’ল। পুনৰ চেষ্টা কৰক।"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"ল’ড হৈ আছে"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"টেবলেট"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"আপোনাৰ মিডিয়া কাষ্ট কৰি থকা হৈছে"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> কাষ্ট কৰি থকা হৈছে"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"সক্ৰিয় নহয়, এপ্‌টো পৰীক্ষা কৰক"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"বিচাৰি পোৱা নগ’ল"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"নিয়ন্ত্ৰণটো উপলব্ধ নহয়"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"সম্প্ৰচাৰ কৰিব নোৱাৰি"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ছেভ কৰিব নোৱাৰি। পুনৰ চেষ্টা কৰক।"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ছেভ কৰিব নোৱাৰি।"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"অতি কমেও ৪ টা বৰ্ণ ব্যৱহাৰ কৰক"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"১৬ টাতকৈ কম বৰ্ণ ব্যৱহাৰ কৰক"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ডৰ নম্বৰ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ক্লিপব’ৰ্ডলৈ বিল্ডৰ নম্বৰ প্ৰতিলিপি কৰা হ’ল।"</string>
     <string name="basic_status" msgid="2315371112182658176">"বাৰ্তালাপ খোলক"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• অতি কমেও এটা ডিভাইচ উপলব্ধ"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"শ্বৰ্টকাটটোত স্পৰ্শ কৰি ধৰি ৰাখক"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"বাতিল কৰক"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"এতিয়াই ফ্লিপ কৰক"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"উন্নত ছেল্ফিৰ বাবে ফ’নটো আনফ’ল্ড কৰক"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"উন্নত ছেল্ফিৰ বাবে সন্মুখৰ ডিছপ্লে’ ফ্লিপ কৰিবনে?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"অধিক ৰিজ’লিউশ্বনৰ বহল ফট’ৰ বাবে পিছফালে থকা কেমেৰাটো ব্যৱহাৰ কৰক।"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ এই স্ক্ৰীনখন অফ হ’ব"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"এতিয়াই স্ক্ৰীন সলনি কৰক"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"ফ’নটো আনফ’ল্ড কৰক"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"স্ক্ৰীন সলনি কৰিবনে?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"অধিক ৰিজ’লিউছনৰ বাবে, পিছফালৰ কেমেৰাটো ব্যৱহাৰ কৰক"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"অধিক ৰিজ’লিউছনৰ বাবে, ফ’নটো লুটিয়াই দিয়ক"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"জপাব পৰা ডিভাইচৰ জাপ খুলি থকা হৈছে"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"জপাব পৰা ডিভাইচৰ ওলোটাই থকা হৈছে"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> বেটাৰী বাকী আছে"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"কৰ্মস্থানৰ প্ৰ’ফাইললৈ সলনি কৰক"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"বন্ধ কৰক"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"লক স্ক্ৰীনৰ ছেটিং"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ৱাই-ফাই উপলব্ধ নহয়"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"কেমেৰা অৱৰোধ কৰা আছে"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"কেমেৰা আৰু মাইক্ৰ’ফ’ন অৱৰোধ কৰা আছে"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"মাইক্ৰ’ফ’ন অৱৰোধ কৰা আছে"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"অগ্ৰাধিকাৰ দিয়া ম’ড অন আছে"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-as/tiles_states_strings.xml b/packages/SystemUI/res/values-as/tiles_states_strings.xml
index 3145341..a9c3e3b 100644
--- a/packages/SystemUI/res/values-as/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-as/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"অফ আছে"</item>
     <item msgid="5966994759929723339">"অন আছে"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"উপলব্ধ নহয়"</item>
+    <item msgid="2478289035899842865">"অফ আছে"</item>
+    <item msgid="5137565285664080143">"অন আছে"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 77bf65b..c331241 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Bildiriş kölgəsi."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Tez ayarlar."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Kilid ekranı."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Ekran kilidi"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Qapadın"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Parlaqlıq"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Rəng inversiyası"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Rəng korreksiyası"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Şrift ölçüsü"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"İstifadəçiləri idarə edin"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Hazır"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Bağlayın"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ekran çəkimi"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Başlıq yoxdur"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Gözləmə rejimi"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Şrift ölçüsü"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Kiçildin"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Böyüdün"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Böyütmə Pəncərəsi"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Böyütmə Pəncərəsi Kontrolları"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Yaxınlaşdırın"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Xəta oldu. Yenə cəhd edin."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Yüklənir"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"planşet"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Medianız yayımlanır"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> yayımlanır"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Aktiv deyil, tətbiqi yoxlayın"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Tapılmadı"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Nəzarət əlçatan deyil"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Yayımlamaq mümkün deyil"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Yadda saxlamaq mümkün deyil. Yenə cəhd edin."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Yadda saxlamaq mümkün deyil."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Ən azı 4 simvoldan istifadə edin"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Maksimum 16 simvoldan istifadə edin"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Montaj nömrəsi"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versiya nömrəsi mübadilə buferinə kopyalandı."</string>
     <string name="basic_status" msgid="2315371112182658176">"Açıq söhbət"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ən azı bir cihaz əlçatandır"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Qısayola toxunub saxlayın"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Ləğv edin"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"İndi fırladın"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Daha yaxşı selfi üçün telefonu açın"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Daha yaxşı selfi üçün ön displeyə çevrilsin?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Daha yüksək ayırdetmə dəqiqliyi ilə daha geniş şəkil üçün arxaya baxan kameradan istifadə edin."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Bu ekran deaktiv ediləcək"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"İndi ekranları dəyişin"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Telefonu açın"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Ekranlar dəyişdirilsin?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Daha yüksək ayırdetmə dəqiqliyi üçün arxa kameradan istifadə edin"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Daha yüksək ayırdetmə dəqiqliyi üçün telefonu çevirin"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Qatlana bilən cihaz açılır"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Qatlana bilən cihaz fırladılır"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> enerji qalıb"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"İş profilinə keçin"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Bağlayın"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Kilid ekranı ayarları"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi əlçatan deyil"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera bloklanıb"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera və mikrofon bloklanıb"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon bloklanıb"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioritet rejimi aktivdir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az/tiles_states_strings.xml b/packages/SystemUI/res/values-az/tiles_states_strings.xml
index fb745b25..d973e4e 100644
--- a/packages/SystemUI/res/values-az/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-az/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Deaktiv"</item>
     <item msgid="5966994759929723339">"Aktiv"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Əlçatan deyil"</item>
+    <item msgid="2478289035899842865">"Deaktiv"</item>
+    <item msgid="5137565285664080143">"Aktiv"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 78812ae..3355feb 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -197,6 +197,7 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Prozor sa obaveštenjima."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Brza podešavanja."</string>
+    <string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"Brza podešavanja i traka sa obaveštenjima."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Zaključan ekran."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Zaključan ekran za posao"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Zatvori"</string>
@@ -257,6 +258,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Osvetljenost"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inverzija boja"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Korekcija boja"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Veličina fonta"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Upravljajte korisnicima"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Gotovo"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zatvori"</string>
@@ -777,6 +779,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"snimanje ekrana"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravnosti"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Veličina fonta"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Umanjite"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Uvećajte"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Prozor za uvećanje"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrole prozora za uvećanje"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Uvećajte"</string>
@@ -862,10 +867,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Došlo je do greške. Probajte ponovo."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Učitava se"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Prebacivanje medija"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Prebacuje se <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno. Vidite aplikaciju"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string>
@@ -903,6 +906,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Emitovanje nije uspelo"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Čuvanje nije uspelo. Probajte ponovo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Čuvanje nije uspelo."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Koristite bar 4 znaka"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Koristite manje od 16 znakova"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u privremenu memoriju."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otvorite konverzaciju"</string>
@@ -1022,11 +1027,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• da je dostupan barem jedan uređaj"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Dodirnite i zadržite prečicu"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Otkaži"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrni"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Otvorite telefon za bolji selfi"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Želite da obrnete na prednji ekran za bolji selfi?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Koristite zadnju kameru da biste snimili širu sliku sa višom rezolucijom."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ovaj ekran će se isključiti"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Zameni ekrane"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Otvorite telefon"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Želite da zamenite ekrane?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Za veću rezoluciju koristite zadnju kameru"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za veću rezoluciju obrnite telefon"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Uređaj na preklop se otvara"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Uređaj na preklop se obrće"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Preostalo je još<xliff:g id="PERCENTAGE">%s</xliff:g> baterije"</string>
@@ -1038,4 +1043,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Pređi na poslovni profil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Podešavanja zaključanog ekrana"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"WiFi nije dostupan"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera je blokirana"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera i mikrofon su blokirani"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon je blokiran"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioritetni režim je uključen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
index b69b064..32051ef 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Isključeno"</item>
     <item msgid="5966994759929723339">"Uključeno"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Nedostupno"</item>
+    <item msgid="2478289035899842865">"Isključeno"</item>
+    <item msgid="5137565285664080143">"Uključeno"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index b539e99..d2279be 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Цень апавяшчэння.."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Хуткія налады."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Экран блакіроўкі."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Экран блакіроўкі дзейнасці"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Закрыць"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Яркасць"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Інверсія колераў"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Карэкцыя колераў"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Памер шрыфту"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Кіраваць карыстальнікамі"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Гатова"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Закрыць"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"запіс экрана"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Без назвы"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Рэжым чакання"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Памер шрыфту"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Паменшыць"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Павялічыць"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Акно павелічэння"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Налады акна павелічэння"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Павялічыць маштаб"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Нешта пайшло не так. Паўтарыце спробу."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Ідзе загрузка"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"планшэт"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Трансляцыя мультымедыйнага змесціва"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Трансляцыя праграмы \"<xliff:g id="APP_LABEL">%1$s</xliff:g>\""</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Неактыўна, праверце праграму"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Не знойдзена"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Кіраванне недаступнае"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Не ўдалося запусціць трансляцыю"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не ўдалося захаваць. Паўтарыце спробу."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не ўдалося захаваць."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Скарыстайце не менш як 4 сімвалы"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Скарыстайце менш за 16 сімвалаў"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Нумар зборкі"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Нумар зборкі скапіраваны ў буфер абмену."</string>
     <string name="basic_status" msgid="2315371112182658176">"Адкрытая размова"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Даступная хаця б адна прылада."</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Дакраніцеся і ўтрымлівайце ярлык"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Скасаваць"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Пераключыць"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Каб атрымаць лепшае сэлфі, раскрыйце тэлефон"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Пераключыць на пярэдні дысплэй для лепшага сэлфі?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Каб зрабіць шырэйшае фота з больш высокай раздзяляльнасцю, скарыстайце заднюю камеру."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Гэты экран будзе выключаны"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Пераключыцца на іншы экран"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Раскрыйце тэлефон"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Пераключыцца на іншы экран?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Каб рабіць фота з больш высокай раздзяляльнасцю, выкарыстоўвайце заднюю камеру"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Каб зрабіць фота з больш высокай раздзяляльнасцю, павярніце тэлефон"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складная прылада ў раскладзеным выглядзе"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Перавернутая складная прылада"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Засталося зараду: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Пераключыцца на працоўны профіль"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрыць"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Налады экрана блакіроўкі"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-be/tiles_states_strings.xml b/packages/SystemUI/res/values-be/tiles_states_strings.xml
index 8fb2da2..e71c29b 100644
--- a/packages/SystemUI/res/values-be/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-be/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Выключана"</item>
     <item msgid="5966994759929723339">"Уключана"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Недаступна"</item>
+    <item msgid="2478289035899842865">"Выключана"</item>
+    <item msgid="5137565285664080143">"Уключана"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index a45ca4c..36b3c8b 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Падащ панел с известия."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Бързи настройки."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Заключване на екрана."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Заключен екран на служебния профил"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Затваряне"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Яркост"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Цветове: инверт."</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Корекция на цветове"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Размер на шрифта"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Управление на потребителите"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Готово"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Затваряне"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"записване на екрана"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Няма заглавие"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим на готовност"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Размер на шрифта"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Намаляване на размера"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Увеличаване на размера"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Прозорец за увеличение"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Контроли за прозореца за увеличение"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Увеличаване на мащаба"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Нещо се обърка. Опитайте отново."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Зарежда се"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"таблет"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Мултимедията се предава"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> се предава"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, проверете прилож."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Не е намерено"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Контролата не е налице"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Предаването не е възможно"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не може да се запази. Опитайте отново."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не може да се запази."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Използвайте поне 4 знака"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Използвайте по-малко от 16 знака"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер на компилацията"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Номерът на компилацията е копиран в буферната памет."</string>
     <string name="basic_status" msgid="2315371112182658176">"Отворен разговор"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Налице е поне едно устройство."</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Докоснете и задръжте прекия път"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Отказ"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Обръщане сега"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Отворете телефона за по-добро селфи"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Да се ползва ли предната камера за по-добро селфи?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Използвайте задната камера за по-широка снимка с по-висока разделителна способност."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Този екран ще се изключи"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Превключване на екраните сега"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Отворете телефона"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Да се превключи ли екранът?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"За по-висока разделителна способност използвайте задната камера"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"За по-висока разделителна способност обърнете телефона"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Разгъване на сгъваемо устройство"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Обръщане на сгъваемо устройство"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Оставаща батерия: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Превключване към служебния потребителски профил"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затваряне"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Настройки за заключения екран"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi не е налице"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Достъпът до камерата е блокиран"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Достъпът до камерата и микрофона е блокиран"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Достъпът до микрофона е блокиран"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Приоритетният режим е включен"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/tiles_states_strings.xml b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
index b85133b..24b41d2 100644
--- a/packages/SystemUI/res/values-bg/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Изкл."</item>
     <item msgid="5966994759929723339">"Вкл."</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Не е налице"</item>
+    <item msgid="2478289035899842865">"Изключено"</item>
+    <item msgid="5137565285664080143">"Включено"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 08b7ca4..0f3f00c 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"বিজ্ঞপ্তি শেড৷"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"দ্রুত সেটিংস৷"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"লক স্ক্রিন।"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"কর্মস্থলের স্ক্রিন লক"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"বন্ধ করুন"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"উজ্জ্বলতা"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"কালার ইনভার্সন"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"রঙ সংশোধন"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"ফন্ট সাইজ"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ব্যবহারকারীদের ম্যানেজ করুন"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"সম্পন্ন হয়েছে"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"বন্ধ করুন"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"স্ক্রিন রেকর্ডিং"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"কোনও শীর্ষক নেই"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"স্ট্যান্ডবাই"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ফন্ট সাইজ"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"আরও ছোট করুন"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"আরও বড় করুন"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"উইন্ডো বড় করে দেখা"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"উইন্ডো কন্ট্রোল বড় করে দেখা"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"বড় করুন"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"কোনও সমস্যা হয়েছে। আবার চেষ্টা করুন।"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"লোড করা হচ্ছে"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ট্যাবলেট"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"আপনার মিডিয়া কাস্ট করা"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> কাস্ট করা হচ্ছে"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"বন্ধ আছে, অ্যাপ চেক করুন"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"খুঁজে পাওয়া যায়নি"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"কন্ট্রোল উপলভ্য নেই"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"সম্প্রচার করা যাচ্ছে না"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"সেভ করা যাচ্ছে না। আবার চেষ্টা করুন।"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"সেভ করা যাচ্ছে না।"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"কমপক্ষে ৪টি অক্ষর ব্যবহার করুন"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"১৬টির চেয়ে কম অক্ষর ব্যবহার করুন"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ড নম্বর"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"বিল্ড নম্বর ক্লিপবোর্ডে কপি করা হয়েছে।"</string>
     <string name="basic_status" msgid="2315371112182658176">"খোলা কথোপকথন"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• অন্তত একটি ডিভাইস উপলভ্য"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"শর্টকাট টাচ করে ধরে রাখুন"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"বাতিল করুন"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"এখনই উল্টান"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"আরও ভাল সেলফির জন্য ফোন আনফোল্ড করা"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"আরও ভাল সেলফির জন্য সামনের ক্যামেরায় পাল্টাতে চান?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"আরও ভাল রেজোলিউশন সহ আরও বেশি ওয়াইড ছবির জন্য ব্যাক-ক্যামেরা ব্যবহার করুন।"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ এই স্ক্রিন বন্ধ হয়ে যাবে"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"এখন স্ক্রিন পাল্টান"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"ফোন আনফোল্ড করুন"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"স্ক্রিন পাল্টাবেন?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"আরও বেশি রেজোলিউশনের জন্য, রিয়ার ক্যামেরা ব্যবহার করুন"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"আরও বেশি রেজোলিউশনের জন্য, ফোন ফ্লিপ করুন"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ফোল্ড করা যায় এমন ডিভাইস খোলা হচ্ছে"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ফোল্ড করা যায় এমন ডিভাইস উল্টানো হচ্ছে"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ব্যাটারির চার্জ বাকি আছে"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"অফিস প্রোফাইলে পাল্টে নিন"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"বন্ধ করুন"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"লক স্ক্রিন সেটিংস"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bn/tiles_states_strings.xml b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
index d70afc0..59061c2 100644
--- a/packages/SystemUI/res/values-bn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"বন্ধ আছে"</item>
     <item msgid="5966994759929723339">"চালু আছে"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"উপলভ্য নেই"</item>
+    <item msgid="2478289035899842865">"বন্ধ আছে"</item>
+    <item msgid="5137565285664080143">"চালু আছে"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index e7a6006..823b7236 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -197,6 +197,7 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Obavještenja sa sjenčenjem."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Brze postavke."</string>
+    <string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"Brze postavke i zaslon obavijesti."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Zaključan ekran."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Zaključan ekran radnog profila"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Zatvori"</string>
@@ -257,6 +258,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Osvjetljenje"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inverzija boja"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Ispravka boja"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Veličina fonta"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Upravljajte korisnicima"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Gotovo"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zatvori"</string>
@@ -777,6 +779,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"snimanje ekrana"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje mirovanja"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Veličina fonta"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Smanjivanje"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Povećavanje"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Prozor za uvećavanje"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrole prozora za uvećavanje"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Uvećavanje"</string>
@@ -862,7 +867,7 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Nešto nije uredu. Pokušajte ponovo."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Učitavanje"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
-    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Emitiranje medijskih sadržaja"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Emitiranje medija"</string>
     <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Emitiranje aplikacije <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, vidite aplikaciju"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
@@ -901,6 +906,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nije moguće emitirati"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nije moguće sačuvati. Pokušajte ponovo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nije moguće sačuvati."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Koristite najmanje 4 znaka"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Koristite manje od 16 znakova"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u međumemoriju."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string>
@@ -1020,11 +1027,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Dostupan je najmanje jedan uređaj"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Dodirnite i zadržite prečicu"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Otkaži"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrni sada"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Raširite telefon za bolji selfi"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Obrnuti na prednji ekran radi boljeg selfija?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Koristite zadnju kameru za širu fotografiju veće rezolucije."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ekran će se isključiti"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Promijenite ekran sada"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Rasklopite telefon"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Promijeniti ekran?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Za višu rezoluciju koristite zadnju kameru"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za višu rezoluciju obrnite telefon"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Sklopivi uređaj se rasklapa"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Sklopivi uređaj se obrće"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Preostalo baterije: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1043,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Pređite na radni profil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Postavke zaključavanja ekrana"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"WiFi mreža nije dostupna"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera je blokirana"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera i mikrofon su blokirani"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon je blokiran"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Način rada Prioriteti je uključen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/tiles_states_strings.xml b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
index b69b064..32051ef 100644
--- a/packages/SystemUI/res/values-bs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Isključeno"</item>
     <item msgid="5966994759929723339">"Uključeno"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Nedostupno"</item>
+    <item msgid="2478289035899842865">"Isključeno"</item>
+    <item msgid="5137565285664080143">"Uključeno"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 109aeb7..d60722f 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Àrea de notificacions"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Configuració ràpida"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Pantalla de bloqueig"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Pantalla de bloqueig per a la feina"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Tanca"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brillantor"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversió de colors"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Correcció de color"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Cos de font"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gestiona els usuaris"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Fet"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Tanca"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"gravació de pantalla"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sense títol"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Cos de font"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Redueix"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Amplia"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Finestra d\'ampliació"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Finestra de controls d\'ampliació"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Amplia"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"S\'ha produït un error. Torna-ho a provar."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"S\'està carregant"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tauleta"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"S\'està emetent el contingut multimèdia"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"S\'està emetent <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactiu; comprova l\'aplicació"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"No s\'ha trobat"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"El control no està disponible"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"No es pot emetre"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"No es pot desar. Torna-ho a provar."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"No es pot desar."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Utilitza 4 caràcters com a mínim"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Utilitza menys de 16 caràcters"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilació"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"El número de compilació s\'ha copiat al porta-retalls."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversa oberta"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Almenys un dispositiu està disponible."</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantén premuda la drecera"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel·la"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Gira ara"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desplega el telèfon per fer una millor selfie"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Girar a pantalla frontal per fer millors selfies?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilitza la càmera posterior per obtenir una foto més àmplia amb una resolució més alta."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Aquesta pantalla s\'apagarà"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Canvia de pantalla ara"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Desplega el telèfon"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Vols canviar de pantalla?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Per a una resolució més alta, utilitza la càmera posterior"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Per a una resolució més alta, gira el telèfon"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositiu plegable desplegant-se"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositiu plegable girant"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Queda un <xliff:g id="PERCENTAGE">%s</xliff:g> de bateria"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Canvia al perfil de treball"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tanca"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Configuració pantalla de bloqueig"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ca/tiles_states_strings.xml b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
index aaf19c7..e99926c 100644
--- a/packages/SystemUI/res/values-ca/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Desactivat"</item>
     <item msgid="5966994759929723339">"Activat"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"No disponible"</item>
+    <item msgid="2478289035899842865">"Desactivat"</item>
+    <item msgid="5137565285664080143">"Activat"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index de48119..6662ca10 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Panel oznámení."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Rychlé nastavení."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Obrazovka uzamčení"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Obrazovka uzamčení pracovního profilu"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Zavřít"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Jas"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Převrácení barev"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Korekce barev"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Velikost písma"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Správa uživatelů"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Hotovo"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zavřít"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"nahrávání obrazovky"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez názvu"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Pohotovostní režim"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Velikost písma"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Zmenšit"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Zvětšit"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Zvětšovací okno"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Ovládací prvky zvětšovacího okna"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Přiblížit"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Vysílání se nezdařilo"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Uložení se nezdařilo. Zkuste to znovu."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Uložení se nezdařilo."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Heslo musí mít alespoň 4 znaky"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Použijte méně než 16 znaků"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo sestavení"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Číslo sestavení bylo zkopírováno do schránky."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otevřít konverzaci"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Je k dispozici alespoň jedno zařízení"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Podržte zkratku"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Zrušit"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Otočit"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Rozložte telefon, selfie bude lepší"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Otočit na přední displej pro lepší selfie?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Pomocí zadního fotoaparátu pořiďte širší fotku s vyšším rozlišením."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Tato obrazovka se vypne"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Přepnout obrazovky"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Rozevřete telefon"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Přepnout obrazovky?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Pomocí zadního fotoaparátu dosáhnete vyššího rozlišení"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Otočte telefon, abyste dosáhli vyššího rozlišení"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozkládání rozkládacího zařízení"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Otáčení rozkládacího zařízení"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Zbývá <xliff:g id="PERCENTAGE">%s</xliff:g> baterie"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Přepnout na pracovní profil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zavřít"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Nastavení obrazovky uzamčení"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Síť Wi-Fi není dostupná"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera je blokována"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera a mikrofon jsou blokovány"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon je blokován"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Režim priority je zapnutý"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/tiles_states_strings.xml b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
index 64e83e0..6359f94 100644
--- a/packages/SystemUI/res/values-cs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Vypnuto"</item>
     <item msgid="5966994759929723339">"Zapnuto"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Nedostupné"</item>
+    <item msgid="2478289035899842865">"Vypnuto"</item>
+    <item msgid="5137565285664080143">"Zapnuto"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 73ec8f5..ee9d8a6 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Notifikationspanel."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Kvikmenu."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Låseskærm."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Låseskærm til arbejde"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Luk"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Lysstyrke"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Ombytning af farver"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Farvekorrigering"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Skriftstørrelse"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Administrer brugere"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Udfør"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Luk"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"skærmoptagelse"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Ingen titel"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Skriftstørrelse"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Formindsk"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Forstør"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Vindue med forstørrelse"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Vindue med forstørrelsesstyring"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom ind"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Noget gik galt. Prøv igen."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Indlæser"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Caster medie"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Caster <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Tjek appen"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ikke fundet"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Styringselement ikke tilgængeligt"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Der kan ikke udsendes en fællesbesked"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Der kan ikke gemmes. Prøv igen."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Der kan ikke gemmes."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Angiv mindst 4 tegn"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Angiv højst 16 tegn"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummeret blev kopieret til udklipsholderen."</string>
     <string name="basic_status" msgid="2315371112182658176">"Åben samtale"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Mindst én enhed er tilgængelig"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Hold fingeren på genvejen"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuller"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Vend nu"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Fold telefonen ud for at tage en bedre selfie"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vil du bruge frontkameraet for at få bedre selfie?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Brug bagsidekameraet for at få et bredere billede med højere opløsning."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Denne skærm slukkes"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Skift skærm nu"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Fold telefonen ud"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Vil du skifte skærm?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Brug kameraet på bagsiden for at få højere opløsning"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Vend telefonen for at få højere opløsning"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldbar enhed foldes ud"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldbar enhed vendes om"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batteri tilbage"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Skift til arbejdsprofil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Luk"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Indstillinger for låseskærm"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-da/tiles_states_strings.xml b/packages/SystemUI/res/values-da/tiles_states_strings.xml
index f0132dc..1daed4c 100644
--- a/packages/SystemUI/res/values-da/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-da/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Fra"</item>
     <item msgid="5966994759929723339">"Til"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Ikke tilgængelig"</item>
+    <item msgid="2478289035899842865">"Fra"</item>
+    <item msgid="5137565285664080143">"Til"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index c3fb287e..66fa231 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Benachrichtigungsleiste"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Schnelleinstellungen"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Sperrbildschirm"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Sperrbildschirm für Arbeitsprofil"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Schließen"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Helligkeit"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Farbumkehr"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Farbkorrektur"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Schriftgröße"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Nutzer verwalten"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Fertig"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Schließen"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"Bildschirmaufzeichnung"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Kein Titel"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Schriftgröße"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Verkleinern"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Vergrößern"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Vergrößerungsfenster"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Einstellungen für Vergrößerungsfenster"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Heranzoomen"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Ein Fehler ist aufgetreten. Versuch es noch einmal."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Wird geladen"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"Tablet"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Medien werden gestreamt"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> wird gestreamt"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv – sieh in der App nach"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nicht gefunden"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Steuerelement nicht verfügbar"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Übertragung nicht möglich"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Speichern nicht möglich. Versuche es noch einmal."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Speichern nicht möglich."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Gib mindestens vier Zeichen ein"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Maximal 16 Zeichen möglich"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build-Nummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build-Nummer in Zwischenablage kopiert."</string>
     <string name="basic_status" msgid="2315371112182658176">"Offene Unterhaltung"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Mindestens ein Gerät ist verfügbar"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Verknüpfung berühren &amp; halten"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Abbrechen"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Jetzt umdrehen"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Für ein besseres Selfie Smartphone öffnen"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Für ein besseres Selfie Frontbildschirm verwenden?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Verwende die Rückkamera, um Fotos mit einem weiteren Blickwinkel und höherer Auflösung aufzunehmen."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Dieses Display wird dann ausgeschaltet"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Bildschirm jetzt wechseln"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Smartphone auffalten"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Bildschirm wechseln?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Mit der Rückkamera lassen sich Fotos mit höherer Auflösung aufnehmen"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Smartphone umdrehen, um Fotos mit höherer Auflösung aufzunehmen"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Faltbares Gerät wird geöffnet"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Faltbares Gerät wird umgeklappt"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Akku bei <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Zum Arbeitsprofil wechseln"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Schließen"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Sperrbildschirm-Einstellungen"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-de/tiles_states_strings.xml b/packages/SystemUI/res/values-de/tiles_states_strings.xml
index bc50e16..9a08747 100644
--- a/packages/SystemUI/res/values-de/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-de/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Aus"</item>
     <item msgid="5966994759929723339">"An"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Nicht verfügbar"</item>
+    <item msgid="2478289035899842865">"Aus"</item>
+    <item msgid="5137565285664080143">"An"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index dacd2f0..84d6610 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Πλαίσιο σκίασης ειδοποιήσεων."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Γρήγορες ρυθμίσεις."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Οθόνη κλειδώματος"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Οθόνη κλειδωμένης εργασίας"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Κλείσιμο"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Φωτεινότητα"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Αντιστροφή χρωμάτων"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Διόρθωση χρωμάτων"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Μέγεθος γραμματοσειράς"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Διαχείριση χρηστών"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Τέλος"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Κλείσιμο"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"εγγραφή οθόνης"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Χωρίς τίτλο"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Κατάσταση αναμονής"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Μέγεθος γραμματοσειράς"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Να μικρύνουν"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Να μεγαλώσουν"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Παράθυρο μεγέθυνσης"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Στοιχεία ελέγχου παραθύρου μεγέθυνσης"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Μεγέθυνση"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Δεν είναι δυνατή η μετάδοση"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Δεν είναι δυνατή η αποθήκευση. Δοκιμάστε ξανά."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Δεν είναι δυνατή η αποθήκευση."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Χρησιμοποιήστε τουλάχιστον 4 χαρακτήρες"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Χρησιμοποιήστε λιγότερους από 16 χαρακτήρες"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Αριθμός έκδοσης"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Ο αριθμός έκδοσης αντιγράφηκε στο πρόχειρο."</string>
     <string name="basic_status" msgid="2315371112182658176">"Άνοιγμα συνομιλίας"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Είναι διαθέσιμη τουλάχιστον μία συσκευή"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Παρατεταμένο άγγιγμα συντόμευσης"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Ακύρωση"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Αναστροφή τώρα"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Ξεδιπλώστε το τηλέφωνο για καλύτερη selfie"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Αναστροφή στην μπροστ. οθόνη για καλύτερη selfie;"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Χρησιμοποιήστε την πίσω κάμερα για να βγάλετε μια φωτογραφία με μεγαλύτερο εύρος και υψηλότερη ανάλυση."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* Αυτή η οθόνη θα απενεργοποιηθεί"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Εναλλαγή οθονών τώρα"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Ξεδιπλώστε το τηλέφωνο"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Αλλαγή οθονών;"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Για υψηλότερη ανάλυση, χρησιμοποιήστε την πίσω κάμερα"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Για υψηλότερη ανάλυση, αναστρέψτε το τηλέφωνο"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Αναδιπλούμενη συσκευή που ξεδιπλώνει"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Αναδιπλούμενη συσκευή που διπλώνει"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Απομένει το <xliff:g id="PERCENTAGE">%s</xliff:g> της μπαταρίας"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Εναλλαγή σε προφίλ εργασίας"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Κλείσιμο"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Ρυθμίσεις κλειδώματος οθόνης"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Δεν υπάρχει διαθέσιμο δίκτυο Wi-Fi"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Η κάμερα έχει αποκλειστεί"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Η κάμερα και το μικρόφωνο έχουν αποκλειστεί"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Το μικρόφωνο έχει αποκλειστεί"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Η λειτουργία προτεραιότητας είναι ενεργοποιημένη"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/tiles_states_strings.xml b/packages/SystemUI/res/values-el/tiles_states_strings.xml
index 352af39..4d94515 100644
--- a/packages/SystemUI/res/values-el/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-el/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Ανενεργό"</item>
     <item msgid="5966994759929723339">"Ενεργό"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Μη διαθέσιμο"</item>
+    <item msgid="2478289035899842865">"Ανενεργό"</item>
+    <item msgid="5137565285664080143">"Ενεργό"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 5f6a481..59eaeab3 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -197,6 +197,7 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Notification shade."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Quick settings."</string>
+    <string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"Quick Settings and notification shade."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lock screen."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Work lock screen"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Close"</string>
@@ -257,6 +258,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brightness"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Colour inversion"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Colour correction"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Font size"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Manage users"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Done"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Close"</string>
@@ -777,6 +779,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"screen recording"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Font size"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Make smaller"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Make larger"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Magnification window"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification window controls"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom in"</string>
@@ -901,6 +906,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Use at least four characters"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Use fewer than 16 characters"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -1020,11 +1027,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch &amp; hold shortcut"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Flip to front display for a better selfie?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use the rear-facing camera for a wider photo with higher resolution."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Switch screens now"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Unfold phone"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Switch screens?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"For higher resolution, use the rear camera"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string>
@@ -1036,4 +1043,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Switch to work profile"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Lock screen settings"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi not available"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Camera is blocked"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Camera and microphone blocked"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Microphone is blocked"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Priority mode on"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
index 56cdbef..0cf2868 100644
--- a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Off"</item>
     <item msgid="5966994759929723339">"On"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Unavailable"</item>
+    <item msgid="2478289035899842865">"Off"</item>
+    <item msgid="5137565285664080143">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index bd3fa83..cbc9d6a 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -197,6 +197,7 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Notification shade."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Quick settings."</string>
+    <string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"Quick settings and Notification shade."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lock screen."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Work lock screen"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Close"</string>
@@ -257,6 +258,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brightness"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Color inversion"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Color correction"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Font size"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Manage users"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Done"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Close"</string>
@@ -777,6 +779,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"screen recording"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Font Size"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Make smaller"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Make larger"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Magnification Window"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification Window Controls"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom in"</string>
@@ -901,6 +906,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Use at least 4 characters"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Use fewer than 16 characters"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -1020,11 +1027,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch &amp; hold shortcut"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Flip to front display for a better selfie?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use the rear-facing camera for a wider photo with higher resolution."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Switch screens now"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Unfold phone"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Switch screens?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"For higher resolution, use the rear camera"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string>
@@ -1036,4 +1043,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Switch to work profile"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Lock screen settings"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi not available"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Camera blocked"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Camera and microphone blocked"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Microphone blocked"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Priority mode on"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
index 56cdbef..0cf2868 100644
--- a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Off"</item>
     <item msgid="5966994759929723339">"On"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Unavailable"</item>
+    <item msgid="2478289035899842865">"Off"</item>
+    <item msgid="5137565285664080143">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 5f6a481..59eaeab3 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -197,6 +197,7 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Notification shade."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Quick settings."</string>
+    <string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"Quick Settings and notification shade."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lock screen."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Work lock screen"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Close"</string>
@@ -257,6 +258,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brightness"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Colour inversion"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Colour correction"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Font size"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Manage users"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Done"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Close"</string>
@@ -777,6 +779,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"screen recording"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Font size"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Make smaller"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Make larger"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Magnification window"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification window controls"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom in"</string>
@@ -901,6 +906,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Use at least four characters"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Use fewer than 16 characters"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -1020,11 +1027,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch &amp; hold shortcut"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Flip to front display for a better selfie?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use the rear-facing camera for a wider photo with higher resolution."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Switch screens now"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Unfold phone"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Switch screens?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"For higher resolution, use the rear camera"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string>
@@ -1036,4 +1043,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Switch to work profile"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Lock screen settings"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi not available"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Camera is blocked"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Camera and microphone blocked"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Microphone is blocked"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Priority mode on"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
index 56cdbef..0cf2868 100644
--- a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Off"</item>
     <item msgid="5966994759929723339">"On"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Unavailable"</item>
+    <item msgid="2478289035899842865">"Off"</item>
+    <item msgid="5137565285664080143">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 5f6a481..59eaeab3 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -197,6 +197,7 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Notification shade."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Quick settings."</string>
+    <string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"Quick Settings and notification shade."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lock screen."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Work lock screen"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Close"</string>
@@ -257,6 +258,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brightness"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Colour inversion"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Colour correction"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Font size"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Manage users"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Done"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Close"</string>
@@ -777,6 +779,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"screen recording"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"No title"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Font size"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Make smaller"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Make larger"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Magnification window"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Magnification window controls"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom in"</string>
@@ -901,6 +906,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Use at least four characters"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Use fewer than 16 characters"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -1020,11 +1027,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• At least one device is available"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch &amp; hold shortcut"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Flip now"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Unfold phone for a better selfie"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Flip to front display for a better selfie?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use the rear-facing camera for a wider photo with higher resolution."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ This screen will turn off"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Switch screens now"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Unfold phone"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Switch screens?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"For higher resolution, use the rear camera"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"For higher resolution, flip the phone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldable device being unfolded"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldable device being flipped around"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> battery remaining"</string>
@@ -1036,4 +1043,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Switch to work profile"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Lock screen settings"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi not available"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Camera is blocked"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Camera and microphone blocked"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Microphone is blocked"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Priority mode on"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
index 56cdbef..0cf2868 100644
--- a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Off"</item>
     <item msgid="5966994759929723339">"On"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Unavailable"</item>
+    <item msgid="2478289035899842865">"Off"</item>
+    <item msgid="5137565285664080143">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 93d48ef..e718dde 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -197,6 +197,7 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‎‏‎‏‎‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎Notification shade.‎‏‎‎‏‎"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‎‎‏‎‏‏‎Quick settings.‎‏‎‎‏‎"</string>
+    <string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‎‎‎‏‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‏‏‏‏‎‏‏‎‎‎‎Quick settings and Notification shade.‎‏‎‎‏‎"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‎‏‎‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‏‎Lock screen.‎‏‎‎‏‎"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‏‏‏‎Work lock screen‎‏‎‎‏‎"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‎‏‎‎‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎Close‎‏‎‎‏‎"</string>
@@ -257,6 +258,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‏‎‏‎‎‎‏‎‏‎‎‎Brightness‎‏‎‎‏‎"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎Color inversion‎‏‎‎‏‎"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‎‎‎‏‏‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‎‏‎‎‎‎Color correction‎‏‎‎‏‎"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‎‏‏‎‎‏‎‎‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‎Font size‎‏‎‎‏‎"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‎Manage users‎‏‎‎‏‎"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‎‎‎‏‎Done‎‏‎‎‏‎"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‎‏‎‎‎‏‎Close‎‏‎‎‏‎"</string>
@@ -777,6 +779,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎screen recording‎‏‎‎‏‎"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎No title‎‏‎‎‏‎"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‎‏‎Standby‎‏‎‎‏‎"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎Font Size‎‏‎‎‏‎"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‏‏‎‏‏‏‎‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‎‏‏‎‏‎‏‎‎‎‎Make smaller‎‏‎‎‏‎"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‏‎‎‏‎‎‎‎‎‏‎‏‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‎‎‎Make larger‎‏‎‎‏‎"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‎‎‎‎‎‎‎‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‏‏‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‏‎Magnification Window‎‏‎‎‏‎"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎Magnification Window Controls‎‏‎‎‏‎"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‎‏‎‏‎‎‎‏‎‎‏‎Zoom in‎‏‎‎‏‎"</string>
@@ -901,6 +906,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎Can’t broadcast‎‏‎‎‏‎"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‏‎‏‏‎‎‏‎Can’t save. Try again.‎‏‎‎‏‎"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‎‎‏‏‎Can’t save.‎‏‎‎‏‎"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎‎‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‎Use at least 4 characters‎‏‎‎‏‎"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎Use fewer than 16 characters‎‏‎‎‏‎"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎Build number‎‏‎‎‏‎"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‎Build number copied to clipboard.‎‏‎‎‏‎"</string>
     <string name="basic_status" msgid="2315371112182658176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‎‎‎‎‎Open conversation‎‏‎‎‏‎"</string>
@@ -1020,11 +1027,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎• At least one device is available‎‏‎‎‏‎"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‎‏‏‎‎‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‎Touch &amp; hold shortcut‎‏‎‎‏‎"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎Cancel‎‏‎‎‏‎"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‏‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‎Flip now‎‏‎‎‏‎"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎Unfold phone for a better selfie‎‏‎‎‏‎"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‎‎‎‏‎‎‎‏‎‏‎Flip to front display for a better selfie?‎‏‎‎‏‎"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‏‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‎‏‎‏‏‏‎‎‎‎‎Use the rear-facing camera for a wider photo with higher resolution.‎‏‎‎‏‎"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‎"<b>"‎‏‎‎‏‏‏‎✱ This screen will turn off‎‏‎‎‏‏‎"</b>"‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‎‏‏‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‎‎‏‏‎Switch screens now‎‏‎‎‏‎"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‎‏‎‎‎‎‎‎‏‏‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‎‎Unfold phone‎‏‎‎‏‎"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‏‎‏‎‎‎‎‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‎‎‏‎‏‎‏‎‏‏‏‏‏‎‏‏‏‎Switch screens?‎‏‎‎‏‎"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‎‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎‎‎‎‎‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‏‏‎For higher resolution, use the rear camera‎‏‎‎‏‎"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‏‎‎‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‏‎‎‏‎For higher resolution, flip the phone‎‏‎‎‏‎"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎Foldable device being unfolded‎‏‎‎‏‎"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‎Foldable device being flipped around‎‏‎‎‏‎"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‏‎‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%s</xliff:g>‎‏‎‎‏‏‏‎ battery remaining‎‏‎‎‏‎"</string>
@@ -1036,4 +1043,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎‎‏‎‎‏‎‎‎Switch to work profile‎‏‎‎‏‎"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‎‎‏‎‏‏‏‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‎Close‎‏‎‎‏‎"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‎‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‎‎‏‏‎Lock screen settings‎‏‎‎‏‎"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‎‎‎Wi-Fi not available‎‏‎‎‏‎"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‎‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‎‏‎‎Camera blocked‎‏‎‎‏‎"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‏‎‎‏‎‎‎Camera and microphone blocked‎‏‎‎‏‎"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎Microphone blocked‎‏‎‎‏‎"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‎Priority mode on‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
index 3a8e34c..b9c8e5f 100644
--- a/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‎‎‎‎Off‎‏‎‎‏‎"</item>
     <item msgid="5966994759929723339">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‏‎‏‏‎On‎‏‎‎‏‎"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎Unavailable‎‏‎‎‏‎"</item>
+    <item msgid="2478289035899842865">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‏‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎‎‎‏‎‎‏‏‎‎‎‏‎Off‎‏‎‎‏‎"</item>
+    <item msgid="5137565285664080143">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‎‏‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‏‏‏‏‎On‎‏‎‎‏‎"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 2e179de..020b9e5 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Pantalla de notificaciones"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Configuración rápida"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Pantalla de bloqueo"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Pantalla bloqueada del perfil de trabajo"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Cerrar"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brillo"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Invertir colores"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Corregir colores"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Tamaño de la fuente"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Administrar usuarios"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Listo"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Cerrar"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"Grabación de pant."</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sin título"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Tamaño de fuente"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Reducir tamaño"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Aumentar tamaño"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Ventana de ampliación"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Controles de ampliación de la ventana"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Acercar"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Se produjo un error. Vuelve a intentarlo."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Cargando"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Transmitiendo tu contenido multimedia"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Transmitiendo <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Verifica la app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"No se encontró"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"El control no está disponible"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Error al iniciar transmisión"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"No se puede guardar. Vuelve a intentarlo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"No se puede guardar."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Usa al menos 4 caracteres"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Usa menos de 16 caracteres"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Se copió el número de compilación en el portapapeles."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Hay al menos un dispositivo disponible."</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantener presionado atajo"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Girar ahora"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Despliega el teléfono para tomar una selfie mejor"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"¿Girar a pantalla frontal para mejores selfies?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Usa la cámara trasera para tomar una foto más amplia y con mejor resolución."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta pantalla se apagará"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Cambiar de pantalla ahora"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Desplegar teléfono"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"¿Quieres cambiar de pantalla?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Para obtener una resolución más alta, usa la cámara posterior"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para obtener una resolución más alta, gira el teléfono"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable siendo desplegado"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo plegable siendo girado"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> de batería restante"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Cambiar al perfil de trabajo"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Cerrar"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Config. de pantalla de bloqueo"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
index 89ee62d..bb3983b 100644
--- a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"No"</item>
     <item msgid="5966994759929723339">"Sí"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"No disponible"</item>
+    <item msgid="2478289035899842865">"Desactivado"</item>
+    <item msgid="5137565285664080143">"Activado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 2d8f098..c8e9b23 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Pantalla de notificaciones"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Ajustes rápidos"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Pantalla de bloqueo."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Pantalla de bloqueo para el perfil de trabajo"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Cerrar"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brillo"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Invertir colores"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Corrección de color"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Tamaño de fuente"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gestionar usuarios"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Hecho"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Cerrar"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"grabación de pantalla"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sin título"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Tamaño de fuente"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Reducir tamaño"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Aumentar tamaño"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Ventana de ampliación"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Ventana de controles de ampliación"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Ampliar"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Se ha producido un error. Inténtalo de nuevo."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Cargando"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Enviando tu contenido multimedia"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Enviando <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo, comprobar aplicación"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"No se ha encontrado"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Control no disponible"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"No se puede emitir"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"No se puede guardar. Inténtalo de nuevo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"No se puede guardar."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Usa 4 caracteres como mínimo"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Usa menos de 16 caracteres"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número de compilación copiado en el portapapeles."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Al menos un dispositivo debe estar disponible"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantén pulsado el acceso directo"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Usar ahora"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Despliega el teléfono para hacer un selfie mejor"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"¿Usar pantalla frontal para hacer mejores selfies?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Usa la cámara trasera para hacer fotos más amplias y con mayor resolución."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta pantalla se apagará"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Cambia de pantalla ahora"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Abre el teléfono"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"¿Cambiar de pantalla?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Para una mayor resolución, usa la cámara trasera"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para una mayor resolución, gira el teléfono"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable desplegándose"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo plegable mostrado desde varios ángulos"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Batería restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Cambiar al perfil de trabajo"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Cerrar"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Ajustes de pantalla de bloqueo"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml
index fe4cbed..7451e6b 100644
--- a/packages/SystemUI/res/values-es/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Desactivado"</item>
     <item msgid="5966994759929723339">"Activado"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"No disponible"</item>
+    <item msgid="2478289035899842865">"Desactivado"</item>
+    <item msgid="5137565285664080143">"Activado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index a983a7a..a46f53d 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Märguande vari."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Kiirseaded."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Kuva lukustamine."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Töö lukustuskuva"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Sulgemine"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Heledus"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Värvide ümberpööramine"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Värviparandus"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Fondi suurus"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Kasutajate haldamine"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Valmis"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Sule"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ekraanikuva salvest."</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Pealkiri puudub"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ooterežiim"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Fondi suurus"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Vähendamine"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Suurendamine"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Suurendamisaken"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Suurendamisakna juhtelemendid"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Suumi sisse"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Midagi läks valesti. Proovige uuesti."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Laadimine"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tahvelarvuti"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Teie meedia ülekandmine"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Rakenduse <xliff:g id="APP_LABEL">%1$s</xliff:g> ülekandmine"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Passiivne, vaadake rakendust"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ei leitud"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Juhtelement pole saadaval"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ei saa üle kanda"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ei saa salvestada. Proovige uuesti."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ei saa salvestada."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Kasutage vähemalt 4 tähemärki"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Kasutage vähem kui 16 tähemärki"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Järgunumber"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Järgunumber kopeeriti lõikelauale."</string>
     <string name="basic_status" msgid="2315371112182658176">"Avage vestlus"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Vähemalt üks seade on saadaval"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pikalt puudutamise otsetee"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Tühista"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Pööra kohe ümber"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Voltige telefon parema selfi jaoks lahti"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Kas kasutada parema selfi jaoks esikaamerat?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Kasutage tagakülje kaamerat, et jäädvustada suurema eraldusvõimega laiem foto."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ See ekraan lülitatakse välja"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Vaheta ekraane kohe"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Telefoni lahtivoltimine"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Kas vahetada ekraane?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Suurema eraldusvõime saavutamiseks kasutage tagakaamerat"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Suurema eraldusvõime saavutamiseks pöörake telefon ümber"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Volditava seadme lahtivoltimine"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Volditava seadme ümberpööramine"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Akutase on <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Lülitu tööprofiilile"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sule"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Lukustuskuva seaded"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-et/tiles_states_strings.xml b/packages/SystemUI/res/values-et/tiles_states_strings.xml
index 07eddef..6a9edbb 100644
--- a/packages/SystemUI/res/values-et/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-et/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Väljas"</item>
     <item msgid="5966994759929723339">"Sees"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Pole saadaval"</item>
+    <item msgid="2478289035899842865">"Väljas"</item>
+    <item msgid="5137565285664080143">"Sees"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 2cd0ced..53ec95e 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Jakinarazpenen panela."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Ezarpen bizkorrak."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Pantaila blokeatzeko aukera."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Laneko pantaila blokeatua"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Itxi"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Distira"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Kolore-alderantzikatzea"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Koloreen zuzenketa"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Letra-tamaina"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Kudeatu erabiltzaileak"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Eginda"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Itxi"</string>
@@ -777,6 +780,12 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"pantaila-grabaketa"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Ez du izenik"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Egonean"</string>
+    <!-- no translation found for font_scaling_dialog_title (6273107303850248375) -->
+    <skip />
+    <!-- no translation found for font_scaling_smaller (1012032217622008232) -->
+    <skip />
+    <!-- no translation found for font_scaling_larger (5476242157436806760) -->
+    <skip />
     <string name="magnification_window_title" msgid="4863914360847258333">"Lupa-leihoa"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Lupa-leihoaren aukerak"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Handitu"</string>
@@ -862,10 +871,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Arazoren bat izan da. Saiatu berriro."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Kargatzen"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tableta"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Multimedia-edukia igortzen"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> aplikazioa igortzen"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktibo; egiaztatu aplikazioa"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ez da aurkitu"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Ez dago erabilgarri kontrolatzeko aukera"</string>
@@ -903,6 +910,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ezin da iragarri"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ezin da gorde. Saiatu berriro."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ezin da gorde."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Erabili lau karaktere gutxienez"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Erabili 16 karaktere baino gutxiago"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Konpilazio-zenbakia"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Kopiatu da konpilazio-zenbakia arbelean."</string>
     <string name="basic_status" msgid="2315371112182658176">"Elkarrizketa irekia"</string>
@@ -1022,11 +1031,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Gutxienez gailu bat erabilgarri dago."</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Eduki sakatuta lasterbidea"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Utzi"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Irauli"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Ireki telefonoa autoargazki hobeak ateratzeko"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Telefonoa irauli nahi duzu autoargazki hobeak ateratzeko?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Erabili atzeko kamera kalitate handiagoko argazki zabalago bat ateratzeko."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Pantaila itzali egingo da"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Aldatu pantaila batetik bestera"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Ireki telefonoa"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Pantaila batetik bestera aldatu nahi duzu?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Erabili atzeko kamera bereizmen handiago a lortzeko"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Irauli telefonoa bereizmen handiago a lortzeko"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Gailu tolesgarria zabaltzen"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Gailu tolesgarria biratzen"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Bateriaren <xliff:g id="PERCENTAGE">%s</xliff:g> geratzen da"</string>
@@ -1038,4 +1047,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Aldatu laneko profilera"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Itxi"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Pantaila blokeatuaren ezarpenak"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi-konexioa ez dago erabilgarri"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera blokeatuta dago"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera eta mikrofonoa blokeatuta daude"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofonoa blokeatuta dago"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Lehentasun modua aktibatuta dago"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/tiles_states_strings.xml b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
index 3bf49c8..d023076 100644
--- a/packages/SystemUI/res/values-eu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Desaktibatuta"</item>
     <item msgid="5966994759929723339">"Aktibatuta"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Ez dago erabilgarri"</item>
+    <item msgid="2478289035899842865">"Desaktibatuta"</item>
+    <item msgid="5137565285664080143">"Aktibatuta"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 3285150..938bc82 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -93,7 +93,7 @@
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"مرز سمت راست <xliff:g id="PERCENT">%1$d</xliff:g> درصد"</string>
     <string name="screenshot_work_profile_notification" msgid="203041724052970693">"در برنامه <xliff:g id="APP">%1$s</xliff:g> در نمایه کاری ذخیره شد"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
-    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> این نماگرفت را تشخیص داد."</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"‫«<xliff:g id="APPNAME">%1$s</xliff:g>» این نماگرفت را تشخیص داد."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> و سایر برنامه‌های باز این نماگرفت را تشخیص دادند."</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ضبط‌کننده صفحه‌نمایش"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"درحال پردازش ضبط صفحه‌نمایش"</string>
@@ -187,8 +187,8 @@
     <string name="accessibility_battery_level" msgid="5143715405241138822">"باتری <xliff:g id="NUMBER">%d</xliff:g> درصد."</string>
     <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"درصد شارژ باتری: <xliff:g id="PERCENTAGE">%1$d</xliff:g>، <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"در حال شارژ باتری، <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> درصد"</string>
-    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"درصد شارژ باتری: <xliff:g id="PERCENTAGE">%d</xliff:g>، شارژ شدن برای محافظت از باتری موقتاً متوقف شد."</string>
-    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"درصد شارژ باتری: <xliff:g id="PERCENTAGE">%1$d</xliff:g>، <xliff:g id="TIME">%2$s</xliff:g>، شارژ شدن برای محافظت از باتری موقتاً متوقف شد."</string>
+    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"شارژ باتری <xliff:g id="PERCENTAGE">%d</xliff:g> درصد است. شارژ شدن برای محافظت از باتری موقتاً متوقف شد."</string>
+    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"شارژ باتری <xliff:g id="PERCENTAGE">%1$d</xliff:g> درصد، <xliff:g id="TIME">%2$s</xliff:g>. شارژ شدن برای محافظت از باتری موقتاً متوقف شد."</string>
     <string name="accessibility_overflow_action" msgid="8555835828182509104">"دیدن همه اعلان‌ها"</string>
     <string name="accessibility_tty_enabled" msgid="1123180388823381118">"تله‌تایپ فعال شد."</string>
     <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"زنگ لرزشی."</string>
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"مجموعه اعلان."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"تنظیمات سریع."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"صفحه قفل."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"صفحه قفل کاری"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"بستن"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"روشنایی"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"وارونگی رنگ"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"تصحیح رنگ"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"اندازه قلم"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"مدیریت کاربران"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"تمام"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"بستن"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ضبط صفحه‌نمایش"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"بدون عنوان"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"آماده‌به‌کار"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"اندازه قلم"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"کوچک‌تر کردن"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"بزرگ‌تر کردن"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"پنجره درشت‌نمایی"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"کنترل‌های پنجره درشت‌نمایی"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"زوم‌پیش کردن"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"مشکلی پیش آمد. دوباره امتحان کنید."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"درحال بار کردن"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"رایانه لوحی"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"پخش محتوای رسانه‌ها"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"پخش محتوای <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"غیرفعال، برنامه را بررسی کنید"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"پیدا نشد"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"کنترل دردسترس نیست"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"همه‌فرستی انجام نشد"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ذخیره نشد. دوباره امتحان کنید."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ذخیره نشد."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"حداقل از ۴ نویسه استفاده کنید"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"از کمتر از ۱۶ نویسه استفاده کنید"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"شماره ساخت"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"شماره ساخت در بریده‌دان کپی شد."</string>
     <string name="basic_status" msgid="2315371112182658176">"باز کردن مکالمه"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• حداقل یک دستگاه دردسترس باشد"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"میان‌بر را لمس کنید و نگه دارید"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"لغو کردن"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"اکنون چرخانده شود"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"برای خویش‌گرفت بهتر، تلفن را باز کنید"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"برای خویش‌گرفت بهتر، از نمایشگر جلو استفاده شود؟"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"برای عکسی عریض‌تر با وضوح بالاتر، از دوربین عقب استفاده کنید."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ این صفحه‌نمایش خاموش خواهد شد"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"صفحه‌ها اکنون جابه‌جا می‌شود"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"باز کردن تلفن"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"صفحه‌ها جابه‌جا شود؟"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"برای وضوح بیشتر، از دوربین پشت استفاده کنید"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"برای وضوح بیشتر، تلفن را برگردانید"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"دستگاه تاشو درحال باز شدن"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"دستگاه تاشو درحال چرخش به اطراف"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> باتری باقی مانده است"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"رفتن به نمایه کاری"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"بستن"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"تنظیمات صفحه قفل"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"‏Wi-Fi دردسترس نیست"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"دوربین مسدود شده است"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"دوربین و میکروفون مسدود شده‌اند"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"میکروفون مسدود شده است"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"حالت اولویت روشن است"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/tiles_states_strings.xml b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
index 85f0bfd..b341e9e 100644
--- a/packages/SystemUI/res/values-fa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"خاموش"</item>
     <item msgid="5966994759929723339">"روشن"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"دردسترس نیست"</item>
+    <item msgid="2478289035899842865">"خاموش"</item>
+    <item msgid="5137565285664080143">"روشن"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 70af7ab..6f9b38b 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -28,7 +28,7 @@
     <string name="invalid_charger_text" msgid="2339310107232691577">"Käytä laitteesi mukana tullutta laturia"</string>
     <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Otetaanko virransäästö käyttöön?"</string>
     <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"Tietoa virransäästöstä"</string>
-    <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Ota käyttöön"</string>
+    <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Laita päälle"</string>
     <string name="battery_saver_start_action" msgid="8353766979886287140">"Laita päälle"</string>
     <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ei kiitos"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Näytön automaattinen kääntö"</string>
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Ilmoitusalue."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Pika-asetukset."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lukitse näyttö."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Työlukitusnäyttö"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Sulje"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Kirkkaus"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Käänteiset värit"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Värinkorjaus"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Fonttikoko"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Ylläpidä käyttäjiä"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Valmis"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Sulje"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"näytön tallennus"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Ei nimeä"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Virransäästötila"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Fonttikoko"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Pienennä"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Suurenna"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Suurennusikkuna"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Suurennusikkunan ohjaimet"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Lähennä"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ei voi lähettää"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Tallennus ei onnistu. Yritä uudelleen."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Tallennus ei onnistu."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Käytä vähintään 4 merkkiä"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Käytä alle 16 merkkiä"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Koontiversion numero"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Koontiversion numero kopioitu leikepöydälle"</string>
     <string name="basic_status" msgid="2315371112182658176">"Avaa keskustelu"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ainakin yksi laite on käytettävissä"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Kosketa pikakuvaketta pitkään"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Peru"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Käännä nyt"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Saat paremman selfien, kun levität puhelimen"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Käännä etunäytölle, jotta saat paremman selfien?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Voit ottaa laajemman kuvan korkeammalla resoluutiolla, kun käytät takakameraa."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Tämä näyttö sammutetaan"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Vaihda näyttöä nyt"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Taita puhelin auki"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Vaihdetaanko näyttöä?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Resoluutio on parempi, kun käytät takakameraa"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Resoluutio on parempi, kun käännät puhelimen"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Taitettava laite taitetaan"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Taitettava laite käännetään ympäri"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Akkua jäljellä <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Vaihda työprofiiliin"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sulje"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Lukitusnäytön asetukset"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi-yhteys ei ole käytettävissä"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera estetty"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera ja mikrofoni estetty"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofoni estetty"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Tärkeät-tila on päällä"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/tiles_states_strings.xml b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
index 1505dc5..bbd64fd 100644
--- a/packages/SystemUI/res/values-fi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Poissa päältä"</item>
     <item msgid="5966994759929723339">"Päällä"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Ei saatavilla"</item>
+    <item msgid="2478289035899842865">"Pois päältä"</item>
+    <item msgid="5137565285664080143">"Päällä"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index e42f24b..c6f8cab 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Volet des notifications"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Paramètres rapides"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Écran de verrouillage"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Verrouillage de l\'écran du profil professionnel"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Fermer"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Luminosité"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversion des couleurs"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Correction des couleurs"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Taille de la police"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gérer les utilisateurs"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Terminé"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Fermer"</string>
@@ -777,6 +780,12 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"enregistrement d\'écran"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sans titre"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Veille"</string>
+    <!-- no translation found for font_scaling_dialog_title (6273107303850248375) -->
+    <skip />
+    <!-- no translation found for font_scaling_smaller (1012032217622008232) -->
+    <skip />
+    <!-- no translation found for font_scaling_larger (5476242157436806760) -->
+    <skip />
     <string name="magnification_window_title" msgid="4863914360847258333">"Fenêtre d\'agrandissement"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Commandes pour la fenêtre d\'agrandissement"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Effectuer un zoom avant"</string>
@@ -862,10 +871,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Une erreur s\'est produite. Réessayez."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Chargement en cours…"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablette"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Diffusion de votre contenu multimédia en cours…"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Diffusion de <xliff:g id="APP_LABEL">%1$s</xliff:g> en cours…"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifiez l\'appli"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"La commande n\'est pas accessible"</string>
@@ -903,6 +910,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Impossible de diffuser"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Impossible d\'enregistrer. Réessayez."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Impossible d\'enregistrer."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Utilisez au moins 4 caractères"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Utilisez moins de 16 caractères"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de version"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Le numéro de version a été copié dans le presse-papiers."</string>
     <string name="basic_status" msgid="2315371112182658176">"Ouvrir la conversation"</string>
@@ -1022,11 +1031,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• qu\'au moins un appareil est utilisable;"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Maintenir le doigt sur raccourci"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuler"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Retourner maintenant"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Déplier le téléphone pour un meilleur égoportrait"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Retourner l\'écran pour un meilleur égoportrait?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilisez l\'appareil photo arrière pour une photo plus large avec une résolution supérieure."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* Cet écran va s\'éteindre"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Changer d\'écran maintenant"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Déplier le téléphone"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Changer d\'écran?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Pour une meilleure résolution, utilisez l\'appareil photo arrière"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Pour une meilleure résolution, retournez le téléphone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable en cours de dépliage"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable en train d\'être retourné"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Charge restante de la pile : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1047,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Passer au profil professionnel"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fermer"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Paramètres écran de verrouillage"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
index c408865..8df6211 100644
--- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Désactivé"</item>
     <item msgid="5966994759929723339">"Activé"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Non accessible"</item>
+    <item msgid="2478289035899842865">"Désactivée"</item>
+    <item msgid="5137565285664080143">"Activée"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 371396a..a191259 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Volet des notifications"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Réglages rapides"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Écran de verrouillage"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Écran de verrouillage du profil professionnel"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Fermer"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Luminosité"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversion des couleurs"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Correction des couleurs"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Taille de la police"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gérer les utilisateurs"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"OK"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Fermer"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"enregistrement écran"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sans titre"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Mode Veille imminent"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Taille de police"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Réduire"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Agrandir"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Fenêtre d\'agrandissement"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Fenêtre des commandes d\'agrandissement"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Faire un zoom avant"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Un problème est survenu. Réessayez."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Chargement…"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablette"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Casting de vos contenus multimédias"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Casting de <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifier l\'appli"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Commande indisponible"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Impossible de diffuser"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Impossible d\'enregistrer. Réessayez."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Impossible d\'enregistrer."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Utilisez au moins quatre caractères"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Utilisez moins de 16 caractères"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numéro de build copié dans le presse-papiers."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversation ouverte"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Au moins un appareil est disponible"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Appuyez de manière prolongée sur raccourci"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuler"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Retourner"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Déplier le téléphone pour un meilleur selfie"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Passer à l\'écran frontal pour un meilleur selfie ?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilisez la caméra arrière pour prendre une photo plus large d\'une résolution supérieure."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Cet écran s\'éteindra"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Changer d\'écran maintenant"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Déplier le téléphone"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Changer d\'écran ?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Pour une résolution plus élevée, utilisez la caméra arrière"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Pour une résolution plus élevée, retournez le téléphone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable qui est déplié"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable qui est retourné"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> de batterie restante"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Passer au profil professionnel"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fermer"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Paramètres écran de verrouillage"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr/tiles_states_strings.xml b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
index 8c6c4f5..ce39cd2 100644
--- a/packages/SystemUI/res/values-fr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Désactivé"</item>
     <item msgid="5966994759929723339">"Activé"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Non disponible"</item>
+    <item msgid="2478289035899842865">"Désactivé"</item>
+    <item msgid="5137565285664080143">"Activé"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 9bea0ca..2684b92 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Panel despregable"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Configuración rápida"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Pantalla de bloqueo."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Pantalla de bloqueo do perfil de traballo"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Pechar"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brillo"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversión da cor"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Corrección da cor"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Tamaño do tipo de letra"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Administrar usuarios"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Feito"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Pechar"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"gravación pantalla"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sen título"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Modo de espera"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Tamaño do tipo de letra"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Reducir o tamaño"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Aumentar o tamaño"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Ventá de superposición"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Controis de ampliación da ventá"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Achegar"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Produciuse un erro. Téntao de novo."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Cargando"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tableta"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Emitindo contido multimedia"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Emitindo <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Comproba a app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Non se atopou"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"O control non está dispoñible"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Non se puido iniciar a emisión"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Non se puido gardar a información. Téntao de novo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Non se pode gardar a información."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Utiliza como mínimo 4 caracteres"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Utiliza menos de 16 caracteres"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Copiouse o número de compilación no portapapeis."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ten que haber polo menos un dispositivo dispoñible"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantén premido o atallo"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Voltear agora"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desprega o teléfono para unha autofoto mellor"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Usar a cámara dianteira para unha autofoto mellor?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Usa a cámara traseira para sacar unha foto máis ampla e con maior resolución."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Desactivarase esta pantalla"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Cambiar de pantalla agora"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Desprega o teléfono"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Queres cambiar de pantalla?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Usa a cámara traseira para gozar dunha maior resolución"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Dálle a volta ao teléfono para gozar dunha maior resolución"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pregable abríndose"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pregable xirando"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Batería restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Cambiar ao perfil de traballo"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Pechar"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Configuración pantalla bloqueo"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gl/tiles_states_strings.xml b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
index 590ec4a..b03f311 100644
--- a/packages/SystemUI/res/values-gl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Desactivado"</item>
     <item msgid="5966994759929723339">"Activado"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Non dispoñible"</item>
+    <item msgid="2478289035899842865">"Desactivado"</item>
+    <item msgid="5137565285664080143">"Activado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index fa55ea6..cf1000d 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"નોટિફિકેશન શેડ."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ઝડપી સેટિંગ."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"લૉક સ્ક્રીન."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"કાર્ય લૉક સ્ક્રીન"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"બંધ કરો"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"તેજ"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"વિપરીત રંગમાં બદલવું"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"રંગ સુધારણા"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"ફૉન્ટનું કદ"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"વપરાશકર્તાઓને મેનેજ કરો"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"થઈ ગયું"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"બંધ કરો"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"સ્ક્રીન રેકોર્ડિંગ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"કોઈ શીર્ષક નથી"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"સ્ટૅન્ડબાય"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ફૉન્ટનું કદ"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"વધુ નાનું બનાવો"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"વધુ મોટું બનાવો"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"વિસ્તૃતીકરણ વિંડો"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"વિસ્તૃતીકરણ વિંડોના નિયંત્રણો"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"મોટું કરો"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"કંઈક ખોટું થયું. ફરી પ્રયાસ કરો."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"લોડ થઈ રહ્યું છે"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ટૅબ્લેટ"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"તમારું મીડિયા કાસ્ટ કરી રહ્યાં છીએ"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> કાસ્ટ કરી રહ્યાં છીએ"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"નિષ્ક્રિય, ઍપને ચેક કરો"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"મળ્યું નથી"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"નિયંત્રણ ઉપલબ્ધ નથી"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"બ્રોડકાસ્ટ કરી શકતા નથી"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"સાચવી શકતા નથી. ફરી પ્રયાસ કરો."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"સાચવી શકતા નથી."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"ઓછામાં ઓછા 4 અક્ષરનો ઉપયોગ કરો"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16 કરતાં ઓછા અક્ષરનો ઉપયોગ કરો"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"બિલ્ડ નંબર"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"બિલ્ડ નંબર ક્લિપબૉર્ડ પર કૉપિ કર્યો."</string>
     <string name="basic_status" msgid="2315371112182658176">"વાતચીત ખોલો"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ઓછામાં ઓછું એક ડિવાઇસ ઉપલબ્ધ છે"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"શૉર્ટકટને ટચ વડે પળભર દબાવી રાખો"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"રદ કરો"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"હમણાં જ ફ્લિપ કરો"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"બહેતર સેલ્ફી લેવા માટે ફોન ખોલો"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"બહેતર સેલ્ફી લેવા ફ્રન્ટ ડિસ્પ્લે પર ફ્લિપ કરીએ?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"વધુ ઉચ્ચ રિઝોલ્યુશનવાળો વિશાળ ફોટો લેવા માટે પાછલા કૅમેરાનો ઉપયોગ કરો."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ આ સ્ક્રીન બંધ થઈ જશે"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"હમણાં સ્ક્રીન સ્વિચ કરો"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"ફોનને અનફોલ્ડ કરો"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"સ્ક્રીન સ્વિચ કરીએ?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"વધુ રિઝોલ્યુશન માટે, રીઅર કૅમેરાનો ઉપયોગ કરો"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"વધુ રિઝોલ્યુશન માટે, ફોનને ફ્લિપ કરો"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ફોલ્ડ કરી શકાય એવું ડિવાઇસ અનફોલ્ડ કરવામાં આવી રહ્યું છે"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ફોલ્ડ કરી શકાય એવું ડિવાઇસ ફ્લિપ કરવામાં આવી રહ્યું છે"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> બૅટરી બાકી છે"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ઑફિસની પ્રોફાઇલ પર સ્વિચ કરો"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"બંધ કરો"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"લૉક સ્ક્રીનના સેટિંગ"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gu/tiles_states_strings.xml b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
index cc062a77..5d1ad6f 100644
--- a/packages/SystemUI/res/values-gu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"બંધ છે"</item>
     <item msgid="5966994759929723339">"ચાલુ છે"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"અનુપલબ્ધ"</item>
+    <item msgid="2478289035899842865">"બંધ"</item>
+    <item msgid="5137565285664080143">"ચાલુ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index c7b9fec..7bab739 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"सूचना शेड."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"त्वरित सेटिंग."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"लॉक स्क्रीन."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"वर्क लॉक स्‍क्रीन"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"बंद करें"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"स्क्रीन की रोशनी"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"रंग बदलने की सुविधा"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"रंग में सुधार करने की सुविधा"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"फ़ॉन्ट का साइज़"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"उपयोगकर्ताओं को मैनेज करें"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"हो गया"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"रद्द करें"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"स्क्रीन रिकॉर्डिंग"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"कोई शीर्षक नहीं"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टैंडबाई"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"फ़ॉन्ट का साइज़"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"छोटा करें"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"बड़ा करें"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"स्क्रीन को बड़ा करके दिखाने वाली विंडो"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"स्क्रीन को बड़ा करके दिखाने वाली विंडो के नियंत्रण"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ज़ूम इन करें"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"कोई गड़बड़ी हुई. फिर से कोशिश करें."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"लोड हो रहा है"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"टैबलेट"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"आपका मीडिया कास्ट किया जा रहा है"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> को कास्ट किया जा रहा है"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"काम नहीं कर रहा, ऐप जांचें"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"कंट्रोल नहीं है"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"कंट्रोल मौजूद नहीं है"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ब्रॉडकास्ट नहीं किया जा सकता"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"सेव नहीं किया जा सका. फिर से कोशिश करें."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"सेव नहीं किया जा सका."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"कम से कम चार वर्ण इस्तेमाल करें"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16 वर्ण से कम इस्तेमाल करें"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर को क्लिपबोर्ड पर कॉपी किया गया."</string>
     <string name="basic_status" msgid="2315371112182658176">"ऐसी बातचीत जिसमें इंटरैक्शन डेटा मौजूद नहीं है"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• कम से कम एक डिवाइस उपलब्ध है"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"शॉर्टकट को दबाकर रखें"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"रद्द करें"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"अभी स्विच करें"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"बेहतर सेल्फ़ी के लिए फ़ोन को अनफ़ोल्ड करें"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"बेहतर सेल्फ़ी के लिए फ़्रंट डिसप्ले पर स्विच करें?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"वाइड ऐंगल में हाई रिज़ॉल्यूशन वाली फ़ोटो लेने के लिए, पीछे का कैमरा इस्तेमाल करें."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ यह स्क्रीन बंद हो जाएगी"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"अब स्क्रीन स्विच करें"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"अपना फ़ोन अनफ़ोल्ड करें"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"स्क्रीन स्विच करनी है?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"बेहतर रिज़ॉल्यूशन वाली फ़ोटो खींचने के लिए, पीछे का कैमरा इस्तेमाल करें"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"बेहतर रिज़ॉल्यूशन वाली फ़ोटो खींचने के लिए, फ़ोन को फ़्लिप करें"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फ़ोल्ड किया जा सकने वाला डिवाइस अनफ़ोल्ड किया जा रहा है"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फ़ोल्ड किया जा सकने वाला डिवाइस पलटा जा रहा है"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> बैटरी बची है"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"वर्क प्रोफ़ाइल पर स्विच करें"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"बंद करें"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"लॉक स्क्रीन की सेटिंग"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"वाई-फ़ाई उपलब्ध नहीं है"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"कैमरे का ऐक्सेस नहीं है"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"कैमरे और माइक्रोफ़ोन का ऐक्सेस नहीं है"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"माइक्रोफ़ोन का ऐक्सेस नहीं है"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"प्राथमिकता मोड चालू है"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/tiles_states_strings.xml b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
index a156b0c..cd29fb9 100644
--- a/packages/SystemUI/res/values-hi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"बंद है"</item>
     <item msgid="5966994759929723339">"चालू है"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"अभी उपलब्ध नहीं है"</item>
+    <item msgid="2478289035899842865">"बंद है"</item>
+    <item msgid="5137565285664080143">"चालू है"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 72bdbce..5a9bf91 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -197,6 +197,7 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Zaslon obavijesti."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Brze postavke."</string>
+    <string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"Brze postavke i zaslon obavijesti."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Zaključavanje zaslona."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Zaključan zaslon radnog profila"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Zatvaranje"</string>
@@ -257,6 +258,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Svjetlina"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inverzija boja"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Korekcija boja"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Veličina fonta"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Upravljajte korisnicima"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Gotovo"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zatvori"</string>
@@ -777,6 +779,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"snimanje zaslona"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje mirovanja"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Veličina fonta"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Smanji"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Povećaj"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Prozor za povećavanje"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrole prozora za povećavanje"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Povećaj"</string>
@@ -901,6 +906,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Emitiranje nije uspjelo"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Spremanje nije uspjelo. Pokušajte ponovo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Spremanje nije uspjelo."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Upotrijebite barem četiri znaka"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Upotrijebite manje od 16 znakova"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj međuverzije"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Broj međuverzije kopiran je u međuspremnik."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string>
@@ -1020,11 +1027,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Dostupan je najmanje jedan uređaj"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Prečac za dodirnuti i zadržati"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Odustani"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Prebaci"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Otvorite telefon da biste snimili bolji selfie"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Prebaciti na prednji zaslon za bolji selfie?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Upotrijebite stražnji fotoaparat za širu fotografiju s višom razlučivošću."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ovaj će se zaslon isključiti"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Promijenite zaslon odmah"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Otklopite telefon"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Želite li promijeniti zaslon?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Za višu razlučivost upotrijebite stražnju kameru"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za višu razlučivost okrenite telefon"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rasklopljen sklopivi uređaj"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Okretanje sklopivog uređaja sa svih strana"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Preostalo je <xliff:g id="PERCENTAGE">%s</xliff:g> baterije"</string>
@@ -1036,4 +1043,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Prijeđite na poslovni profil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Postavke zaključanog zaslona"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi nije dostupan"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera je blokirana"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Blokirani su kamera i mikrofon"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon je blokiran"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Uključen je prioritetni način rada"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/tiles_states_strings.xml b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
index b69b064..32051ef 100644
--- a/packages/SystemUI/res/values-hr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Isključeno"</item>
     <item msgid="5966994759929723339">"Uključeno"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Nedostupno"</item>
+    <item msgid="2478289035899842865">"Isključeno"</item>
+    <item msgid="5137565285664080143">"Uključeno"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 0ad27c4..8a088a1 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Értesítési felület."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Gyorsbeállítások."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lezárási képernyő."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Munka lezárási képernyővel"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Bezárás"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Fényerő"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Színek invertálása"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Színjavítás"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Betűméret"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Felhasználók kezelése"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Kész"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Bezárás"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"képernyőrögzítés"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Nincs cím"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Készenléti mód"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Betűméret"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Kisebb"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Nagyobb"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Nagyítás ablaka"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Nagyítási vezérlők ablaka"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Nagyítás"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nem sikerült a közvetítés"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"A mentés nem sikerült. Próbálja újra."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"A mentés nem sikerült."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Legalább négy karaktert használjon"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Legfeljebb 16 karaktert használhat"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildszám"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Buildszám a vágólapra másolva."</string>
     <string name="basic_status" msgid="2315371112182658176">"Beszélgetés megnyitása"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Legalább egy eszköz rendelkezésre áll"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Tartsa nyomva a parancsikont"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Mégse"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Átfordítás most"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Hajtsa ki a telefont jobb szelfi készítéséhez"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Átfordítja az előlapi kijelzőre a jobb szelfiért?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Használja az előlapi kamerát, hogy nagyobb felbontású, szélesebb fotót készíthessen"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ A képernyő kikapcsol"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Váltson képernyőt most"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Hajtsa ki a telefont"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Szeretne képernyőt váltani?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"A nagyobb felbontás érdekében használja a hátlapi kamerát."</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"A nagyobb felbontás érdekében fordítsa meg a telefont"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Összehajtható eszköz kihajtása"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Összehajtható eszköz körbeforgatása"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Akkumulátor töltöttségi szintje: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Váltás munkaprofilra"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Bezárás"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Lezárási képernyő beállításai"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hu/tiles_states_strings.xml b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
index 050bc14..157c552 100644
--- a/packages/SystemUI/res/values-hu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Ki"</item>
     <item msgid="5966994759929723339">"Be"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Nem áll rendelkezésre"</item>
+    <item msgid="2478289035899842865">"Ki"</item>
+    <item msgid="5137565285664080143">"Be"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index ff8f19a..819a029 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -187,7 +187,7 @@
     <string name="accessibility_battery_level" msgid="5143715405241138822">"Մարտկոցը <xliff:g id="NUMBER">%d</xliff:g> տոկոս է:"</string>
     <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"Մարտկոցի լիցքը <xliff:g id="PERCENTAGE">%1$d</xliff:g> տոկոս է։ Այն կաշխատի <xliff:g id="TIME">%2$s</xliff:g>։"</string>
     <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Մարտկոցը լիցքավորվում է: Լիցքը <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> տոկոս է:"</string>
-    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Մարտկոցի լիցքը <xliff:g id="PERCENTAGE">%d</xliff:g> է։ Լիցքավորումը դադարեցվել է՝ մարտկոցը պաշտպանելու համար։"</string>
+    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Մարտկոցի լիցքը <xliff:g id="PERCENTAGE">%d</xliff:g> տոկոս է։ Լիցքավորումը դադարեցվել է՝ մարտկոցը պաշտպանելու համար։"</string>
     <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"Մարտկոցի լիցքը <xliff:g id="PERCENTAGE">%1$d</xliff:g> է։ Այն կաշխատի <xliff:g id="TIME">%2$s</xliff:g>։ Լիցքավորումը դադարեցվել է՝ մարտկոցը պաշտպանելու նպատակով։"</string>
     <string name="accessibility_overflow_action" msgid="8555835828182509104">"Տեսնել բոլոր ծանուցումները"</string>
     <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Հեռատիպը միացված է:"</string>
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Ծանուցումների վահանակ:"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Արագ կարգավորումներ:"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Էկրանի կողպում:"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Աշխատանքային պրոֆիլի կողպէկրան"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Փակել"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Պայծառություն"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Գունաշրջում"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Գունաշտկում"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Տառաչափ"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Կառավարել օգտատերերին"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Պատրաստ է"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Փակել"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"էկրանի տեսագրում"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Անանուն"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Սպասման ռեժիմ"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Տառաչափ"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Փոքրացնել"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Մեծացնել"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Խոշորացման պատուհան"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Խոշորացման պատուհանի կառավարման տարրեր"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Մեծացնել"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Չհաջողվեց հեռարձակել"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Չհաջողվեց պահել։ Նորից փորձեք։"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Չհաջողվեց պահել։"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Օգտագործեք առնվազն 4 նիշ"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Օգտագործեք ոչ ավել քան 16 նիշ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Կառուցման համարը"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Կառուցման համարը պատճենվեց սեղմատախտակին։"</string>
     <string name="basic_status" msgid="2315371112182658176">"Բաց զրույց"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Հասանելի է առնվազն մեկ սարք"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Հպեք դյուրանցմանը և պահեք"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Չեղարկել"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Շրջել հիմա"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Բացեք հեռախոսի փեղկը՝ ավելի լավ սելֆի անելու համար"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Հեռախոսը էկրանով դեպի ձե՞զ շրջեցիք"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Օգտագործեք հետևի տեսախցիկը՝ ավելի բարձր լուծաչափով և ավելի լայն լուսանկար ստանալու համար։"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Այս էկրանը կանջատվի"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Փոխել էկրանը հիմա"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Բացեք հեռախոսի փեղկը"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Փոխե՞լ էկրանը"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Ավելի մեծ լուծաչափի համար օգտագործեք հիմնական տեսախցիկը"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Ավելի մեծ լուծաչափի համար շրջեք հեռախոսը"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ծալովի սարք՝ բացված վիճակում"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Ծալովի սարք՝ շրջված վիճակում"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Մարտկոցի լիցքը՝ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Անցնել աշխատանքային պրոֆիլ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Փակել"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Կողպէկրանի կարգավորումներ"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hy/tiles_states_strings.xml b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
index 6015fbd..089716f 100644
--- a/packages/SystemUI/res/values-hy/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Անջատված է"</item>
     <item msgid="5966994759929723339">"Միացված է"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Հասանելի չէ"</item>
+    <item msgid="2478289035899842865">"Անջատված է"</item>
+    <item msgid="5137565285664080143">"Միացված է"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 12495c1..b70173a 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Bayangan pemberitahuan."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Setelan cepat."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Layar kunci."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Layar kunci kantor"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Tutup"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Kecerahan"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversi warna"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Koreksi warna"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Ukuran font"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Kelola pengguna"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Selesai"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Tutup"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"perekaman layar"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Tanpa judul"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Siaga"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Ukuran Font"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Buat lebih kecil"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Buat lebih besar"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Jendela Pembesaran"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrol Jendela Pembesaran"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Perbesar"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Terjadi error. Coba lagi."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Memuat"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Mentransmisikan media"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Mentransmisikan <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Nonaktif, periksa aplikasi"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrol tidak tersedia"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Tidak dapat menyiarkan"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Tidak dapat menyimpan. Coba lagi."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Tidak dapat menyimpan."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Gunakan minimal 4 karakter"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Gunakan kurang dari 16 karakter"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nomor build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nomor versi disalin ke papan klip."</string>
     <string name="basic_status" msgid="2315371112182658176">"Membuka percakapan"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Tersedia minimal satu perangkat"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Sentuh lama pintasan"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Batal"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Balik sekarang"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Bentangkan ponsel untuk selfie yang lebih baik"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Balik ke layar depan untuk selfie yang lebih bagus?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gunakan kamera belakang untuk foto dengan resolusi lebih tinggi dan lebih lebar."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Layar ini akan dinonaktifkan"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Beralih layar sekarang"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Bentangkan ponsel"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Beralih layar?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Untuk resolusi lebih tinggi, gunakan kamera belakang"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Untuk resolusi lebih tinggi, balik ponsel"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Perangkat foldable sedang dibentangkan"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Perangkat foldable sedang dibalik"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Baterai tersisa <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Beralih ke profil kerja"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tutup"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Setelan layar kunci"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-in/tiles_states_strings.xml b/packages/SystemUI/res/values-in/tiles_states_strings.xml
index 5416c8f..71460a71 100644
--- a/packages/SystemUI/res/values-in/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-in/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Nonaktif"</item>
     <item msgid="5966994759929723339">"Aktif"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Tidak tersedia"</item>
+    <item msgid="2478289035899842865">"Nonaktif"</item>
+    <item msgid="5137565285664080143">"Aktif"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 87b8a73..85b435e 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -187,8 +187,8 @@
     <string name="accessibility_battery_level" msgid="5143715405241138822">"<xliff:g id="NUMBER">%d</xliff:g> prósent á rafhlöðu."</string>
     <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"Hleðsla rafhlöðu er <xliff:g id="PERCENTAGE">%1$d</xliff:g> prósent, <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Rafhlaða í hleðslu, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
-    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Hleðsla rafhlöðu er <xliff:g id="PERCENTAGE">%d</xliff:g> prósent, hlé gert á hleðslu til að vernda rafhlöðuna."</string>
-    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"Hleðsla rafhlöðu er <xliff:g id="PERCENTAGE">%1$d</xliff:g> prósent, <xliff:g id="TIME">%2$s</xliff:g>, hlé gert á hleðslu til að vernda rafhlöðuna."</string>
+    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Rafhleðsla er <xliff:g id="PERCENTAGE">%d</xliff:g> prósent, hlé gert á hleðslu til að vernda rafhlöðuna."</string>
+    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"Rafhleðsla er <xliff:g id="PERCENTAGE">%1$d</xliff:g> prósent, <xliff:g id="TIME">%2$s</xliff:g>, hlé gert á hleðslu til að vernda rafhlöðuna."</string>
     <string name="accessibility_overflow_action" msgid="8555835828182509104">"Sjá allar tilkynningar"</string>
     <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Fjarriti virkur."</string>
     <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Titrar við hringingu."</string>
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Tilkynningasvæði."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Flýtistillingar."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lásskjár."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Vinnulásskjár"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Loka"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Birtustig"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Umsnúningur lita"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Litaleiðrétting"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Leturstærð"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Stjórna notendum"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Lokið"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Loka"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"skjáupptaka"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Enginn titill"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Biðstaða"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Leturstærð"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Minnka"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Stækka"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Stækkunargluggi"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Stækkunarstillingar glugga"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Auka aðdrátt"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Eitthvað fór úrskeiðis. Reyndu aftur."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Hleður"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"spjaldtölva"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Sendir út efni frá þér"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Sendir út <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Óvirkt, athugaðu forrit"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Fannst ekki"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Stýring er ekki tiltæk"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ekki hægt að senda út"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ekki hægt að vista. Reyndu aftur."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ekki hægt að vista."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Notaðu að minnsta kosti 4 stafi"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Notaðu færri en 16 stafi"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Útgáfunúmer smíðar"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Útgáfunúmer smíðar afritað á klippiborð."</string>
     <string name="basic_status" msgid="2315371112182658176">"Opna samtal"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Að minnsta kosti eitt tæki er tiltækt"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Haltu flýtilyklinum inni"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Hætta við"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Snúa núna"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Opnaðu símann til að taka betri sjálfsmynd"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Snúa á framskjá til að ná betri sjálfsmynd?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Notaðu aftari myndavélina til að ná víðara sjónarhorni með meiri upplausn."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Slökkt verður á þessum skjá"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Skipta um skjá núna"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Opnaðu símann"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Skipta um skjá?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Notaðu aftari myndavélina til að fá betri upplausn"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Snúðu símanum til að fá betri upplausn"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Samanbrjótanlegt tæki opnað"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Samanbrjótanlegu tæki snúið við"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> hleðsla eftir á rafhlöðu"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Skipta yfir í vinnusnið"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Loka"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Stillingar fyrir lásskjá"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-is/tiles_states_strings.xml b/packages/SystemUI/res/values-is/tiles_states_strings.xml
index 12dd776..17aaf6c 100644
--- a/packages/SystemUI/res/values-is/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-is/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Slökkt"</item>
     <item msgid="5966994759929723339">"Kveikt"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Ekki tiltækt"</item>
+    <item msgid="2478289035899842865">"Slökkt"</item>
+    <item msgid="5137565285664080143">"Kveikt"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index bc89cbb..8c25677 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -197,6 +197,7 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Area notifiche."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Impostazioni rapide."</string>
+    <string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"Area notifiche e Impostazioni rapide."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Schermata di blocco."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Schermata di blocco del profilo di lavoro"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Chiudi"</string>
@@ -257,6 +258,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Luminosità"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversione dei colori"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Correzione del colore"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Dimensioni carattere"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gestisci utenti"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Fine"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Chiudi"</string>
@@ -777,6 +779,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"Registraz. schermo"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Senza titolo"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Dimensioni carattere"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Rimpicciolisci"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Ingrandisci"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Finestra ingrandimento"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Finestra controlli di ingrandimento"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Aumenta lo zoom"</string>
@@ -901,6 +906,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Impossibile trasmettere"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Impossibile salvare. Riprova."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Impossibile salvare."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Usa almeno 4 caratteri"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Usa meno di 16 caratteri"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numero build copiato negli appunti."</string>
     <string name="basic_status" msgid="2315371112182658176">"Apri conversazione"</string>
@@ -1020,11 +1027,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ci sia almeno un dispositivo disponibile"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Tocca scorciatoia/tieni premuto"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annulla"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Gira ora"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Apri il telefono per un selfie migliore"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Passare al display frontale per un selfie migliore?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilizza la fotocamera posteriore per una foto più ampia con maggiore risoluzione."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Questo schermo verrà spento"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Cambia schermo ora"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Apri il telefono"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Vuoi cambiare schermo?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Usa la fotocamera posteriore per una maggiore risoluzione"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Gira il telefono per una maggiore risoluzione"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pieghevole che viene aperto"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pieghevole che viene capovolto"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batteria rimanente"</string>
@@ -1036,4 +1043,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Passa a profilo di lavoro"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Chiudi"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Impostazioni schermata di blocco"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml
index 5ec557b..7aa09d4 100644
--- a/packages/SystemUI/res/values-it/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Off"</item>
     <item msgid="5966994759929723339">"On"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Non disponibile"</item>
+    <item msgid="2478289035899842865">"Off"</item>
+    <item msgid="5137565285664080143">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 8633127..1237ba6 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"לוח התראות."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"הגדרות מהירות."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"מסך נעילה."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"מסך נעילה של עבודה"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"סגירה"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"בהירות"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"היפוך צבעים"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"תיקון צבע"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"גודל הגופן"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ניהול משתמשים"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"סיום"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"סגירה"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"הקלטת המסך"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"ללא שם"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"המתנה"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"גודל גופן"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"הקטנה"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"הגדלה"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"חלון הגדלה"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"בקרות של חלון ההגדלה"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"התקרבות"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"לא ניתן לשדר"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"לא ניתן לשמור. כדאי לנסות שוב."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"לא ניתן לשמור."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"יש להזין 4 תווים לפחות"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"אפשר להזין עד 16 תווים"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"‏מספר Build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"‏מספר ה-Build הועתק ללוח."</string>
     <string name="basic_status" msgid="2315371112182658176">"פתיחת שיחה"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• יש לפחות מכשיר אחד זמין"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"מקש קיצור ללחיצה ארוכה"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ביטול"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"אני רוצה להפוך"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"כדי לצלם תמונת סלפי טובה יותר, פותחים את הטלפון"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"להפוך למסך הקדמי כדי לצלם תמונת סלפי טובה יותר?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"במצלמה האחורית אפשר לצלם תמונה רחבה יותר ברזולוציה גבוהה יותר."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ המסך יכבה"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"כן, אני רוצה להחליף בין המסכים"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"פתיחת הטלפון"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"להחליף בין המסכים?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"כדי לצלם תמונה ברזולוציה גבוהה יותר, כדאי להשתמש במצלמה האחורית"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"כדי לצלם תמונה ברזולוציה גבוהה יותר, כדאי להפוך את הטלפון"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"מכשיר מתקפל עובר למצב לא מקופל"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"מכשיר מתקפל עובר למצב מהופך"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"רמת הטעינה שנותרה בסוללה: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"מעבר לפרופיל עבודה"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"סגירה"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"הגדרות מסך הנעילה"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"‏ה-Wi-Fi לא זמין"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"המצלמה חסומה"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"המצלמה והמיקרופון חסומים"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"המיקרופון חסום"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"מצב \'עדיפות\' מופעל"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/tiles_states_strings.xml b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
index 91577b8..d5a0e72 100644
--- a/packages/SystemUI/res/values-iw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"כבוי"</item>
     <item msgid="5966994759929723339">"מופעל"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"לא זמין"</item>
+    <item msgid="2478289035899842865">"מושבת"</item>
+    <item msgid="5137565285664080143">"מופעל"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 9aef2a9..2ce2f53 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"通知シェード"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"クイック設定"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ロック画面"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"仕事用プロファイルのロック画面"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"閉じる"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"画面の明るさ"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"色反転"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"色補正"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"フォントサイズ"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ユーザーを管理"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"完了"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"閉じる"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"画面の録画"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"タイトルなし"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"スタンバイ"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"フォントサイズ"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"縮小"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"拡大"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"拡大ウィンドウ"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"拡大ウィンドウ コントロール"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"拡大"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"エラーが発生しました。もう一度お試しください。"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"読み込んでいます"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"タブレット"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"メディアをキャストしています"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> をキャストしています"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"無効: アプリをご確認ください"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"見つかりませんでした"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"コントロールを使用できません"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ブロードキャストできません"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"保存できません。もう一度お試しください。"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"保存できません。"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"4 文字以上にしてください"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"使用できる文字数は 16 文字未満です"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ビルド番号"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ビルド番号をクリップボードにコピーしました。"</string>
     <string name="basic_status" msgid="2315371112182658176">"空の会話"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 利用できるデバイスが 1 台以上ある"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ショートカットの長押しが必要です"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"キャンセル"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"切り替える"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"高画質で撮るにはスマートフォンを開いてください"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"前面ディスプレイに切り替えて綺麗に撮りましょう"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"高解像度で広い範囲を撮影するには、背面カメラを使用してください。"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱この画面は OFF になります"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"画面を切り替えましょう"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"スマートフォンを開いてください"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"画面を切り替えますか?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"高解像度で撮るには背面カメラを使用してください"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"高解像度で撮るにはスマートフォンを裏返してください"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"折りたたみ式デバイスが広げられている"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"折りたたみ式デバイスがひっくり返されている"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"バッテリー残量 <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"仕事用プロファイルに切り替える"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"閉じる"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"ロック画面の設定"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi は利用できません"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"カメラはブロックされています"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"カメラとマイクはブロックされています"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"マイクはブロックされています"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"優先モードは ON です"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/tiles_states_strings.xml b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
index c2a3321..31158ca 100644
--- a/packages/SystemUI/res/values-ja/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"OFF"</item>
     <item msgid="5966994759929723339">"ON"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"使用不可"</item>
+    <item msgid="2478289035899842865">"OFF"</item>
+    <item msgid="5137565285664080143">"ON"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 62efabe..59febea 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"შეტყობინებების ფარდა"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"სწრაფი პარამეტრები"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ეკრანის დაბლოკვა."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"სამსახურის ჩაკეტილი ეკრანი"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"დახურვა"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"განათება"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ფერთა ინვერსია"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"ფერთა კორექცია"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"შრიფტის ზომა"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"მომხმარებლების მართვა"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"დასრულდა"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"დახურვა"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ეკრანის ჩაწერა"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"უსათაურო"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"მოლოდინის რეჟიმი"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"შრიფტის ზომა"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"დაპატარავება"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"გადიდება"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"გადიდების ფანჯარა"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"გადიდების კონტროლის ფანჯარა"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"მასშტაბის გადიდება"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ტრანსლაცია შეუძლებელია"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"შენახვა ვერ ხერხდება. ცადეთ ხელახლა."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"შენახვა ვერ ხერხდება."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"გამოიყენეთ მინიმუმ 4 სიმბოლო."</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"გამოიყენეთ 16-ზე ნაკლები სიმბოლო"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ანაწყობის ნომერი"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ანაწყობის ნომერი დაკოპირებულია გაცვლის ბუფერში."</string>
     <string name="basic_status" msgid="2315371112182658176">"მიმოწერის გახსნა"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ხელმისაწვდომია მინიმუმ ერთი მოწყობილობა"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"შეხების დაamp; მოცდის მალსახმობი"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"გაუქმება"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ახლა გადატრიალება"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"გაშალეთ ტელეფონი უკეთესი სელფისთვის"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"გამოვიყენოთ წინა ეკრანი უკეთესი სელფის მისაღებად?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"გამოიყენეთ უკანა კამერა უფრო ფართო ფოტოს გადასაღებად მაღალი გარჩევადობით."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ეს ეკრანი გამოირთვება"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"ეკრანების ახლა გადართვა"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"გაშალეთ ტელეფონი"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"გადაირთოს ეკრანები?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"მაღალი გარჩევადობისთვის გამოიყენეთ უკანა კამერა"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"მაღალი გარჩევადობისთვის ამოაბრუნეთ ტელეფონი"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"დასაკეცი მოწყობილობა იხსნება"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"დასაკეცი მოწყობილობა ტრიალებს"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"დარჩენილია ბატარეის <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"სამსახურის პროფილზე გადართვა"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"დახურვა"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"ჩაკეტილი ეკრანის პარამეტრები"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi მიუწვდომელია"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"კამერა დაბლოკილია"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"კამერა და მიკროფონი დაბლოკილია"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"მიკროფონი დაბლოკილია"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"პრიორიტეტული რეჟიმი ჩართულია"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/tiles_states_strings.xml b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
index c951874..366030a 100644
--- a/packages/SystemUI/res/values-ka/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"გამორთულია"</item>
     <item msgid="5966994759929723339">"ჩართულია"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"მიუწვდომელია"</item>
+    <item msgid="2478289035899842865">"გამორთული"</item>
+    <item msgid="5137565285664080143">"ჩართული"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 56d8b91..6bdb0aa 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Хабарландыру тақтасы"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Жылдам параметрлер."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Бекіту экраны."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Әрекетті құлыптау экраны"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Жабу"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Жарықтығы"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Түс инверсиясы"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Түсті түзету"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Қаріп өлшемі"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Пайдаланушыларды басқару"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Дайын"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Жабу"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"экранды бейнеге жазу"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Атауы жоқ"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Күту режимі"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Қаріп өлшемі"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Кішірейту"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Үлкейту"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Ұлғайту терезесі"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Ұлғайту терезесінің басқару элементтері"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Ұлғайту"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Бірдеңе дұрыс болмады. Қайталап көріңіз."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Жүктеліп жатыр"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"планшет"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Медиаконтентті трансляциялау"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Трансляция: <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Өшірулі. Қолданба тексеріңіз."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Табылмады"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Басқару виджеті қолжетімсіз"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Тарату мүмкін емес"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Сақталмайды. Қайталап көріңіз."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Сақталмайды."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Кемінде 4 таңба пайдаланыңыз."</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Ең көбі 16 таңба пайдаланыңыз."</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Құрама нөмірі"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Құрама нөмірі буферге көшірілді."</string>
     <string name="basic_status" msgid="2315371112182658176">"Ашық әңгіме"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Кемінде бір құрылғы қолжетімді"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Таңбашаны басып тұрыңыз."</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Бас тарту"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Айналдыру"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Жақсырақ селфи түсіру үшін телефонды жазыңыз"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Жақсырақ селфи үшін алдыңғы экранға ауысасыз ба?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Ажыратымдылығы жоғары кеңірек фотосурет түсіру үшін артқы камераны пайдаланыңыз."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Бұл экран өшіріледі."</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Экрандарды қазір ауыстыру"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Телефонды ашу"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Экрандарды ауыстыру керек пе?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Жоғары ажыратымдылық үшін артқы камераны пайдаланыңыз."</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Жоғары ажыратымдылық үшін телефонды айналдырыңыз."</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Бүктемелі құрылғы ашылып жатыр."</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Бүктемелі құрылғы аударылып жатыр."</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Қалған батарея заряды: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Жұмыс профиліне ауысу"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Жабу"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Экран құлпының параметрлері"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-kk/tiles_states_strings.xml b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
index c312b49..b8089e4 100644
--- a/packages/SystemUI/res/values-kk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Өшірулі."</item>
     <item msgid="5966994759929723339">"Қосулы."</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Қолжетімсіз"</item>
+    <item msgid="2478289035899842865">"Өшірулі"</item>
+    <item msgid="5137565285664080143">"Қосулы"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 3a04488..080769a 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"ពណ៌​ការ​ជូន​ដំណឹង"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ការ​កំណត់​រហ័ស។"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ចាក់​សោ​អេក្រង់។"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"អេក្រង់​ចាក់​សោ​លក្ខណៈ​ការងារ"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"បិទ"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ពន្លឺ"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ការបញ្ច្រាស​ពណ៌"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"ការ​កែតម្រូវ​ពណ៌"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"ទំហំ​ពុម្ព​អក្សរ"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"គ្រប់គ្រង​អ្នក​ប្រើប្រាស់"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"រួចរាល់"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"បិទ"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ការថតវីដេអូអេក្រង់"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"គ្មាន​ចំណងជើង"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ផ្អាក​ដំណើរការ"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ទំហំពុម្ពអក្សរ"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"កំណត់ឱ្យតូចជាងមុន"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"កំណត់ឱ្យធំជាងមុន"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"វិនដូ​ការពង្រីក"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"វិនដូគ្រប់គ្រង​​ការពង្រីក"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ពង្រីក"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"មានអ្វីមួយខុសប្រក្រតី។ សូមព្យាយាមម្ដងទៀត។"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"កំពុងផ្ទុក"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ថេប្លេត"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"កំពុងភ្ជាប់មេឌៀ​របស់អ្នក"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"កំពុង​ភ្ជាប់ <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"អសកម្ម ពិនិត្យមើល​កម្មវិធី"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"រកមិន​ឃើញទេ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"មិនអាច​គ្រប់គ្រង​បានទេ"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"មិនអាចផ្សាយបានទេ"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"មិនអាច​រក្សាទុក​បានទេ។ សូមព្យាយាមម្ដងទៀត។"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"មិនអាច​រក្សាទុក​បានទេ។"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"ប្រើយ៉ាងហោចណាស់ 4 តួអក្សរ"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"ប្រើតិចជាង 16 តួអក្សរ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"លេខ​កំណែបង្កើត"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"បានចម្លងលេខ​កំណែបង្កើតទៅឃ្លីបបត។"</string>
     <string name="basic_status" msgid="2315371112182658176">"បើកការសន្ទនា"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ឧបករណ៍យ៉ាងតិចមួយអាចប្រើបាន"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ចុចឱ្យជាប់លើផ្លូវកាត់"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"បោះបង់"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ត្រឡប់ឥឡូវនេះ"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"លាតទូរសព្ទ ដើម្បីសែលហ្វីកាន់តែប្រសើរ"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ត្រឡប់ទៅផ្ទាំងអេក្រង់ខាងមុខ​ ដើម្បី​ថត​សែលហ្វីកាន់តែបានល្អឬ?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ប្រើកាមេរ៉ាខាងក្រោយ ដើម្បីទទួលបានរូបថតកាន់តែធំជាមួយនឹងកម្រិតគុណភាពកាន់តែខ្ពស់។"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ អេក្រង់នេះនឹងបិទ"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"ប្ដូរអេក្រង់ឥឡូវនេះ"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"លាតទូរសព្ទ"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"ប្ដូរអេក្រង់ឬ?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"សម្រាប់កម្រិតគុណភាពកាន់តែខ្ពស់ សូមប្រើប្រាស់កាមេរ៉ាខាងក្រោយ"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"សម្រាប់កម្រិតគុណភាពកាន់តែខ្ពស់ សូមត្រឡប់ទូរសព្ទ"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ឧបករណ៍អាច​បត់បានកំពុងត្រូវបានលា"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ឧបករណ៍អាច​បត់បានកំពុងត្រូវបានលា"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"ថ្មនៅសល់ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ប្ដូរ​ទៅ​កម្រង​ព័ត៌មាន​ការងារ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"បិទ"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"ការកំណត់​អេក្រង់ចាក់សោ"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"មិនមាន Wi-Fi ទេ"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"បាន​ទប់ស្កាត់​កាមេរ៉ា"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"បានទប់ស្កាត់​កាមេរ៉ា និង​មីក្រូហ្វូន"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"បាន​ទប់ស្កាត់​មីក្រូហ្វូន"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"មុខងារ​អាទិភាពត្រូវបានបើក"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/tiles_states_strings.xml b/packages/SystemUI/res/values-km/tiles_states_strings.xml
index ec748cf..8c5c8d1 100644
--- a/packages/SystemUI/res/values-km/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-km/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"បិទ"</item>
     <item msgid="5966994759929723339">"បើក"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"មិនមានទេ"</item>
+    <item msgid="2478289035899842865">"បិទ"</item>
+    <item msgid="5137565285664080143">"បើក"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index dbc7e15..4a8bbd8 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"ಅಧಿಸೂಚನೆಯ ಛಾಯೆ."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳು."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ಲಾಕ್‌ ಸ್ಕ್ರೀನ್."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"ಕೆಲಸದ ಲಾಕ್ ಪರದೆ"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ಮುಚ್ಚು"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ಪ್ರಕಾಶಮಾನ"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ಕಲರ್ ಇನ್‍ವರ್ಶನ್"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"ಬಣ್ಣದ ತಿದ್ದುಪಡಿ"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"ಫಾಂಟ್ ಗಾತ್ರ"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಹಿಸಿ"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"ಮುಗಿದಿದೆ"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ಮುಚ್ಚಿರಿ"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"ಯಾವುದೇ ಶೀರ್ಷಿಕೆಯಿಲ್ಲ"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ಸ್ಟ್ಯಾಂಡ್‌ಬೈ"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ಫಾಂಟ್ ಗಾತ್ರ"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"ಚಿಕ್ಕದಾಗಿಸಿ"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"ದೊಡ್ಡದಾಗಿಸಿ"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"ವರ್ಧನೆಯ ವಿಂಡೋ"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"ವರ್ಧನೆಯ ವಿಂಡೋ ನಿಯಂತ್ರಣಗಳು"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ಝೂಮ್ ಇನ್ ಮಾಡಿ"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ಪ್ರಸಾರ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ಉಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ಉಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"ಕನಿಷ್ಠ 4 ಅಕ್ಷರಗಳನ್ನು ಬಳಸಿ"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16 ಕ್ಕಿಂತ ಕಡಿಮೆ ಅಕ್ಷರಗಳನ್ನು ಬಳಸಿ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆಯನ್ನು ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ನಲ್ಲಿ ನಕಲಿಸಲಾಗಿದೆ."</string>
     <string name="basic_status" msgid="2315371112182658176">"ಸಂಭಾಷಣೆಯನ್ನು ತೆರೆಯಿರಿ"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ಕನಿಷ್ಠ ಒಂದು ಸಾಧನ ಲಭ್ಯವಿದೆ"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ಸ್ಪರ್ಶಿಸಿ ಹೋಲ್ಡ್ ಮಾಡಿ ಶಾರ್ಟ್‌ಕಟ್"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ರದ್ದುಗೊಳಿಸಿ"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ಈಗ ಫ್ಲಿಪ್ ಮಾಡಿ"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ಉತ್ತಮ ಸೆಲ್ಫೀಗಾಗಿ ಫೋನ್ ಅನ್ನು ಅನ್‌ಫೋಲ್ಡ್ ಮಾಡಿ"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ಉತ್ತಮ ಸೆಲ್ಫೀಗಾಗಿ ಮುಂಭಾಗದ ಕ್ಯಾಮರಾಗೆ ಫ್ಲಿಪ್ ಮಾಡಬೇಕೆ?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ಹೆಚ್ಚಿನ ರೆಸಲ್ಯೂಷನ್ ಹೊಂದಿರುವ ವಿಶಾಲವಾದ ಫೋಟೋಗಾಗಿ ಹಿಂಭಾಗದ ಕ್ಯಾಮರಾವನ್ನು ಬಳಸಿ."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ಈ ಸ್ಕ್ರೀನ್ ಆಫ್ ಆಗುತ್ತದೆ"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"ಈಗ ಸ್ಕ್ರೀನ್‌ಗಳನ್ನು ಬದಲಿಸಿ"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"ಫೋನ್ ಅನ್ನು ಅನ್‌ಫೋಲ್ಡ್ ಮಾಡಿ"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"ಸ್ಕ್ರೀನ್‌ಗಳನ್ನು ಬದಲಿಸಬೇಕೆ?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"ಅಧಿಕ ರೆಸಲ್ಯೂಷನ್‌ಗಾಗಿ, ಹಿಂಬದಿಯ ಕ್ಯಾಮರಾವನ್ನು ಬಳಸಿ"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ಅಧಿಕ ರೆಸಲ್ಯೂಷನ್‌ಗಾಗಿ, ಫೋನ್ ಅನ್ನು ಫ್ಲಿಪ್ ಮಾಡಿ"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ಫೋಲ್ಡ್ ಮಾಡಬಹುದಾದ ಸಾಧನವನ್ನು ಅನ್‌ಫೋಲ್ಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ಫೋಲ್ಡ್ ಮಾಡಬಹುದಾದ ಸಾಧನವನ್ನು ಸುತ್ತಲೂ ತಿರುಗಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ಬ್ಯಾಟರಿ ಉಳಿದಿದೆ"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ಗೆ ಬದಲಿಸಿ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ಮುಚ್ಚಿರಿ"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ವೈ-ಫೈ ಲಭ್ಯವಿಲ್ಲ"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"ಕ್ಯಾಮರಾವನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ರೊಫೋನ್‌ ಅನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"ಮೈಕ್ರೋಫೋನ್ ಅನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"ಆದ್ಯತೆಯ ಮೋಡ್‌ ಆನ್‌ ಆಗಿದೆ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/tiles_states_strings.xml b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
index 864a607..16e82ea 100644
--- a/packages/SystemUI/res/values-kn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"ಆಫ್ ಮಾಡಿ"</item>
     <item msgid="5966994759929723339">"ಆನ್ ಮಾಡಿ"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"ಲಭ್ಯವಿಲ್ಲ"</item>
+    <item msgid="2478289035899842865">"ಆಫ್ ಆಗಿದೆ"</item>
+    <item msgid="5137565285664080143">"ಆನ್ ಆಗಿದೆ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 1595de3..dd68c5a 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"알림 세부정보"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"빠른 설정"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"화면을 잠급니다."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"업무용 잠금 화면"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"닫기"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"밝기"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"색상 반전"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"색상 보정"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"글꼴 크기"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"사용자 관리"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"완료"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"닫기"</string>
@@ -777,6 +780,12 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"화면 녹화"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"제목 없음"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"대기"</string>
+    <!-- no translation found for font_scaling_dialog_title (6273107303850248375) -->
+    <skip />
+    <!-- no translation found for font_scaling_smaller (1012032217622008232) -->
+    <skip />
+    <!-- no translation found for font_scaling_larger (5476242157436806760) -->
+    <skip />
     <string name="magnification_window_title" msgid="4863914360847258333">"확대 창"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"확대 창 컨트롤"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"확대"</string>
@@ -901,6 +910,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"방송할 수 없음"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"저장할 수 없습니다. 다시 시도해 주세요."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"저장할 수 없습니다."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"4자 이상 입력하세요."</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16자 미만이어야 합니다."</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"빌드 번호"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"빌드 번호가 클립보드에 복사되었습니다."</string>
     <string name="basic_status" msgid="2315371112182658176">"대화 열기"</string>
@@ -1020,11 +1031,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 1대 이상의 기기를 사용할 수 있습니다."</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"바로가기를 길게 터치하세요."</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"취소"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"지금 뒤집기"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"휴대전화를 열어서 더 나은 셀카를 찍어보세요"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"전면 디스플레이가 보이도록 뒤집어서 더 나은 셀카를 찍어보세요"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"후면 카메라를 통해 넓은 각도로 해상도가 높은 사진을 찍어보세요."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 이 화면이 꺼집니다."</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"지금 화면 전환"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"휴대전화 펼치기"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"화면을 전환할까요?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"해상도를 높이려면 후면 카메라를 사용하세요."</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"해상도를 높이려면 후면 카메라를 사용하세요."</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"폴더블 기기를 펼치는 모습"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"폴더블 기기를 뒤집는 모습"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"배터리 <xliff:g id="PERCENTAGE">%s</xliff:g> 남음"</string>
@@ -1036,4 +1047,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"직장 프로필로 전환"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"닫기"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"잠금 화면 설정"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ko/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
index c52c17c..7981d28 100644
--- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"꺼짐"</item>
     <item msgid="5966994759929723339">"켜짐"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"사용 불가"</item>
+    <item msgid="2478289035899842865">"사용 안함"</item>
+    <item msgid="5137565285664080143">"사용"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 653292c1..efd9c08 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Билдирмелер тактасы."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Тез тууралоолор."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Кулпуланган экран."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Жумуштун кулпуланган экраны"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Жабуу"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Жарыктыгы"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Түстөрдү инверсиялоо"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Түстөрдү тууралоо"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Ариптин өлчөмү"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Колдонуучуларды тескөө"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Бүттү"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Жабуу"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"экранды жаздыруу"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Аталышы жок"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Көшүү режими"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Арип өлчөмү"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Кичирейтүү"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Чоңойтуу"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Чоңойтуу терезеси"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Чоңойтуу терезесин башкаруу каражаттары"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Жакындатуу"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Кабарлоого болбойт"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Сакталган жок. Кайталап көрүңүз."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Сакталган жок."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Кеминде 4 символдон турушу керек"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16 символдон ашпашы керек"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Курама номери"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Курама номери алмашуу буферине көчүрүлдү."</string>
     <string name="basic_status" msgid="2315371112182658176">"Ачык сүйлөшүү"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Кеминде бир түзмөк жеткиликтүү"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Ыкчам баскычты басып туруңуз"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Токтотуу"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Азыр которуу"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Жакшы селфи тартуу үчүн негизги камерага которуңуз"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Жакшы селфи тартуу үчүн маңдайкы экранга которосузбу?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Кең жана жогорку дааналыктагы сүрөттү тартуу үчүн негизги камераны колдонуңуз."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Бул экран өчөт"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Экрандарды азыр которуштуруу"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Телефонду жайып алыңыз"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Экрандар которуштурулсунбу?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Жогорку дааналык үчүн арткы камераны колдонуңуз"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Жогорку дааналык үчүн телефондун арткы камерасын колдонуңуз"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ачылып турган бүктөлмө түзмөк"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Оодарылып жаткан бүктөлмө түзмөк"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Батареянын кубаты: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Жумуш профилине которулуу"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Жабуу"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Кулпуланган экран параметрлери"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi жеткиликтүү эмес"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Камера бөгөттөлдү"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Камера менен микрофон бөгөттөлдү"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Микрофон бөгөттөлдү"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Маанилүү сүйлөшүүлөр режими күйүк"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/tiles_states_strings.xml b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
index f872926..0f277f9 100644
--- a/packages/SystemUI/res/values-ky/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Өчүк"</item>
     <item msgid="5966994759929723339">"Күйүк"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Жеткиликсиз"</item>
+    <item msgid="2478289035899842865">"Өчүк"</item>
+    <item msgid="5137565285664080143">"Күйүк"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index ac81dcc..4f38e60 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -63,7 +63,7 @@
     <dimen name="large_dialog_width">348dp</dimen>
 
     <dimen name="qs_panel_padding_top">@dimen/qqs_layout_margin_top</dimen>
-    <dimen name="qs_panel_padding_top_combined_headers">@dimen/qs_panel_padding_top</dimen>
 
-    <dimen name="controls_padding_horizontal">16dp</dimen>
+    <dimen name="controls_header_horizontal_padding">12dp</dimen>
+    <dimen name="controls_content_margin_horizontal">16dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index ce929e9..00190ec 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"ໜ້າຈໍແຈ້ງເຕືອນ."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ການຕັ້ງຄ່າດ່ວນ."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ລັອກ​ໜ້າ​ຈໍ."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"ໜ້າຈໍລັອກວຽກ"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ປິດ"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ຄວາມແຈ້ງ"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ການປີ້ນສີ"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"ການແກ້ໄຂສີ"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"ຂະໜາດຟອນ"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ຈັດການຜູ້ໃຊ້"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"ແລ້ວໆ"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ປິດ"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ການບັນທຶກໜ້າຈໍ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"ບໍ່ມີຊື່"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ສະແຕນບາຍ"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ຂະໜາດຟອນ"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"ເຮັດໃຫ້ນ້ອຍລົງ"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"ເຮັດໃຫ້ໃຫຍ່ຂຶ້ນ"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"ໜ້າຈໍການຂະຫຍາຍ"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"ການຄວບຄຸມໜ້າຈໍການຂະຫຍາຍ"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ຊູມເຂົ້າ"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ບໍ່ສາມາດອອກອາກາດໄດ້"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ບໍ່ສາມາດບັນທຶກໄດ້. ກະລຸນາລອງໃໝ່."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ບໍ່ສາມາດບັນທຶກໄດ້."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"ໃຊ້ຢ່າງໜ້ອຍ 4 ຕົວອັກສອນ"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"ໃຊ້ໜ້ອຍກວ່າ 16 ຕົວອັກສອນ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ໝາຍເລກສ້າງ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ສຳເນົາໝາຍເລກສ້າງໄປໃສ່ຄລິບບອດແລ້ວ."</string>
     <string name="basic_status" msgid="2315371112182658176">"ເປີດການສົນທະນາ"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ມີຢ່າງໜ້ອຍ 1 ອຸປະກອນພ້ອມໃຫ້ນຳໃຊ້"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ແຕະທາງລັດຄ້າງໄວ້"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ຍົກເລີກ"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ປີ້ນດຽວນີ້"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ກາງໂທລະສັບອອກເພື່ອການຖ່າຍເຊວຟີທີ່ດີຂຶ້ນ"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ປີ້ນເປັນຈໍສະແດງຜົນດ້ານໜ້າເພື່ອການຖ່າຍເຊວຟີທີ່ດີຂຶ້ນບໍ?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ໃຊ້ກ້ອງຫຼັງເພື່ອການຖ່າຍຮູບທີ່ກວ້າງຂຶ້ນດ້ວຍຄວາມລະອຽດສູງຂຶ້ນ."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ໜ້າຈໍນີ້ຈະປິດ"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"ສະຫຼັບໜ້າຈໍດຽວນີ້"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"ພືໂທລະສັບອອກ"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"ສະຫຼັບໜ້າຈໍບໍ?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"ເພື່ອຄວາມລະອຽດທີ່ສູງຂຶ້ນ, ໃຫ້ໃຊ້ກ້ອງຖ່າຍຮູບຫຼັງ"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ເພື່ອຄວາມລະອຽດທີ່ສູງຂຶ້ນ, ໃຫ້ປີ້ນໂທລະສັບ"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ອຸປະກອນທີ່ພັບໄດ້ກຳລັງກາງອອກ"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ອຸປະກອນທີ່ພັກໄດ້ກຳລັງປີ້ນໄປມາ"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"ແບັດເຕີຣີເຫຼືອ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ສະຫຼັບໄປໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ປິດ"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"ການຕັ້ງຄ່າໜ້າຈໍລັອກ"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi ບໍ່ພ້ອມໃຫ້ນຳໃຊ້"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"ກ້ອງຖ່າຍຮູບຖືກບລັອກຢູ່"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"ກ້ອງຖ່າຍຮູບ ແລະ ໄມໂຄຣໂຟນຖືກບລັອກຢູ່"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"ໄມໂຄຣໂຟນຖືກບລັອກຢູ່"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"ໂໝດຄວາມສຳຄັນເປີດຢູ່"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/tiles_states_strings.xml b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
index 6ae37e4..d54cf4d 100644
--- a/packages/SystemUI/res/values-lo/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"ປິດ"</item>
     <item msgid="5966994759929723339">"ເປີດ"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"ບໍ່ສາມາດເບິ່ງໄດ້"</item>
+    <item msgid="2478289035899842865">"ປິດ"</item>
+    <item msgid="5137565285664080143">"ເປີດ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index e153fe0..5bcd893 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Pranešimų gaubtas."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Spartieji nustatymai."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Užrakinimo ekranas."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Darbo profilio užrakinimo ekranas"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Uždaryti"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Šviesumas"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Spalvų inversija"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Spalvų taisymas"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Šrifto dydis"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Tvarkyti naudotojus"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Atlikta"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Uždaryti"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ekrano įrašymas"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Nėra pavadinimo"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Budėjimo laikas"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Šrifto dydis"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Padaryti mažesnius"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Padaryti didesnius"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Didinimo langas"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Didinimo lango valdikliai"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Artinti"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nepavyko transliuoti"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nepavyko išsaugoti. Bandykite dar kartą."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nepavyko išsaugoti."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Naudokite bent 4 simbolius"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Naudokite daugiausia 16 simbolių"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijos numeris"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versijos numeris nukopijuotas į iškarpinę."</string>
     <string name="basic_status" msgid="2315371112182658176">"Atidaryti pokalbį"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Pasiekiamas bent vienas įrenginys"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Paliesk. ir palaik. spart. klav."</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Atšaukti"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Apversti dabar"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Užfiksuokite geresnę asmenukę atlenkę telefoną"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Užfiksuoti geresnę asmenukę įjungus priekinį rodinį?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Naudokite galinį fotoaparatą, kad nuotrauka būtų platesnė ir didesnės skyros."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Šis ekranas išsijungs"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Perjungti ekranus dabar"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Atlenkite telefoną"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Perjungti ekranus?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Didesnei raiškai naudokite galinį fotoaparatą"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Kad raiška būtų geresnė, apverskite telefoną"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Lankstomasis įrenginys išlankstomas"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Lankstomasis įrenginys apverčiamas"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Liko akumuliatoriaus įkrovos: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Perjungti į darbo profilį"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Uždaryti"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Užrakinimo ekrano nustatymai"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"„Wi-Fi“ ryšys nepasiekiamas"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Fotoaparatas užblokuotas"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Fotoaparatas ir mikrofonas užblokuoti"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofonas užblokuotas"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioriteto režimas įjungtas"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/tiles_states_strings.xml b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
index 03d98c4..e66f590 100644
--- a/packages/SystemUI/res/values-lt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Išjungta"</item>
     <item msgid="5966994759929723339">"Įjungta"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Nepasiekiama"</item>
+    <item msgid="2478289035899842865">"Išjungta"</item>
+    <item msgid="5137565285664080143">"Įjungta"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 2878f7d..4dcb454 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -187,8 +187,8 @@
     <string name="accessibility_battery_level" msgid="5143715405241138822">"Akumulators: <xliff:g id="NUMBER">%d</xliff:g> procenti"</string>
     <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"Akumulatora uzlādes līmenis: <xliff:g id="PERCENTAGE">%1$d</xliff:g>%%, <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Notiek akumulatora uzlāde, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
-    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Akumulatora uzlādes līmenis: <xliff:g id="PERCENTAGE">%d</xliff:g>%%, uzlāde ir apturēta, lai aizsargātu akumulatoru."</string>
-    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"Akumulatora uzlādes līmenis: <xliff:g id="PERCENTAGE">%1$d</xliff:g>%%, <xliff:g id="TIME">%2$s</xliff:g>, uzlāde ir apturēta, lai aizsargātu akumulatoru."</string>
+    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Akumulatora uzlādes līmenis: <xliff:g id="PERCENTAGE">%d</xliff:g>, uzlāde ir apturēta, lai aizsargātu akumulatoru."</string>
+    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"Akumulatora uzlādes līmenis: <xliff:g id="PERCENTAGE">%1$d</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>, uzlāde ir apturēta, lai aizsargātu akumulatoru."</string>
     <string name="accessibility_overflow_action" msgid="8555835828182509104">"Skatīt visus paziņojumus"</string>
     <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Teletaips ir iespējots."</string>
     <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Zvana signāls — vibrācija."</string>
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Paziņojumu panelis"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Ātrie iestatījumi"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Bloķēšanas ekrāns."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Darba profila bloķēšanas ekrāns"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Aizvērt"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Spilgtums"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Krāsu inversija"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Krāsu korekcija"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Fonta lielums"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Pārvaldīt lietotājus"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Gatavs"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Aizvērt"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ekrāna ierakstīšana"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Nav nosaukuma"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Gaidstāve"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Fonta lielums"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Samazināt"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Palielināt"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Palielināšanas logs"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Palielināšanas loga vadīklas"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Tuvināt"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Radās kļūda. Mēģiniet vēlreiz."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Notiek ielāde"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"planšetdators"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Notiek multivides satura apraide"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Notiek lietotnes <xliff:g id="APP_LABEL">%1$s</xliff:g> apraide"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktīva, pārbaudiet lietotni"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Netika atrasta"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Vadīkla nav pieejama"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nevar apraidīt"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nevar saglabāt. Mēģiniet vēlreiz."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nevar saglabāt."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Izmantojiet vismaz 4 rakstzīmes"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Izmantojiet mazāk nekā 16 rakstzīmes"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijas numurs"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versijas numurs ir kopēts starpliktuvē."</string>
     <string name="basic_status" msgid="2315371112182658176">"Atvērt sarunu"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ir pieejama vismaz viena ierīce."</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pieskarieties saīsnei un turiet."</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Atcelt"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Apvērst tūlīt"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Labākas pašbildes uzņemšana, atlokot tālruni"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vai apvērst uz priekšējo kameru labākai pašbildei?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Lai uzņemtu platāku fotoattēlu ar augstāku izšķirtspēju, izmantojiet aizmugurējo kameru."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Šis ekrāns tiks izslēgts."</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Mainīt ekrānus tagad"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Tālruņa atlocīšana"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Vai mainīt ekrānus?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Lai izmantotu augstāku izšķirtspēju, lietojiet aizmugurējo kameru"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Lai izmantotu augstāku izšķirtspēju, apvērsiet tālruni"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Salokāma ierīce tiek atlocīta"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Salokāma ierīce tiek apgriezta"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Atlikušais uzlādes līmenis: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Pārslēgties uz darba profilu"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Aizvērt"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Bloķēšanas ekrāna iestatījumi"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lv/tiles_states_strings.xml b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
index 6e9264d..d32efec 100644
--- a/packages/SystemUI/res/values-lv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Izslēgts"</item>
     <item msgid="5966994759929723339">"Ieslēgts"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Nav pieejams"</item>
+    <item msgid="2478289035899842865">"Izslēgts"</item>
+    <item msgid="5137565285664080143">"Ieslēgts"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index b7d69cf..e80be92 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Панел за известување"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Брзи поставки."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Заклучи екран."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Работен заклучен екран"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Затвори"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Осветленост"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Инверзија на боите"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Корекција на боите"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Големина на фонтот"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Управувајте со корисниците"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Готово"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Затвори"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"снимање на екранот"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Без наслов"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Подготвеност"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Големина на фонтот"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Намали"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Зголеми"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Прозорец за зголемување"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Контроли на прозорец за зголемување"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Зумирај"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Нешто не е во ред. Обидете се повторно."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Се вчитува"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"таблет"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Емитување на вашите аудиовизуелни содржини"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Се емитува <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Неактивна, провери апликација"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Не е најдено"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Контролата не е достапна"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Не може да се емитува"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не може да се зачува. Обидете се повторно."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не може да се зачува."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Употребете најмалку 4 знаци"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Употребете помалку од 16 знаци"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број на верзија"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Бројот на верзијата е копиран во привремената меморија."</string>
     <string name="basic_status" msgid="2315371112182658176">"Започни разговор"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• достапен е најмалку еден уред"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Допрете и задржете ја кратенката"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Откажи"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Префрли сега"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Отворете го телефонот за подобро селфи"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Да се префрли на предниот екран за подобро селфи?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Користете ја задната камера за поширока фотографија со повисока резолуција."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Екранов ќе се исклучи"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Променете го екранот сега"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Отворете го телефонот"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Да се промени екранот?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Користете ја задната камера за да добиете повисока резолуција"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Отворете го телефонот за да добиете повисока резолуција"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Преклопувачки уред се отклопува"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Преклопувачки уред се врти"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Преостаната батерија: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Префрли се на работен профил"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затвори"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Поставки за заклучен екран"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mk/tiles_states_strings.xml b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
index 96c8a49..8c4459a 100644
--- a/packages/SystemUI/res/values-mk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Исклучено"</item>
     <item msgid="5966994759929723339">"Вклучено"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Недостапно"</item>
+    <item msgid="2478289035899842865">"Исклучено"</item>
+    <item msgid="5137565285664080143">"Вклучено"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 46258cb..6622fb9 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"അറിയിപ്പ് ഷെയ്‌ഡ്."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ദ്രുത ക്രമീകരണങ്ങൾ."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ലോക്ക് സ്‌ക്രീൻ."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"ഔദ്യോഗിക ലോക്ക് സ്ക്രീൻ"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"അവസാനിപ്പിക്കുക"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"തെളിച്ചം"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"നിറം വിപരീതമാക്കൽ"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"നിറം ശരിയാക്കൽ"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"ഫോണ്ട് വലുപ്പം"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ഉപയോക്താക്കളെ മാനേജ് ചെയ്യുക"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"പൂർത്തിയാക്കി"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"അടയ്ക്കുക"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"സ്ക്രീൻ റെക്കോർഡിംഗ്"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"പേരില്ല"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"സ്‌റ്റാൻഡ്‌ബൈ"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ഫോണ്ട് വലുപ്പം"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"ചെറുതാക്കുക"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"വലുതാക്കുക"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"മാഗ്നിഫിക്കേഷൻ വിൻഡോ"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"മാഗ്നിഫിക്കേഷൻ വിൻഡോ നിയന്ത്രണങ്ങൾ"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"സൂം ഇൻ ചെയ്യുക"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ബ്രോഡ്‌കാസ്‌റ്റ് ചെയ്യാനാകുന്നില്ല"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"സംരക്ഷിക്കാൻ കഴിയില്ല. വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"സംരക്ഷിക്കാൻ കഴിയില്ല."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"കുറഞ്ഞത് 4 പ്രതീകങ്ങളെങ്കിലും ഉപയോഗിക്കുക"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16-ൽ കുറവ് പ്രതീകങ്ങൾ ഉപയോഗിക്കുക"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ബിൽഡ് നമ്പർ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ക്ലിപ്പ്ബോർഡിലേക്ക് ബിൽഡ് നമ്പർ പകർത്തി."</string>
     <string name="basic_status" msgid="2315371112182658176">"സംഭാഷണം തുറക്കുക"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ഒരു ഉപകരണമെങ്കിലും ലഭ്യമാണ്"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"സ്പർശിച്ച് പിടിക്കുക കുറുക്കുവഴി"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"റദ്ദാക്കുക"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ഇപ്പോൾ ഫ്ലിപ്പ് ചെയ്യൂ"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"കൂടുതൽ മികച്ച സെൽഫി ലഭിക്കാൻ ഫോൺ അൺഫോൾഡ് ചെയ്യൂ"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"മികച്ച സെൽഫിക്ക് ഫ്രണ്ട് ഡിസ്പ്ലേയിലേക്ക് മാറണോ?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ഉയർന്ന റെസല്യൂഷൻ ഉള്ള, വീതി കൂടിയ ഫോട്ടോയ്ക്ക്, പിൻഭാഗത്തെ ക്യാമറ ഉപയോഗിക്കുക."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ഈ സ്ക്രീൻ ഓഫാകും"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"ഇപ്പോൾ സ്ക്രീനുകൾ മാറുക"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"ഫോൺ അൺഫോൾഡ് ചെയ്യൽ"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"സ്ക്രീനുകൾ മാറണോ?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"ഉയർന്ന റെസല്യൂഷന്, പിൻ ക്യാമറ ഉപയോഗിക്കുക"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ഉയർന്ന റെസല്യൂഷന്, ഫോൺ ഫ്ലിപ്പ് ചെയ്യുക"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ഫോൾഡ് ചെയ്യാവുന്ന ഉപകരണം അൺഫോൾഡ് ആകുന്നു"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ഫോൾഡ് ചെയ്യാവുന്ന ഉപകരണം, കറങ്ങുന്ന വിധത്തിൽ ഫ്ലിപ്പ് ആകുന്നു"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ബാറ്ററി ചാർജ് ശേഷിക്കുന്നു"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ഔദ്യോഗിക പ്രൊഫൈലിലേക്ക് മാറുക"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"അടയ്ക്കുക"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"ലോക്ക് സ്ക്രീൻ ക്രമീകരണം"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"വൈഫൈ ലഭ്യമല്ല"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"ക്യാമറ ബ്ലോക്ക് ചെയ്തിരിക്കുന്നു"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"ക്യാമറയും മൈക്രോഫോണും ബ്ലോക്ക് ചെയ്തിരിക്കുന്നു"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"മൈക്രോഫോൺ ബ്ലോക്ക് ചെയ്തിരിക്കുന്നു"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"മുൻഗണനാ മോഡ് ഓണാണ്"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/tiles_states_strings.xml b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
index 7a07873..62bac5c 100644
--- a/packages/SystemUI/res/values-ml/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"ഓഫാണ്"</item>
     <item msgid="5966994759929723339">"ഓണാണ്"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"ലഭ്യമല്ല"</item>
+    <item msgid="2478289035899842865">"ഓഫാണ്"</item>
+    <item msgid="5137565285664080143">"ഓണാണ്"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 2ef8216..5e875d1 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Мэдэгдлийн хураангуй самбар"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Шуурхай тохиргоо."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Дэлгэц түгжих."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Ажлын түгжигдсэн дэлгэц"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Хаах"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Тодрол"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Өнгө хувиргалт"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Өнгө тохируулга"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Фонтын хэмжээ"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Хэрэглэгчдийг удирдах"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Дууссан"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Хаах"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"дэлгэцийн бичлэг"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Гарчиггүй"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Зогсолтын горим"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Фонтын хэмжээ"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Жижгэрүүлэх"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Томруулах"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Томруулалтын цонх"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Томруулалтын цонхны хяналт"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Томруулах"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Алдаа гарлаа. Дахин оролдоно уу."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Ачаалж байна"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"таблет"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Таны медиаг дамжуулж байна"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g>-г дамжуулж байна"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Идэвхгүй байна, аппыг шалгана уу"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Олдсонгүй"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Хяналт боломжгүй байна"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Нэвтрүүлэх боломжгүй"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Хадгалах боломжгүй. Дахин оролдоно уу."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Хадгалах боломжгүй."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Дор хаяж 4 тэмдэгт ашиглана уу."</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16-аас цөөн тэмдэгт ашиглана уу"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Хийцийн дугаар"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Хийцийн дугаарыг түр санах ойд хуулсан."</string>
     <string name="basic_status" msgid="2315371112182658176">"Харилцан яриаг нээх"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Дор хаяж нэг төхөөрөмж боломжтой"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Товчлолд хүрээд удаан дарна уу"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Цуцлах"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Одоо хөнтрөх"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Илүү сайн селфи хийхийн тулд утсаа дэлгэнэ үү"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Сайн сельфи авахаар урд талын дэлгэц рүү хөнтрөх үү?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Илүү өндөр нягтаршилтай илүү өргөн зураг авахын тулд арын камерыг ашиглана уу."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Энэ дэлгэц унтарна"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Одоо дэлгэцүүдийг сэлгэх"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Утсыг дэлгэх"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Дэлгэцүүдийг сэлгэх үү?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Илүү өндөр нягтрал авах бол ар талын камерыг ашиглана уу"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Илүү өндөр нягтрал авах бол утсыг хөнтөрнө үү"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Эвхэгддэг төхөөрөмжийг дэлгэж байна"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Эвхэгддэг төхөөрөмжийг хөнтөрч байна"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> батарей үлдлээ"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Ажлын профайл руу сэлгэх"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Хаах"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Түгжигдсэн дэлгэцийн тохиргоо"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi боломжгүй байна"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Камерыг блоклосон"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Камер болон микрофоныг блоклосон"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Микрофоныг блоклосон"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Чухал горим асаалттай байна"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/tiles_states_strings.xml b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
index 776c487..33f3596 100644
--- a/packages/SystemUI/res/values-mn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Унтраалттай"</item>
     <item msgid="5966994759929723339">"Асаалттай"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Боломжгүй"</item>
+    <item msgid="2478289035899842865">"Унтраалттай"</item>
+    <item msgid="5137565285664080143">"Асаалттай"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index c4fd4aa..9f3680d 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"सूचना शेड."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"क्विक सेटिंग्ज."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"लॉक स्क्रीन."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"कार्य लॉक स्क्रीन"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"बंद करा"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"चमक"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"कलर इन्व्हर्जन"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"रंग सुधारणा"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"फॉंटचा आकार"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"वापरकर्ते व्यवस्‍थापित करा"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"पूर्ण झाले"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"बंद करा"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"स्क्रीन रेकॉर्डिंग"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"शीर्षक नाही"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टँडबाय"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"फॉंट आकार"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"आणखी लहान करा"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"आणखी मोठे करा"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"मॅग्निफिकेशन विंडो"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"मॅग्निफिकेशन विंडो नियंत्रणे"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"झूम इन करा"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"काहीतरी चूक झाली. पुन्हा प्रयत्न करा."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"लोड करत आहे"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"टॅबलेट"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"तुमचा मीडिया कास्ट करत आहे"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> कास्ट करत आहे"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय, ॲप तपासा"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"आढळले नाही"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"नियंत्रण उपलब्ध नाही"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ब्रॉडकास्ट करू शकत नाही"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"सेव्ह करू शकत नाही. पुन्हा प्रयत्न करा."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"सेव्ह करू शकत नाही."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"किमान चार वर्ण वापरा"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"१६ पेक्षा कमी वर्ण वापरा"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर क्लिपबोर्डवर कॉपी केला."</string>
     <string name="basic_status" msgid="2315371112182658176">"संभाषण उघडा"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• किमान एक डिव्हाइस उपलब्ध करणे"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"स्पर्श करा आणि धरून ठेवा शॉर्टकट"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"रद्द करा"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"आता फ्लिप करा"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"आणखी चांगल्या सेल्फीसाठी फोनबद्दल अधिक जाणून घ्या"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"आणखी चांगल्या सेल्फीसाठी फ्रंट डिस्प्ले वापरायचा का?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"उच्च रेझोल्यूशन असलेल्या विस्तृत फोटोसाठी रीअर कॅमेरा वापरा."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ही स्क्रीन बंद होईल"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"आता स्क्रीन स्विच करा"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"फोन उघडा"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"स्क्रीन स्विच करायच्या का?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"उच्च रेझोल्यूशनसाठी रीअर कॅमेरा वापरा"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"उच्च रेझोल्यूशनसाठी, फोन फ्लिप करा"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्ड करता येण्यासारखे डिव्हाइस अनफोल्ड केले जात आहे"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्ड करता येण्यासारखे डिव्हाइस आजूबाजूला फ्लिप केले जात आहे"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> बॅटरी शिल्लक आहे"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"कार्य प्रोफाइलवर स्विच करा"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"बंद करा"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"लॉक स्क्रीन सेटिंग्ज"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mr/tiles_states_strings.xml b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
index f75f0d0..24d3b47 100644
--- a/packages/SystemUI/res/values-mr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"बंद आहे"</item>
     <item msgid="5966994759929723339">"सुरू आहे"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"उपलब्ध नाही"</item>
+    <item msgid="2478289035899842865">"बंद आहे"</item>
+    <item msgid="5137565285664080143">"सुरू आहे"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index aa3626c..109d519 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Bidai pemberitahuan."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Tetapan pantas."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Kunci skrin."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Skrin kunci kerja"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Tutup"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Kecerahan"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Penyongsangan warna"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Pembetulan warna"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Saiz fon"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Urus pengguna"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Selesai"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Tutup"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"rakaman skrin"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Tiada tajuk"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Tunggu sedia"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Saiz Fon"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Kecilkan"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Besarkan"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Tetingkap Pembesaran"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Kawalan Tetingkap Pembesaran"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zum masuk"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Tidak dapat disiarkan"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Tidak dapat disimpan. Cuba lagi."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Tidak dapat disimpan."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Gunakan sekurang-kurangnya 4 aksara"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Gunakan kurang daripada 16 aksara"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nombor binaan"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nombor binaan disalin ke papan keratan."</string>
     <string name="basic_status" msgid="2315371112182658176">"Buka perbualan"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Sekurang-kurangnya satu peranti tersedia"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pintasan sentuh &amp; tahan"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Batal"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Balikkan sekarang"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Buka telefon untuk swafoto yang lebih baik"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Balikkan ke paparan depan utk swafoto lebih baik?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gunakan kamera menghadap belakang untuk mendapatkan foto yang lebih luas dengan resolusi yang lebih tinggi."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Skrin ini akan dimatikan"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Tukar skrin sekarang"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Buka telefon"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Tukar skrin?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Untuk peleraian lebih tinggi, gunakan kamera belakang"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Untuk peleraian lebih tinggi, balikkan telefon"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Peranti boleh lipat dibuka"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Peranti boleh lipat diterbalikkan"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Bateri tinggal <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Tukar kepada profil kerja"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tutup"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Tetapan skrin kunci"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi tidak tersedia"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera disekat"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera dan mikrofon disekat"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon disekat"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Mod keutamaan dihidupkan"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/tiles_states_strings.xml b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
index 9fa7ab5..07a8426 100644
--- a/packages/SystemUI/res/values-ms/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Mati"</item>
     <item msgid="5966994759929723339">"Hidup"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Tidak tersedia"</item>
+    <item msgid="2478289035899842865">"Mati"</item>
+    <item msgid="5137565285664080143">"Hidup"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 6338abf..4fa84eb 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"အ​ကြောင်းကြားစာအကွက်"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"အမြန်လုပ် အပြင်အဆင်"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"မျက်နှာပြင် သော့ပိတ်ရန်"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"အလုပ်သုံး လော့ခ်မျက်နှာပြင်"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ပိတ်ရန်"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"အလင်းတောက်ပမှု"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"အရောင်ပြောင်းပြန်ပြုလုပ်ရန်"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"အရောင် အမှန်ပြင်ခြင်း"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"ဖောင့်အရွယ်အစား"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"အသုံးပြုသူများ စီမံရန်"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"ပြီးပါပြီ"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ပိတ်ရန်"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"စခရင်ရိုက်ကူးမှု"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"ခေါင်းစဉ် မရှိပါ"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"အသင့်အနေအထား"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ဖောင့်အရွယ်အစား"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"ချုံ့ရန်"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"ချဲ့ရန်"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"ဝင်းဒိုး ချဲ့ခြင်း"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"ဝင်းဒိုး ထိန်းချုပ်မှုများ ချဲ့ခြင်း"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ဇူးမ်ဆွဲရန်"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ထုတ်လွှင့်၍ မရပါ"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"သိမ်း၍မရပါ။ ထပ်စမ်းကြည့်ပါ။"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"သိမ်း၍မရပါ။"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"အနည်းဆုံး အက္ခရာ ၄ လုံး သုံးရန်"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"အက္ခရာ ၁၆ လုံးအောက် သုံးရန်"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"တည်ဆောက်မှုနံပါတ်"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"တည်ဆောက်မှုနံပါတ်ကို ကလစ်ဘုတ်သို့ မိတ္တူကူးပြီးပါပြီ။"</string>
     <string name="basic_status" msgid="2315371112182658176">"စကားဝိုင်းကို ဖွင့်ရန်"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• အနည်းဆုံး စက်တစ်ခုသုံးနိုင်ရမည်"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ဖြတ်လမ်းလင့်ခ်ကို ထိပြီးဖိထားပါ"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"မလုပ်တော့"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ယခုလှည့်လိုက်ပါ"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ပိုကောင်းသော ဆယ်လ်ဖီအတွက် ဖုန်းကိုဖြန့်လိုက်ပါ"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ပိုကောင်းသော ဆယ်လ်ဖီအတွက် ဖန်သားပြင်ကိုလှည့်မလား။"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ပုံရိပ်ပြတ်သားကိန်း ပိုမြင့်ပြီး မြင်ကွင်းပိုကျယ်သည့် ဓာတ်ပုံအတွက် နောက်ဘက်ကင်မရာကို အသုံးပြုပါ။"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ဤဖန်သားပြင်ကို ပိတ်လိုက်မည်"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"စခရင်များ ယခုပြောင်းရန်"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"ဖုန်းကို ဖြန့်လိုက်ပါ"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"စခရင်များ ပြောင်းမလား။"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"ပုံရိပ် ပိုမိုပြတ်သားစေရန် အနောက်ကင်မရာသုံးပါ"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ပုံရိပ် ပိုမိုပြတ်သားစေရန် ဖုန်းကို တစ်ဖက်သို့ လှန်လိုက်ပါ"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ခေါက်နိုင်သောစက်ကို ဖြန့်လိုက်သည်"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ခေါက်နိုင်သောစက်ကို တစ်ဘက်သို့ လှန်လိုက်သည်"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"ဘက်ထရီ <xliff:g id="PERCENTAGE">%s</xliff:g> ကျန်သေးသည်"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"အလုပ်ပရိုဖိုင်သို့ ပြောင်းရန်"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ပိတ်ရန်"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"လော့ခ်မျက်နှာပြင် ဆက်တင်များ"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi မရနိုင်ပါ"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"ကင်မရာကို ပိတ်ထားသည်"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"ကင်မရာနှင့် မိုက်ခရိုဖုန်းကို ပိတ်ထားသည်"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"မိုက်ခရိုဖုန်းကို ပိတ်ထားသည်"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"ဦးစားပေးမုဒ် ဖွင့်ထားသည်"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my/tiles_states_strings.xml b/packages/SystemUI/res/values-my/tiles_states_strings.xml
index 493a7f0..fd375d4 100644
--- a/packages/SystemUI/res/values-my/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-my/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"ပိတ်"</item>
     <item msgid="5966994759929723339">"ဖွင့်"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"မရနိုင်ပါ"</item>
+    <item msgid="2478289035899842865">"ပိတ်"</item>
+    <item msgid="5137565285664080143">"ဖွင့်"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 9a9ca35..7e8e5f0 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Varselskygge."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Hurtiginnstillinger."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Låseskjerm."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Låseskjerm for arbeid"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Lukk"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Lysstyrke"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Fargeinvertering"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Fargekorrigering"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Skriftstørrelse"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Administrer brukere"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Ferdig"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Lukk"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"skjermopptak"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Ingen tittel"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ventemodus"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Skriftstørrelse"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Gjør mindre"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Gjør større"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Forstørringsvindu"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Kontroller for forstørringsvindu"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zoom inn"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Noe gikk galt. Prøv på nytt."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Laster inn"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"nettbrett"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Caster mediene"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Caster <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Sjekk appen"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ikke funnet"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrollen er utilgjengelig"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Kan ikke kringkaste"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kan ikke lagre. Prøv på nytt."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kan ikke lagre."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Bruk minst 4 tegn"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Bruk færre enn 16 tegn"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Delversjonsnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Delversjonsnummeret er kopiert til utklippstavlen."</string>
     <string name="basic_status" msgid="2315371112182658176">"Åpen samtale"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• minst én enhet er tilgjengelig"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Trykk på og hold inne snarveien"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Vend nå"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Brett ut telefonen for å ta bedre selfier"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vil du bruke frontkameraet for bedre selfier?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Bruk det bakovervendte kameraet for å ta bredere bilder med høyere oppløsning."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Denne skjermen slås av"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Bytt skjerm nå"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Brett ut telefonen"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Vil du bytte skjerm?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Bruk baksidekameraet for å få høyere oppløsning"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Brett ut telefonen for å få høyere oppløsning"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En sammenleggbar enhet blir brettet ut"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En sammenleggbar enhet blir snudd"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batteri gjenstår"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Bytt til jobbprofilen"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Lukk"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Innstillinger for låseskjermen"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi er ikke tilgjengelig"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kameraet er blokkert"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kameraet og mikrofonen er blokkert"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofonen er blokkert"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioriteringsmodus er på"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/tiles_states_strings.xml b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
index 6fa902a..e4a81194 100644
--- a/packages/SystemUI/res/values-nb/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Av"</item>
     <item msgid="5966994759929723339">"På"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Utilgjengelig"</item>
+    <item msgid="2478289035899842865">"Av"</item>
+    <item msgid="5137565285664080143">"På"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index e460e26..db4c1a2 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"सूचना कक्ष।"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"द्रुत सेटिङहरू"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"स्क्रीन बन्द गर्नुहोस्।"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"कार्य प्रोफाइलको लक स्क्रिन"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"बन्द गर्नुहोस्"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"उज्यालपन"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"कलर इन्भर्सन"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"कलर करेक्सन"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"फन्टको आकार"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"प्रयोगकर्ताहरू व्यवस्थित गर्नुहोस्"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"भयो"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"बन्द गर्नुहोस्"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"स्क्रिन रेकर्डिङ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"शीर्षक छैन"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्ट्यान्डबाई"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"फन्टको आकार"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"अझ सानो बनाउनुहोस्"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"अझ ठुलो बनाउनुहोस्"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"म्याग्निफिकेसन विन्डो"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"म्याग्निफिकेसन विन्डोका नियन्त्रणहरू"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"जुम इन गर्नुहोस्"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"प्रसारण गर्न सकिएन"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"सेभ गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"सेभ गर्न सकिएन।"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"कम्तीमा ४ वटा वर्ण प्रयोग गर्नुहोस्"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"१६ वटाभन्दा कम वर्ण प्रयोग गर्नुहोस्"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नम्बर"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नम्बर कपी गरी क्लिपबोर्डमा सारियो।"</string>
     <string name="basic_status" msgid="2315371112182658176">"वार्तालाप खोल्नुहोस्"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• कम्तीमा एउटा डिभाइस उपलब्ध छ"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"सर्टकट थिचिराख्नुहोस्"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"रद्द गर्नुहोस्"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"अहिले नै फ्लिप गर्नुहोस्"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"अझ राम्रो सेल्फी खिच्न फोन अनफोल्ड गर्नुहोस्"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"अझ राम्रो सेल्फी खिच्न फ्लिप गरी अगाडिपट्टिको डिस्प्ले प्रयोग गर्ने हो?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"अझ बढी रिजोल्युसन भएको फराकिलो फोटो खिच्न पछाडिपट्टिको क्यामेरा प्रयोग गर्नुहोस्।"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ यो स्क्रिन अफ हुने छ"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"अहिले नै स्क्रिन बदल्नुहोस्"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"फोन अनफोल्ड गर्नुहोस्"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"स्क्रिनहरू बदल्ने हो?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"उच्च रिजोल्युसनको सेल्फी खिच्न पछाडिको क्यामेरा प्रयोग गर्नुहोस्"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"उच्च रिजोल्युसनको सेल्फी खिच्न फोन फ्लिप गर्नुहोस्"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"फोल्ड गर्न मिल्ने डिभाइस अनफोल्ड गरेको देखाइएको एनिमेसन"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"फोल्ड गर्न मिल्ने डिभाइस यताउता पल्टाएर देखाइएको एनिमेसन"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ब्याट्री बाँकी छ"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"कार्य प्रोफाइल प्रयोग गर्नुहोस्"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"बन्द गर्नुहोस्"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"लक स्क्रिनसम्बन्धी सेटिङ"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi उपलब्ध छैन"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"क्यामेरा ब्लक गरिएको छ"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"क्यामेरा र माइक्रोफोन ब्लक गरिएको छ"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"माइक्रोफोन ब्लक गरिएको छ"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"प्राथमिकता मोड अन छ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/tiles_states_strings.xml b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
index 17193ba..5cf91e5 100644
--- a/packages/SystemUI/res/values-ne/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"अफ"</item>
     <item msgid="5966994759929723339">"अन"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"उपलब्ध छैन"</item>
+    <item msgid="2478289035899842865">"अफ छ"</item>
+    <item msgid="5137565285664080143">"अन छ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 8d67715..28a78e1 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Meldingenpaneel."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Snelle instellingen."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Vergrendelscherm."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Vergrendelscherm voor werk"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Sluiten"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Helderheid"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Kleurinversie"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Kleurcorrectie"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Lettergrootte"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gebruikers beheren"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Klaar"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Sluiten"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"schermopname"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Geen titel"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stand-by"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Lettergrootte"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Verkleinen"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Vergroten"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Vergrotingsvenster"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Bediening van vergrotingsvenster"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Inzoomen"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Kan niet uitzenden"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kan niet opslaan. Probeer het opnieuw."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kan niet opslaan."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Gebruik minstens 4 tekens"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Gebruik minder dan 16 tekens"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummer naar klembord gekopieerd."</string>
     <string name="basic_status" msgid="2315371112182658176">"Gesprek openen"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Er is ten minste één apparaat beschikbaar"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Houd de sneltoets ingedrukt"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuleren"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Nu omkeren"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Klap de telefoon open voor een betere selfie"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Omkeren naar scherm voorkant voor een betere selfie?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gebruik de camera aan de achterzijde voor een bredere foto met hogere resolutie."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Dit scherm gaat uit"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Wissel nu van scherm"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Telefoon openklappen"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Van scherm wisselen?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Gebruik de camera aan de achterzijde voor een hogere resolutie"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Draai de telefoon om voor een hogere resolutie"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Opvouwbaar apparaat wordt uitgevouwen"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Opvouwbaar apparaat wordt gedraaid"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Nog <xliff:g id="PERCENTAGE">%s</xliff:g> batterijlading"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Overschakelen naar werkprofiel"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sluiten"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Instellingen vergrendelscherm"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi niet beschikbaar"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Camera geblokkeerd"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Camera en microfoon geblokkeerd"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Microfoon geblokkeerd"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioriteitsmodus aan"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/tiles_states_strings.xml b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
index fbccd78..592ecf5 100644
--- a/packages/SystemUI/res/values-nl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Uit"</item>
     <item msgid="5966994759929723339">"Aan"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Niet beschikbaar"</item>
+    <item msgid="2478289035899842865">"Uit"</item>
+    <item msgid="5137565285664080143">"Aan"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 992cd86..d3ce6fc 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"ବିଜ୍ଞପ୍ତି ଶେଡ୍‍।"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"କ୍ୱିକ୍ ସେଟିଂସ୍।"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ଲକ୍‌ ସ୍କ୍ରୀନ୍‌।"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"ୱର୍କ ଲକ୍‍ ସ୍କ୍ରୀନ୍‍"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ବନ୍ଦ କରନ୍ତୁ"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ଉଜ୍ଜ୍ୱଳତା"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ରଙ୍ଗ ଇନଭାର୍ସନ"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"ରଙ୍ଗ ସଂଶୋଧନ"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"ଫଣ୍ଟର ଆକାର"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ୟୁଜରମାନଙ୍କୁ ପରିଚାଳନା କରନ୍ତୁ"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"ହୋଇଗଲା"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ବନ୍ଦ କରନ୍ତୁ"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ସ୍କ୍ରିନ ରେକର୍ଡିଂ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"କୌଣସି ଶୀର୍ଷକ ନାହିଁ"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ଷ୍ଟାଣ୍ଡବାଏ"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ଫଣ୍ଟର ଆକାର"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"ଛୋଟ କରନ୍ତୁ"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"ବହୁତ ବଡ଼ କରନ୍ତୁ"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ୱିଣ୍ଡୋ"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ୱିଣ୍ଡୋ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ଜୁମ୍ ଇନ୍ କରନ୍ତୁ"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"କିଛି ତ୍ରୁଟି ହୋଇଛି। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"ଲୋଡ ହେଉଛି"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ଟାବଲେଟ"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"ଆପଣଙ୍କ ମିଡିଆକୁ କାଷ୍ଟ କରାଯାଉଛି"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g>କୁ କାଷ୍ଟ କରାଯାଉଛି"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"ନିଷ୍କ୍ରିୟ ଅଛି, ଆପ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"ମିଳିଲା ନାହିଁ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"ନିୟନ୍ତ୍ରଣ ଉପଲବ୍ଧ ନାହିଁ"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ବ୍ରଡକାଷ୍ଟ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ସେଭ କରାଯାଇପାରିଲା ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ସେଭ କରାଯାଇପାରିଲା ନାହିଁ।"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"ଅତିକମରେ 4ଟି କେରେକ୍ଟର ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16ଟିରୁ କମ କେରେକ୍ଟର ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ବିଲ୍ଡ ନମ୍ୱର"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"କ୍ଲିପବୋର୍ଡକୁ କପି କରାଯାଇଥିବା ବିଲ୍ଡ ନମ୍ୱର।"</string>
     <string name="basic_status" msgid="2315371112182658176">"ବାର୍ତ୍ତାଳାପ ଖୋଲନ୍ତୁ"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ଅତିକମରେ ଗୋଟିଏ ଡିଭାଇସ ଉପଲବ୍ଧ ଅଛି"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ସର୍ଟକଟକୁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ବାତିଲ କରନ୍ତୁ"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ବର୍ତ୍ତମାନ ଫ୍ଲିପ କରନ୍ତୁ"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ଏକ ଉନ୍ନତ ସେଲ୍ଫି ପାଇଁ ଫୋନକୁ ଅନଫୋଲ୍ଡ କରନ୍ତୁ"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ଏକ ଉନ୍ନତ ସେଲ୍ଫି ପାଇଁ ସାମ୍ନା ଡିସପ୍ଲେକୁ ଫ୍ଲିପ କରିବେ?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ଉଚ୍ଚ ରିଜୋଲ୍ୟୁସନ ସହ ଅଧିକ ଚଉଡ଼ାର ଏକ ଫଟୋ ନେବା ପାଇଁ ପଛ-ପଟର କେମେରା ବ୍ୟବହାର କରନ୍ତୁ।"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ଏହି ସ୍କ୍ରିନ ବନ୍ଦ ହୋଇଯିବ"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"ବର୍ତ୍ତମାନ ସ୍କ୍ରିନ ସ୍ୱିଚ କରନ୍ତୁ"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"ଫୋନକୁ ଅନଫୋଲ୍ଡ କରନ୍ତୁ"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"ସ୍କ୍ରିନ ସ୍ୱିଚ କରିବେ?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"ଉଚ୍ଚ ରିଜୋଲ୍ୟୁସନ ପାଇଁ ପଛ କେମେରା ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ଉଚ୍ଚ ରିଜୋଲ୍ୟୁସନ ପାଇଁ ଫୋନକୁ ଫ୍ଲିପ କରନ୍ତୁ"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଅନଫୋଲ୍ଡ କରାଯାଉଛି"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ଫୋଲ୍ଡ କରାଯାଇପାରୁଥିବା ଡିଭାଇସକୁ ଫ୍ଲିପ କରାଯାଉଛି"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ବେଟେରୀ ଚାର୍ଜ ବାକି ଅଛି"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ୱାର୍କ ପ୍ରୋଫାଇଲକୁ ସ୍ୱିଚ କରନ୍ତୁ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"ଲକ ସ୍କ୍ରିନ ସେଟିଂସ"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"ୱାଇ-ଫାଇ ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"କେମେରାକୁ ବ୍ଲକ କରାଯାଇଛି"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"କେମେରା ଏବଂ ମାଇକ୍ରୋଫୋନକୁ ବ୍ଲକ କରାଯାଇଛି"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"ମାଇକ୍ରୋଫୋନକୁ ବ୍ଲକ କରାଯାଇଛି"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"ପ୍ରାୟୋରିଟି ମୋଡ ଚାଲୁ ଅଛି"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-or/tiles_states_strings.xml b/packages/SystemUI/res/values-or/tiles_states_strings.xml
index acaa3fb..d362c65f 100644
--- a/packages/SystemUI/res/values-or/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-or/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"ବନ୍ଦ ଅଛି"</item>
     <item msgid="5966994759929723339">"ଚାଲୁ ଅଛି"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"ଅନୁପଲବ୍ଧ"</item>
+    <item msgid="2478289035899842865">"ବନ୍ଦ ଅଛି"</item>
+    <item msgid="5137565285664080143">"ଚାଲୁ ଅଛି"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index c814159..70e15b8 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"ਸੂਚਨਾ ਸ਼ੇਡ।"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ।"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">" ਲਾਕ  ਸਕ੍ਰੀਨ।"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"ਕਾਰਜ-ਸਥਾਨ  ਲਾਕ  ਸਕ੍ਰੀਨ"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ਬੰਦ ਕਰੋ"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ਚਮਕ"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ਰੰਗ ਪਲਟਨਾ"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"ਰੰਗ ਸੁਧਾਈ"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"ਫੌਂਟ ਦਾ ਆਕਾਰ"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ਵਰਤੋਂਕਾਰਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"ਹੋ ਗਿਆ"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ਬੰਦ ਕਰੋ"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"ਕੋਈ ਸਿਰਲੇਖ ਨਹੀਂ"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ਸਟੈਂਡਬਾਈ"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ਫ਼ੌਂਟ ਦਾ ਆਕਾਰ"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"ਛੋਟਾ ਕਰੋ"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"ਵੱਡਾ ਕਰੋ"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"ਵੱਡਦਰਸ਼ੀਕਰਨ Window"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"ਵੱਡਦਰਸ਼ੀਕਰਨ Window ਦੇ ਕੰਟਰੋਲ"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ਜ਼ੂਮ ਵਧਾਓ"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"ਕੋਈ ਗੜਬੜ ਹੋ ਗਈ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"ਲੋਡ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ਟੈਬਲੈੱਟ"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"ਤੁਹਾਡੇ ਮੀਡੀਆ ਨੂੰ ਕਾਸਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> \'ਤੇ ਕਾਸਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"ਅਕਿਰਿਆਸ਼ੀਲ, ਐਪ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"ਨਹੀਂ ਮਿਲਿਆ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"ਕੰਟਰੋਲ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ਪ੍ਰਸਾਰਨ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"ਘੱਟੋ-ਘੱਟ 4 ਅੱਖਰ-ਚਿੰਨ੍ਹ ਵਰਤੋ"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16 ਤੋਂ ਘੱਟ ਅੱਖਰ-ਚਿੰਨ੍ਹ ਵਰਤੋ"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ਬਿਲਡ ਨੰਬਰ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ਬਿਲਡ ਨੰਬਰ ਨੂੰ ਕਲਿੱਪਬੋਰਡ \'ਤੇ ਕਾਪੀ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="basic_status" msgid="2315371112182658176">"ਗੱਲਬਾਤ ਖੋਲ੍ਹੋ"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ਘੱਟੋ-ਘੱਟ ਇੱਕ ਡੀਵਾਈਸ ਉਪਲਬਧ ਹੈ"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ਸ਼ਾਰਟਕੱਟ ਨੂੰ ਸਪਰਸ਼ ਕਰ ਕੇ ਰੱਖੋ"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ਰੱਦ ਕਰੋ"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ਹੁਣੇ ਫਲਿੱਪ ਕਰੋ"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ਬਿਹਤਰ ਸੈਲਫ਼ੀ ਲਈ ਫ਼ੋਨ ਨੂੰ ਖੋਲ੍ਹੋ"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"ਕੀ ਬਿਹਤਰ ਸੈਲਫ਼ੀ ਲਈ ਅਗਲੀ ਡਿਸਪਲੇ \'ਤੇ ਫਲਿੱਪ ਕਰਨਾ ਹੈ?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ਉੱਚ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਵਾਲੀ ਜ਼ਿਆਦਾ ਚੌੜੀ ਫ਼ੋਟੋ ਲਈ ਪਿਛਲੇ ਕੈਮਰੇ ਦੀ ਵਰਤੋਂ ਕਰੋ।"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ਇਹ ਸਕ੍ਰੀਨ ਬੰਦ ਹੋ ਜਾਵੇਗੀ"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"ਹੁਣ ਸਕ੍ਰੀਨਾਂ ਨੂੰ ਸਵਿੱਚ ਕਰੋ"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"ਫ਼ੋਨ ਨੂੰ ਖੋਲ੍ਹੋ"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"ਕੀ ਸਕ੍ਰੀਨਾਂ ਨੂੰ ਸਵਿੱਚ ਕਰਨਾ ਹੈ?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"ਉੱਚ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਲਈ, ਪਿਛਲਾ ਕੈਮਰਾ ਵਰਤੋ"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ਉੱਚ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਲਈ, ਫ਼ੋਨ ਨੂੰ ਫਲਿੱਪ ਕਰੋ"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"ਮੋੜਨਯੋਗ ਡੀਵਾਈਸ ਨੂੰ ਖੋਲ੍ਹਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"ਮੋੜਨਯੋਗ ਡੀਵਾਈਸ ਨੂੰ ਆਲੇ-ਦੁਆਲੇ ਫਲਿੱਪ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ਬੈਟਰੀ ਬਾਕੀ"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ \'ਤੇ ਜਾਓ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ਬੰਦ ਕਰੋ"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"ਲਾਕ ਸਕ੍ਰੀਨ ਸੈਟਿੰਗਾਂ"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pa/tiles_states_strings.xml b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
index 9653b92..f249afb 100644
--- a/packages/SystemUI/res/values-pa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"ਬੰਦ"</item>
     <item msgid="5966994759929723339">"ਚਾਲੂ"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"ਉਪਲਬਧ ਨਹੀਂ"</item>
+    <item msgid="2478289035899842865">"ਬੰਦ"</item>
+    <item msgid="5137565285664080143">"ਚਾਲੂ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 025dd66..b67bd00 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Obszar powiadomień."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Szybkie ustawienia."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Ekran blokady."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Ekran blokady wyświetlany podczas działania"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Zamknij"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Jasność"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Odwrócenie kolorów"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Korekcja kolorów"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Rozmiar czcionki"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Zarządzaj użytkownikami"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Gotowe"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zamknij"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"nagrywanie ekranu"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez tytułu"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Tryb gotowości"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Rozmiar czcionki"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Pomniejsz"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Powiększ"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Okno powiększenia"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Elementy sterujące okna powiększenia"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Powiększ"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Coś poszło nie tak. Spróbuj ponownie."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Wczytuję"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Przesyłanie multimediów"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Przesyłanie treści z aplikacji <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Nieaktywny, sprawdź aplikację"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nie znaleziono"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Element jest niedostępny"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nie można przesyłać"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nie można zapisać. Spróbuj ponownie."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nie można zapisać."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Wpisz co najmniej 4 znaki"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Wpisz mniej niż 16 znaków"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numer kompilacji"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numer kompilacji został skopiowany do schowka."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otwarta rozmowa"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Dostępne jest co najmniej 1 urządzenie."</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Skrót – naciśnij i przytrzymaj"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anuluj"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Przełącz teraz"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Rozłóż telefon, aby uzyskać lepszej jakości selfie"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Przełączyć na przedni wyświetlacz?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Użyj tylnego aparatu, aby zrobić szersze zdjęcie o większej rozdzielczości."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* Ten ekran się wyłączy"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Przełącz ekrany teraz"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Otwieranie telefonu"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Przełączyć ekrany?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Użyj tylnego aparatu, aby uzyskać wyższą rozdzielczość"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Odwróć telefon, aby uzyskać wyższą rozdzielczość"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Składane urządzenie jest rozkładane"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Składane urządzenie jest obracane"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Pozostało <xliff:g id="PERCENTAGE">%s</xliff:g> baterii"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Przełącz na profil służbowy"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zamknij"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Ustawienia ekranu blokady"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
index 50650986..c73cbed 100644
--- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Wyłączono"</item>
     <item msgid="5966994759929723339">"Włączono"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Brak dostępu"</item>
+    <item msgid="2478289035899842865">"Wyłączono"</item>
+    <item msgid="5137565285664080143">"Włączono"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 39feb08..f3ef152 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Aba de notificações."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Configurações rápidas."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Tela de bloqueio."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Tela de bloqueio de trabalho"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Fechar"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brilho"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversão de cores"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Correção de cor"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Tamanho da fonte"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gerenciar usuários"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Concluído"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Fechar"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"gravação de tela"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sem título"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Em espera"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Tamanho da fonte"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Diminuir"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Aumentar"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Janela de ampliação"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Controles da janela de ampliação"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Aumentar zoom"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Não foi possível fazer a transmissão"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Falha ao salvar. Tente de novo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Falha ao salvar."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Use pelo menos 4 caracteres"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Use menos de 16 caracteres"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Pelo menos um dispositivo está disponível"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Toque e pressione o atalho"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Virar agora"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Abra o smartphone para tirar uma selfie melhor"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Usar o display frontal para tirar uma selfie melhor?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use a câmera traseira para tirar uma foto mais ampla e com maior resolução."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta tela vai ser desativada"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Trocar de tela agora"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Abra o smartphone"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Trocar de tela?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Para uma resolução maior, use a câmera traseira"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para uma resolução maior, vire o smartphone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável sendo aberto"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável sendo virado"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Bateria restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Alternar para o perfil de trabalho"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Configurações de tela de bloqueio"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi indisponível"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Câmara bloqueada"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Câmera e microfone bloqueados"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Microfone bloqueado"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Modo de prioridade ativado"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
index ebe67d8..28c07f4 100644
--- a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Desativado"</item>
     <item msgid="5966994759929723339">"Ativado"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Indisponível"</item>
+    <item msgid="2478289035899842865">"Desativado"</item>
+    <item msgid="5137565285664080143">"Ativado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 98f063f..ac7886c 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Painel de notificações."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Definições rápidas."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Ecrã de bloqueio."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Ecrã de bloqueio de trabalho"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Fechar"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brilho"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversão de cores"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Correção da cor"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Tamanho do tipo de letra"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gerir utilizadores"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Concluído"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Fechar"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"gravação de ecrã"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sem título"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Modo de espera"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Tamanho do tipo de letra"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Diminuir"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Aumentar"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Janela de ampliação"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Controlos da janela de ampliação"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Aumentar zoom"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Não é possível transmitir"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Não é possível guardar. Tente novamente."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Não é possível guardar."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Use, pelo menos, 4 carateres"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Use menos de 16 carateres"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da compilação"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número da compilação copiado para a área de transferência."</string>
     <string name="basic_status" msgid="2315371112182658176">"Abrir conversa"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Está disponível, pelo menos, um dispositivo"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Toque sem soltar no atalho"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Inverter agora"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desdobre o telemóvel para uma selfie melhor"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Inverter para ecrã frontal para uma selfie melhor?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use a câmara traseira para uma foto mais ampla com uma resolução superior."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Este ecrã vai ser desligado"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Mudar de ecrã agora"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Desdobre o telemóvel"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Mudar de ecrã?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Para uma resolução superior, use a câmara traseira"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para uma resolução superior, inverta o telemóvel"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável a ser desdobrado"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável a ser virado ao contrário"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> de bateria restante"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Mudar para perfil de trabalho"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Definições do ecrã de bloqueio"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi indisponível"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Câmara bloqueada"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Câmara e microfone bloqueados"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Microfone bloqueado"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Modo Prioridade ativado"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
index bda7473..b58b848 100644
--- a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Desativado"</item>
     <item msgid="5966994759929723339">"Ativado"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Indisponível"</item>
+    <item msgid="2478289035899842865">"Desativado"</item>
+    <item msgid="5137565285664080143">"Ativado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 39feb08..f3ef152 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Aba de notificações."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Configurações rápidas."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Tela de bloqueio."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Tela de bloqueio de trabalho"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Fechar"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brilho"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversão de cores"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Correção de cor"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Tamanho da fonte"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gerenciar usuários"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Concluído"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Fechar"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"gravação de tela"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sem título"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Em espera"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Tamanho da fonte"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Diminuir"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Aumentar"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Janela de ampliação"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Controles da janela de ampliação"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Aumentar zoom"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Não foi possível fazer a transmissão"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Falha ao salvar. Tente de novo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Falha ao salvar."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Use pelo menos 4 caracteres"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Use menos de 16 caracteres"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Pelo menos um dispositivo está disponível"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Toque e pressione o atalho"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Virar agora"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Abra o smartphone para tirar uma selfie melhor"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Usar o display frontal para tirar uma selfie melhor?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Use a câmera traseira para tirar uma foto mais ampla e com maior resolução."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta tela vai ser desativada"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Trocar de tela agora"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Abra o smartphone"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Trocar de tela?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Para uma resolução maior, use a câmera traseira"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para uma resolução maior, vire o smartphone"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo dobrável sendo aberto"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo dobrável sendo virado"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Bateria restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Alternar para o perfil de trabalho"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Configurações de tela de bloqueio"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi indisponível"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Câmara bloqueada"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Câmera e microfone bloqueados"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Microfone bloqueado"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Modo de prioridade ativado"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/tiles_states_strings.xml b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
index ebe67d8..28c07f4 100644
--- a/packages/SystemUI/res/values-pt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Desativado"</item>
     <item msgid="5966994759929723339">"Ativado"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Indisponível"</item>
+    <item msgid="2478289035899842865">"Desativado"</item>
+    <item msgid="5137565285664080143">"Ativado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index bf26016..4bdbbc4 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Fereastră pentru notificări."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Setări rapide."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Ecranul de blocare."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Ecran de blocare pentru serviciu"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Închide"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Luminozitate"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inversarea culorilor"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Corecția culorii"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Dimensiunea fontului"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Gestionează utilizatorii"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Terminat"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Închide"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"înregistrare de ecran"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Fără titlu"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Standby"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Dimensiunea fontului"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Micșorează"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Mărește"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Fereastra de mărire"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Comenzi pentru fereastra de mărire"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Mărește"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"A apărut o eroare. Încearcă din nou."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Se încarcă"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tabletă"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Se proiectează conținutul media"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Se proiectează <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactiv, verifică aplicația"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nu s-a găsit"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Comanda este indisponibilă"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nu se poate transmite"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nu se poate salva. Încearcă din nou."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nu se poate salva."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Folosește minimum 4 caractere."</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Folosește maximum 16 caractere"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numărul versiunii"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numărul versiunii s-a copiat în clipboard."</string>
     <string name="basic_status" msgid="2315371112182658176">"Deschide conversația"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Este disponibil cel puțin un dispozitiv"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Atinge lung comanda rapidă"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anulează"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Întoarce-l acum"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Desfă telefonul pentru un selfie mai bun"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Comuți la ecranul frontal pentru un selfie mai bun?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Folosește camera posterioară pentru o fotografie mai lată, cu rezoluție mai mare."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Acest ecran se va dezactiva"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Schimbă ecranul acum"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Deschide telefonul"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Schimbi ecranul?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Pentru o rezoluție mai mare, folosește camera foto posterioară"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Pentru o rezoluție mai mare, deschide telefonul"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispozitiv pliabil care este desfăcut"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispozitiv pliabil care este întors"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> baterie rămasă"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Comută la profilul de serviciu"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Închide"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Setările ecranului de blocare"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Conexiune Wi-Fi indisponibilă"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Camera foto a fost blocată"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Camera foto și microfonul sunt blocate"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Microfonul a fost blocat"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Modul Cu prioritate este activat"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/tiles_states_strings.xml b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
index 7b7bb3a..5a5eb9f 100644
--- a/packages/SystemUI/res/values-ro/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Dezactivat"</item>
     <item msgid="5966994759929723339">"Activat"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Indisponibil"</item>
+    <item msgid="2478289035899842865">"Dezactivat"</item>
+    <item msgid="5137565285664080143">"Activat"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 1a10a79..f1a0cc3 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Панель уведомлений"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Быстрые настройки"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Экран блокировки."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Заблокировано"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Закрыть"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Яркость"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Инверсия цветов"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Коррекция цвета"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Размер шрифта"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Управление пользователями"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Готово"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Закрыть"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"запись экрана"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Без названия"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Переход в режим ожидания"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Размер шрифта"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Уменьшить"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Увеличить"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Окно увеличения"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Настройки окна увеличения"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Увеличить"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Не удалось запустить трансляцию"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не удалось сохранить. Повторите попытку."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не удалось сохранить."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Минимальное количество символов – 4"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Максимальное количество символов – 16"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер сборки"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Номер сборки скопирован в буфер обмена."</string>
     <string name="basic_status" msgid="2315371112182658176">"Открытый чат"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Доступно хотя бы одно устройство."</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Нажмите и удерживайте ярлык"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Отмена"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Перевернуть сейчас"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Разложите телефон, чтобы селфи получилось лучше"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Перейти на передний экран?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Используйте основную камеру с широкоугольным объективом и высоким разрешением."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Этот экран отключится"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Переключиться на другой экран"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Разложите телефон"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Переключиться на другой экран?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Используйте основную камеру, чтобы делать снимки с более высоким разрешением."</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Переверните телефон и используйте основную камеру, чтобы делать снимки с более высоким разрешением."</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складное устройство в разложенном виде"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Перевернутое складное устройство"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Уровень заряда батареи: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Перейти в рабочий профиль"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрыть"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Настройки блокировки экрана"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Функция Wi-Fi недоступна"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Камера заблокирована"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Камера и микрофон заблокированы"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Микрофон заблокирован"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Режим \"Только важные\" включен"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/tiles_states_strings.xml b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
index 6255bd8..cd14079 100644
--- a/packages/SystemUI/res/values-ru/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Отключено"</item>
     <item msgid="5966994759929723339">"Включено"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Недоступно"</item>
+    <item msgid="2478289035899842865">"Выключено"</item>
+    <item msgid="5137565285664080143">"Включено"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 217a6e3..c335189 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"දැනුම්දීම් ආවරණය."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ක්ෂණික සැකසීම්."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"අගුළු තිරය."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"කාර්යාල අගුලු තිරය"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"වසන්න"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"දීප්තිමත් බව"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"වර්ණ අපවර්තනය"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"වර්ණ නිවැරදි කිරීම"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"අකුරු විශාලත්වය"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"පරිශීලකයන් කළමනාකරණය කරන්න"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"නිමයි"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"වසන්න"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"තිර පටිගත කිරීම"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"මාතෘකාවක් නැත"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"පොරොත්තු"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"අකුරු විශාලත්වය"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"වඩා කුඩා කරන්න"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"වඩා විශාල කරන්න"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"විශාලන කවුළුව"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"විශාලනය කිරීමේ කවුළු පාලන"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"විශාලනය වැඩි කරන්න"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"යම් දෙයක් වැරදිණි. නැවත උත්සාහ කරන්න."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"පූරණය වේ"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ටැබ්ලටය"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"ඔබේ මාධ්‍ය විකාශය කිරීම"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> විකාශය කරමින්"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"අක්‍රියයි, යෙදුම පරීක්ෂා කරන්න"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"හමු නොවිණි"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"පාලනය ලබා ගත නොහැකිය"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"විකාශනය කළ නොහැකිය"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"සුරැකිය නොහැකිය. නැවත උත්සාහ කරන්න."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"සුරැකිය නොහැකිය."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"අවම වශයෙන් අනුලකුණු 4ක් භාවිතා කරන්න"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"අනුලකුණු 16කට වඩා අඩුවෙන් භාවිතා කරන්න"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"නිමැවුම් අංකය"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"නිමැවුම් අංකය පසුරු පුවරුවට පිටපත් කරන ලදි."</string>
     <string name="basic_status" msgid="2315371112182658176">"සංවාදය විවෘත කරන්න"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• අවම වශයෙන් එක උපාංගයක් ලැබේ"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ස්පර්ශ කර අල්ලා සිටීමේ කෙටිමඟ"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"අවලංගු කරන්න"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"දැන් පෙරළන්න"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"වඩා හොඳ සෙල්ෆියක් සඳහා දුරකථනය දිගහරින්න"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"වඩා හොඳ සෙල්ෆියක් සඳහා ඉදිරිපස සංදර්ශකයට පෙරළන්න ද?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ඉහළ විභේදන සහිත පුළුල් ඡායාරූපයක් සඳහා පසුපසට මුහුණලා ඇති කැමරාව භාවිතා කරන්න."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ මෙම තිරය ක්‍රියා විරහිත වනු ඇත"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"දැන් තිර මාරු කරන්න"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"දුරකථනය දිගහරින්න"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"තිර මාරු කරන්න ද?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"ඉහළ විභේදනය සඳහා, පසුපස කැමරාව භාවිතා කරන්න"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"ඉහළ විභේදනය සඳහා, දුරකථනය හරවන්න"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"දිග හැරෙමින් පවතින නැමිය හැකි උපාංගය"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"වටා පෙරළෙමින් තිබෙන නැමිය හැකි උපාංගය"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> බැටරිය ඉතිරිව ඇත"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"කාර්යාල පැතිකඩ වෙත මාරු වන්න"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"වසන්න"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"අගුළු තිර සැකසීම්"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi ලද නොහැක"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"කැමරාව අවහිරයි"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"කැමරාව සහ මයික්‍රොෆෝනය අවහිරයි"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"මයික්‍රොෆෝනය අවහිරයි"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"ප්‍රමුඛතා මාදිලිය සක්‍රීයයි"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/tiles_states_strings.xml b/packages/SystemUI/res/values-si/tiles_states_strings.xml
index 327e0b9..fcd768b 100644
--- a/packages/SystemUI/res/values-si/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-si/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"ක්‍රියාවිරහිතයි"</item>
     <item msgid="5966994759929723339">"ක්‍රියාත්මකයි"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"නොමැත"</item>
+    <item msgid="2478289035899842865">"ක්‍රියාවිරහිතයි"</item>
+    <item msgid="5137565285664080143">"ක්‍රියාත්මකයි"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index f6f7b37..1174755f 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Panel upozornení."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Rýchle nastavenia."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Uzamknutá obrazovka"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Uzamknutá obrazovka pracovného profilu"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Zavrieť"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Jas"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inverzia farieb"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Úprava farieb"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Veľkosť písma"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Spravovať používateľov"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Hotovo"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zavrieť"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"nahrávanie obrazovky"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez názvu"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Pohotovostný režim"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Veľkosť písma"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Zmenšiť"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Zväčšiť"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Okno priblíženia"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Ovládacie prvky okna priblíženia"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Priblížiť"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nedá sa vysielať"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nedá sa uložiť. Skúste to znova."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nedá sa uložiť."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Použite aspoň štyri znaky"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Použite menej než 16 znakov"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo zostavy"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Číslo zostavy bolo skopírované do schránky."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otvorená konverzácia"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• K dispozícii je minimálne jedno zariadenie"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pridržte skratku"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Zrušiť"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Otočiť"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Ak chcete lepšie selfie, rozložte telefón"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Otočiť na prednú obrazovku pre lepšie selfie?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Pomocou zadného fotoaparátu vytvorte širšiu fotku s vyšším rozlíšením."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Táto obrazovka sa vypne"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Prepnite obrazovky"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Rozloženie telefónu"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Chcete prepnúť obrazovky?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Ak chcete vyššie rozlíšenie, použite zadnú kameru"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Ak chcete vyššie rozlíšenie, prevráťte telefón"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozloženie skladacieho zariadenia"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Prevrátenie skladacieho zariadenia"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Zostáva <xliff:g id="PERCENTAGE">%s</xliff:g> batérie"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Prepnúť na pracovný profil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zavrieť"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Nastavenia uzamknutej obrazovky"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi‑Fi nie je k dispozícii"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera je blokovaná"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera a mikrofón sú blokované"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofón je blokovaný"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Režim priority je zapnutý"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/tiles_states_strings.xml b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
index 3cbde1c..660f85d 100644
--- a/packages/SystemUI/res/values-sk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Vypnuté"</item>
     <item msgid="5966994759929723339">"Zapnuté"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Nedostupné"</item>
+    <item msgid="2478289035899842865">"Vypnuté"</item>
+    <item msgid="5137565285664080143">"Zapnuté"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index c188d45..ffb74ae 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -187,8 +187,8 @@
     <string name="accessibility_battery_level" msgid="5143715405241138822">"Baterija <xliff:g id="NUMBER">%d</xliff:g> odstotkov."</string>
     <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"Baterija je napolnjena na <xliff:g id="PERCENTAGE">%1$d</xliff:g> %% – <xliff:g id="TIME">%2$s</xliff:g>."</string>
     <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Baterija se polni, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> odstotkov."</string>
-    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Baterija je napolnjena na <xliff:g id="PERCENTAGE">%d</xliff:g> %% – zaradi zaščite baterije je polnjenje začasno zaustavljeno."</string>
-    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"Baterija je napolnjena na <xliff:g id="PERCENTAGE">%1$d</xliff:g> %% – <xliff:g id="TIME">%2$s</xliff:g> je zaradi zaščite baterije polnjenje začasno zaustavljeno."</string>
+    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Baterija je napolnjena na <xliff:g id="PERCENTAGE">%d</xliff:g> odstotkov. Zaradi zaščite baterije je polnjenje začasno zaustavljeno."</string>
+    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"Baterija je napolnjena na <xliff:g id="PERCENTAGE">%1$d</xliff:g> odstotkov – <xliff:g id="TIME">%2$s</xliff:g>. Zaradi zaščite baterije je polnjenje začasno zaustavljeno."</string>
     <string name="accessibility_overflow_action" msgid="8555835828182509104">"Prikaži vsa obvestila"</string>
     <string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter omogočen."</string>
     <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Zvonjenje z vibriranjem."</string>
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Zaslon z obvestili."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Hitre nastavitve."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Zaklenjen zaslon"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Zaklenjen zaslon delovnega profila"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Zapri"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Svetlost"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inverzija barv"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Popravljanje barv"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Velikost pisave"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Upravljanje uporabnikov"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Končano"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Zapri"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"snemanje zaslona"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Brez naslova"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravljenosti"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Velikost pisave"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Pomanjšanje"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Povečanje"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Povečevalno okno"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrolniki povečevalnega okna"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Povečaj"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Prišlo je do napake. Poskusite znova."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Nalaganje"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablični računalnik"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Predvajanje predstavnosti"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Predvajanje aplikacije <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, poglejte aplikacijo"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ni mogoče najti"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrolnik ni na voljo"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Oddajanje ni mogoče"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ni mogoče shraniti. Poskusite znova."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ni mogoče shraniti."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Uporabite vsaj 4 znake."</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Uporabite manj kot 16 znakov."</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Delovna različica"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Delovna različica je bila kopirana v odložišče."</string>
     <string name="basic_status" msgid="2315371112182658176">"Odprt pogovor"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Na voljo mora biti vsaj ena naprava."</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pridržite bližnjico"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Prekliči"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrni"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Razprite telefon za boljši selfi"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Obrnite telefon na sprednji zaslon za boljši selfi"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Uporabite hrbtni fotoaparat, da posnamete širšo sliko višje ločljivosti."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ta zaslon se bo izklopil."</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Preklopi zaslona zdaj"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Razprite telefon."</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Želite preklopiti zaslona?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Za višjo ločljivost uporabite hrbtni fotoaparat"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Za višjo ločljivost obrnite telefon"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Razpiranje zložljive naprave"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Obračanje zložljive naprave"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Preostanek energije baterije: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Preklopi na delovni profil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zapri"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Nastavitve zaklepanja zaslona"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi ni na voljo."</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Fotoaparat je blokiran."</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Fotoaparat in mikrofon sta blokirana."</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon je blokiran."</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prednostni način je vklopljen."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/tiles_states_strings.xml b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
index e720819..d7e62ca 100644
--- a/packages/SystemUI/res/values-sl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Izklopljeno"</item>
     <item msgid="5966994759929723339">"Vklopljeno"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Ni na voljo"</item>
+    <item msgid="2478289035899842865">"Izklopljeno"</item>
+    <item msgid="5137565285664080143">"Vklopljeno"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index c9789a9..84a5f96 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Streha e njoftimeve."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Cilësimet e shpejta."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Ekrani i kyçjes."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Ekrani i kyçjes së punës"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Mbylle"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Ndriçimi"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Anasjellja e ngjyrës"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Korrigjimi i ngjyrës"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Madhësia e fontit"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Menaxho përdoruesit"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"U krye"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Mbyll"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"regjistrim i ekranit"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Pa titull"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Në gatishmëri"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Madhësia e fontit"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Zvogëlo"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Zmadho"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Dritarja e zmadhimit"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Kontrollet e dritares së zmadhimit"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zmadho"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nuk mund të transmetohet"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nuk mund të ruhet. Provo përsëri."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nuk mund të ruhet."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Përdor të paktën 4 karaktere"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Përdor më pak se 16 karaktere"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numri i ndërtimit"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numri i ndërtimit u kopjua te kujtesa e fragmenteve"</string>
     <string name="basic_status" msgid="2315371112182658176">"Hap bisedën"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ofrohet të paktën një pajisje"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Prek dhe mbaj shtypur shkurtoren"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anulo"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Ktheje tani"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Shpalos telefonin për një selfi më të mirë"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Të kthehet tek ekrani para për selfi më të mirë?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Përdor lenten e kamerës së pasme për një fotografi më të gjerë me rezolucion më të lartë."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ky ekran do të fiket"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Ndërro ekranet tani"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Shpalos telefonin"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Të ndërrohen ekranet?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Për rezolucion më të lartë, përdor kamerën e pasme"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Për rezolucion më të lartë, përmbys telefonin"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Pajisja e palosshme duke u hapur"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Pajisja e palosshme duke u rrotulluar"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Përqindja e mbetur e baterisë: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Kalo te profili i punës"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Mbyll"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Cilësimet e ekranit të kyçjes"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi nuk ofrohet"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera u bllokua"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera dhe mikrofoni u bllokuan"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofoni u bllokua"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Modaliteti i përparësisë aktiv"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
index 7a09f24..45f63bf 100644
--- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Joaktiv"</item>
     <item msgid="5966994759929723339">"Aktiv"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Nuk ofrohet"</item>
+    <item msgid="2478289035899842865">"Joaktiv"</item>
+    <item msgid="5137565285664080143">"Aktiv"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index d756401..f9b3dd6 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -197,6 +197,7 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Прозор са обавештењима."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Брза подешавања."</string>
+    <string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"Брза подешавања и трака са обавештењима."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Закључан екран."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Закључан екран за посао"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Затвори"</string>
@@ -257,6 +258,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Осветљеност"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Инверзија боја"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Корекција боја"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Величина фонта"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Управљаjте корисницима"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Готово"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Затвори"</string>
@@ -777,6 +779,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"снимање екрана"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Без наслова"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Стање приправности"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Величина фонта"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Умањите"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Увећајте"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Прозор за увећање"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Контроле прозора за увећање"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Увећајте"</string>
@@ -862,10 +867,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Дошло је до грешке. Пробајте поново."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Учитава се"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"таблет"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Пребацивање медија"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Пребацује се <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно. Видите апликацију"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Није пронађено"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Контрола није доступна"</string>
@@ -903,6 +906,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Емитовање није успело"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Чување није успело. Пробајте поново."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Чување није успело."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Користите бар 4 знака"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Користите мање од 16 знакова"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број верзије"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Број верзије је копиран у привремену меморију."</string>
     <string name="basic_status" msgid="2315371112182658176">"Отворите конверзацију"</string>
@@ -1022,11 +1027,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• да је доступан барем један уређај"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Додирните и задржите пречицу"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Откажи"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Обрни"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Отворите телефон за бољи селфи"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Желите да обрнете на предњи екран за бољи селфи?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Користите задњу камеру да бисте снимили ширу слику са вишом резолуцијом."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Овај екран ће се искључити"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Замени екране"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Отворите телефон"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Желите да замените екране?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"За већу резолуцију користите задњу камеру"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"За већу резолуцију обрните телефон"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Уређај на преклоп се отвара"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Уређај на преклоп се обрће"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Преостало је још<xliff:g id="PERCENTAGE">%s</xliff:g> батерије"</string>
@@ -1038,4 +1043,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Пређи на пословни профил"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затвори"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Подешавања закључаног екрана"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"WiFi није доступан"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Камера је блокирана"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Камера и микрофон су блокирани"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Микрофон је блокиран"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Приоритетни режим је укључен"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/tiles_states_strings.xml b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
index dace491..c959bfb 100644
--- a/packages/SystemUI/res/values-sr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Искључено"</item>
     <item msgid="5966994759929723339">"Укључено"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Недоступно"</item>
+    <item msgid="2478289035899842865">"Искључено"</item>
+    <item msgid="5137565285664080143">"Укључено"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index d12c25f..be4f200 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Meddelandepanel."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Snabbinställningar."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Låsskärm."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Låsskärm för arbete"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Stäng"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Ljusstyrka"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Färginvertering"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Färgkorrigering"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Teckenstorlek"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Hantera användare"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Klart"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Stäng"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"skärminspelning"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Ingen titel"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Viloläge"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Teckenstorlek"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Förminska"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Förstora"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Förstoringsfönster"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Inställningar för förstoringsfönster"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Zooma in"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Något gick fel. Försök igen."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Läser in"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"surfplatta"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Castar din media"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Castar <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv, kolla appen"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Hittades inte"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Styrning är inte tillgänglig"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Det gick inte att sända ut"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Det gick inte att spara. Försök igen."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Det gick inte att spara."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Använd minst 4 tecken"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Använd färre än 16 tecken"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versionsnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versionsnumret har kopierats till urklipp."</string>
     <string name="basic_status" msgid="2315371112182658176">"Öppen konversation"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• minst en enhet är tillgänglig"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Tryck länge på genvägen"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Vänd nu"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Vik upp telefonen för att ta en bättre selfie"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vill du ta en bättre selfie med främre kameran?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Använd den bakre kameran för att ta ett mer vidsträckt foto med högre upplösning."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Den här skärmen inaktiveras"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Byt skärm nu"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Vik ut telefonen"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Vill du byta skärm?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Använd den bakre kameran för högre upplösning"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Vänd telefonen för högre upplösning"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En vikbar enhet viks upp"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En vikbar enhet vänds"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> av batteriet återstår"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Byt till jobbprofilen"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Stäng"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Inställningar för låsskärm"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wifi är inte tillgängligt"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kameran är blockerad"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kameran och mikrofonen är blockerade"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofonen är blockerad"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Prioritetsläge är aktiverat"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/tiles_states_strings.xml b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
index 9e69b00..28717df 100644
--- a/packages/SystemUI/res/values-sv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Av"</item>
     <item msgid="5966994759929723339">"På"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Inte tillgängligt"</item>
+    <item msgid="2478289035899842865">"Av"</item>
+    <item msgid="5137565285664080143">"På"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 564de43..4e04b64 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Kivuli cha arifa."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Mipangilio ya haraka."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Skrini iliyofungwa."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Skrini iliyofungwa ya kazini"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Funga"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Ung\'avu"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Ugeuzaji rangi"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Usahihishaji wa rangirangi"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Ukubwa wa fonti"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Dhibiti watumiaji"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Nimemaliza"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Funga"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"kurekodi skrini"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Wimbo hauna jina"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Hali tuli"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Ukubwa wa Fonti"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Punguza"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Kuza"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Dirisha la Ukuzaji"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Vidhibiti vya Dirisha la Ukuzaji"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Vuta karibu"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Hitilafu fulani imetokea. Jaribu tena."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Inapakia"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"kompyuta kibao"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Inatuma maudhui yako"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Inatuma <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Haitumiki, angalia programu"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Hakipatikani"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kidhibiti hakipatikani"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Imeshindwa kutuma arifa"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Imeshindwa kuhifadhi. Jaribu tena."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Imeshindwa kuhifadhi."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Tumia angalau herufi 4"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Tumia herufi chini ya 16"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nambari ya muundo"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nambari ya muundo imewekwa kwenye ubao wa kunakili."</string>
     <string name="basic_status" msgid="2315371112182658176">"Fungua mazungumzo"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Angalau kifaa kimoja kinapatikana"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Gusa na ushikilie njia ya mkato"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Ghairi"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Geuza kifaa sasa"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Kunjua simu ili upige selfi iliyo bora"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Ungependa kugeuza skrini ya mbele ili upige selfi?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Tumia kamera ya nyuma ili upige picha pana iliyo na ubora wa juu."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Skrini hii itajizima"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Badilisha skrini sasa"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Kunjua simu"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Ungependa kubadilisha skrini?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Kwa ubora wa juu, tumia kamera ya nyuma"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Kwa ubora wa juu, geuza simu"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Kifaa kinachokunjwa kikikunjuliwa"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Kifaa kinachokunjwa kikigeuzwa"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Chaji ya betri imesalia <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Tumia wasifu wa kazini"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Funga"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Mipangilio ya skrini iliyofungwa"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sw/tiles_states_strings.xml b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
index 2f765ef..2fe4060 100644
--- a/packages/SystemUI/res/values-sw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Imezimwa"</item>
     <item msgid="5966994759929723339">"Imewashwa"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Haipatikani"</item>
+    <item msgid="2478289035899842865">"Umezima"</item>
+    <item msgid="5137565285664080143">"Umewasha"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 45b137a..59becc6 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -62,7 +62,6 @@
     <dimen name="qs_security_footer_background_inset">0dp</dimen>
 
     <dimen name="qs_panel_padding_top">8dp</dimen>
-    <dimen name="qs_panel_padding_top_combined_headers">@dimen/qs_panel_padding_top</dimen>
 
     <!-- The width of large/content heavy dialogs (e.g. Internet, Media output, etc) -->
     <dimen name="large_dialog_width">472dp</dimen>
@@ -88,4 +87,7 @@
 
     <!-- Biometric Auth pattern view size, better to align keyguard_security_width -->
     <dimen name="biometric_auth_pattern_view_size">348dp</dimen>
+
+    <dimen name="controls_header_horizontal_padding">12dp</dimen>
+    <dimen name="controls_content_margin_horizontal">24dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-sw720dp-land/dimens.xml b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
index 9ed9360..8583f05 100644
--- a/packages/SystemUI/res/values-sw720dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
@@ -37,6 +37,8 @@
     <dimen name="qs_media_rec_album_size">112dp</dimen>
     <dimen name="qs_media_rec_album_side_margin">16dp</dimen>
 
+    <dimen name="controls_panel_corner_radius">40dp</dimen>
+
     <dimen name="lockscreen_shade_max_over_scroll_amount">42dp</dimen>
 
     <!-- Roughly the same distance as media on LS to media on QS. We will translate by this value
diff --git a/packages/SystemUI/res/values-sw720dp-port/dimens.xml b/packages/SystemUI/res/values-sw720dp-port/dimens.xml
index 8b41a44..9248d58 100644
--- a/packages/SystemUI/res/values-sw720dp-port/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-port/dimens.xml
@@ -33,5 +33,7 @@
      side -->
     <dimen name="qs_tiles_page_horizontal_margin">60dp</dimen>
 
+    <dimen name="controls_panel_corner_radius">46dp</dimen>
+
     <dimen name="notification_section_divider_height">16dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index 8f59df6..2086459 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -19,7 +19,8 @@
     <!-- gap on either side of status bar notification icons -->
     <dimen name="status_bar_icon_padding">1dp</dimen>
 
-    <dimen name="controls_padding_horizontal">40dp</dimen>
+    <dimen name="controls_header_horizontal_padding">28dp</dimen>
+    <dimen name="controls_content_margin_horizontal">40dp</dimen>
 
     <dimen name="large_screen_shade_header_height">56dp</dimen>
 
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index b20bd37..f623ff1 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"அறிவிப்பு விவரம்."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"உடனடி அமைப்பு."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"லாக் ஸ்கிரீன்."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"பணி லாக் ஸ்கிரீன்"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"மூடு"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ஒளிர்வு"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"கலர் இன்வெர்ஷன்"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"கலர் கரெக்‌ஷன்"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"எழுத்து வடிவத்தின் அளவு"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"பயனர்களை நிர்வகியுங்கள்"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"முடிந்தது"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"மூடுக"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ஸ்கிரீன் ரெக்கார்டிங்"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"தலைப்பு இல்லை"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"இயக்க நேரம்"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"எழுத்து வடிவத்தின் அளவு"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"சிறிதாக்கும்"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"பெரிதாக்கும்"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"பெரிதாக்கல் சாளரம்"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"பெரிதாக்கல் சாளரக் கட்டுப்பாடுகள்"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"பெரிதாக்கு"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"ஏதோ தவறாகிவிட்டது. மீண்டும் முயலவும்."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"ஏற்றுகிறது"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"டேப்லெட்"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"உங்கள் மீடியா அலைபரப்பப்படுகிறது"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ஆப்ஸை அலைபரப்புகிறது"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"செயலில் இல்லை , சரிபார்க்கவும்"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"இல்லை"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"கட்டுப்பாடு இல்லை"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ஒளிபரப்ப முடியவில்லை"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"சேமிக்க முடியவில்லை. மீண்டும் முயலவும்."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"சேமிக்க முடியவில்லை."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"குறைந்தது 4 எழுத்துகளைப் பயன்படுத்துங்கள்"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16 எழுத்துகளுக்குக் குறைவாகப் பயன்படுத்துங்கள்"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"பதிப்பு எண்"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"பதிப்பு எண் கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது."</string>
     <string name="basic_status" msgid="2315371112182658176">"திறந்தநிலை உரையாடல்"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• குறைந்தபட்சம் ஒரு சாதனமாவது கிடைக்க வேண்டும்"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ஷார்ட்கட்டை தொட்டுப் பிடிக்கவும்"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ரத்துசெய்"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"இப்போது மாற்றவும்"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"சிறந்த செல்ஃபிக்கு மொபைலை மடக்காதீர்கள்"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"சிறந்த செல்ஃபிக்கு முன்புற டிஸ்பிளேவிற்கு மாற்றவா?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"அதிகத் தெளிவுத்திறனுடன் அகலக் கோணத்தில் படத்தை எடுப்பதற்குப் பின்பக்கக் கேமராவைப் பயன்படுத்துங்கள்."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ இந்தத் திரை ஆஃப் ஆகிவிடும்"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"இப்போது திரைகளை மாற்றவா?"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"மொபைலை விரியுங்கள்"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"காட்சித் திரைகளை மாற்றுவது எப்படி?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"உயர் தெளிவுத்திறனுக்கு, பின்புறக் கேமராவை உபயோகிங்கள்"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"உயர் தெளிவுத்திறனுக்கு, மொபைலை ஃபிளிப் செய்யுங்கள்"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"மடக்கத்தக்க சாதனம் திறக்கப்படுகிறது"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"மடக்கத்தக்க சாதனம் ஃபிளிப் செய்யப்பட்டு திருப்பப்படுகிறது"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> பேட்டரி மீதமுள்ளது"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"பணிக் கணக்கிற்கு மாறு"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"மூடுக"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"பூட்டுத் திரை அமைப்புகள்"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"வைஃபை கிடைக்கவில்லை"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"கேமரா தடுக்கப்பட்டுள்ளது"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"கேமராவும் மைக்ரோஃபோனும் தடுக்கப்பட்டுள்ளன"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"மைக்ரோஃபோன் தடுக்கப்பட்டுள்ளது"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"முன்னுரிமைப் பயன்முறை இயக்கத்தில் உள்ளது"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/tiles_states_strings.xml b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
index 41f6412..5bcc6c7 100644
--- a/packages/SystemUI/res/values-ta/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"முடக்கப்பட்டுள்ளது"</item>
     <item msgid="5966994759929723339">"இயக்கப்பட்டுள்ளது"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"கிடைக்கவில்லை"</item>
+    <item msgid="2478289035899842865">"முடக்கப்பட்டுள்ளது"</item>
+    <item msgid="5137565285664080143">"இயக்கப்பட்டுள்ளது"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 0719671..9ddbe9b 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"నోటిఫికేషన్ షేడ్."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"శీఘ్ర సెట్టింగ్‌లు."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"లాక్ స్క్రీన్."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"కార్యాలయ లాక్ స్క్రీన్"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"మూసివేస్తుంది"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ప్రకాశం"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"కలర్ మార్పిడి"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"కలర్ కరెక్షన్"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"ఫాంట్ సైజ్"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"యూజర్‌లను మేనేజ్ చేయండి"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"పూర్తయింది"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"మూసివేయి"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"స్క్రీన్ రికార్డింగ్"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"శీర్షిక లేదు"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"స్టాండ్‌బై"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ఫాంట్ సైజ్"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"చిన్నదిగా చేస్తుంది"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"పెద్దదిగా చేస్తుంది"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"మ్యాగ్నిఫికేషన్ విండో"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"మ్యాగ్నిఫికేషన్ నియంత్రణల విండో"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"దగ్గరగా జూమ్ చేయండి"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ప్రసారం చేయడం సాధ్యపడలేదు"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"సేవ్ చేయడం సాధ్యపడదు. మళ్లీ ట్రై చేయండి."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"సేవ్ చేయడం సాధ్యపడదు."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"కనీసం 4 అక్షరాలను ఉపయోగించండి"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16 కంటే తక్కువ అక్షరాలను ఉపయోగించండి"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"బిల్డ్ నంబర్"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"బిల్డ్ నంబర్, క్లిప్‌బోర్డ్‌కు కాపీ చేయబడింది."</string>
     <string name="basic_status" msgid="2315371112182658176">"సంభాషణను తెరవండి"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• కనీసం ఒక పరికరమైనా అందుబాటులో ఉందని"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"షార్ట్‌కట్‌ను తాకి, నొక్కి ఉంచు"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"రద్దు చేయండి"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ఇప్పుడే తిప్పండి"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"మెరుగైన సెల్ఫీ కోసం ఫోన్‌ను అన్‌ఫోల్డ్ చేయండి"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"మంచి సెల్ఫీ కోసం ముందు వైపు డిస్‌ప్లేకు తిప్పాలా?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"వెనుక వైపున ఉన్న కెమెరాను ఉపయోగించి అధిక రిజల్యూషన్ గల, మరింత వెడల్పైన ఫోటోను పొందండి."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ఈ స్క్రీన్ ఆఫ్ అవుతుంది"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"ఇప్పుడే స్క్రీన్‌లను మార్చండి"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"ఫోన్‌ను అన్‌ఫోల్డ్ చేయండి"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"స్క్రీన్‌లను మార్చాలా?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"అధిక రిజల్యూషన్ కోసం, వెనుక వైపు కెమెరాను ఉపయోగించండి"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"అధిక రిజల్యూషన్ కోసం, ఫోన్‌ను తిప్పండి"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"మడవగల పరికరం విప్పబడుతోంది"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"మడవగల పరికరం చుట్టూ తిప్పబడుతోంది"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> బ్యాటరీ మిగిలి ఉంది"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"వర్క్ ప్రొఫైల్‌కు మారండి"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"మూసివేయండి"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"లాక్ స్క్రీన్ సెట్టింగ్‌లు"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi అందుబాటులో లేదు"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"కెమెరా బ్లాక్ చేయబడింది"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"కెమెరా, మైక్రోఫోన్ బ్లాక్ చేయబడ్డాయి"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"మైక్రోఫోన్ బ్లాక్ చేయబడింది"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"ప్రయారిటీ మోడ్ ఆన్‌లో ఉంది"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/tiles_states_strings.xml b/packages/SystemUI/res/values-te/tiles_states_strings.xml
index 44ba477..6549c56 100644
--- a/packages/SystemUI/res/values-te/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-te/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"ఆఫ్"</item>
     <item msgid="5966994759929723339">"ఆన్"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"అందుబాటులో లేదు"</item>
+    <item msgid="2478289035899842865">"ఆఫ్‌లో ఉంది"</item>
+    <item msgid="5137565285664080143">"ఆన్‌లో ఉంది"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 90617ca..c01929b 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -197,6 +197,7 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"หน้าต่างแจ้งเตือน"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"การตั้งค่าด่วน"</string>
+    <string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"การตั้งค่าด่วนและหน้าต่างแจ้งเตือน"</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"ล็อกหน้าจอ"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"หน้าจอล็อกของโปรไฟล์งาน"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"ปิด"</string>
@@ -257,6 +258,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ความสว่าง"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"การกลับสี"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"การแก้สี"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"ขนาดแบบอักษร"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"จัดการผู้ใช้"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"เสร็จสิ้น"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ปิด"</string>
@@ -777,6 +779,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"การบันทึกหน้าจอ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"ไม่มีชื่อ"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"สแตนด์บาย"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ขนาดแบบอักษร"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"ทำให้เล็กลง"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"ทำให้ใหญ่ขึ้น"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"หน้าต่างการขยาย"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"การควบคุมหน้าต่างการขยาย"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"ซูมเข้า"</string>
@@ -901,6 +906,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ออกอากาศไม่ได้"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"บันทึกไม่ได้ โปรดลองอีกครั้ง"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"บันทึกไม่ได้"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"ใช้อักขระอย่างน้อย 4 ตัว"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"ใช้อักขระไม่เกิน 16 ตัว"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"หมายเลขบิลด์"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"คัดลอกหมายเลขบิลด์ไปยังคลิปบอร์ดแล้ว"</string>
     <string name="basic_status" msgid="2315371112182658176">"เปิดการสนทนา"</string>
@@ -1020,11 +1027,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• มีอุปกรณ์พร้อมใช้งานอย่างน้อย 1 รายการ"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"แตะแป้นพิมพ์ลัดค้างไว้"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ยกเลิก"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"พลิกเลย"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"กางโทรศัพท์เพื่อเซลฟีที่ดียิ่งขึ้น"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"พลิกเป็นหน้าจอด้านหน้าเพื่อภาพเซลฟีที่ดีขึ้นไหม"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"ใช้กล้องหลังเพื่อถ่ายภาพกว้างขึ้นด้วยความละเอียดสูงขึ้น"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ หน้าจอนี้จะปิดไป"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"สลับหน้าจอเลย"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"กางโทรศัพท์ออก"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"สลับหน้าจอไหม"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"ใช้กล้องหลังเพื่อให้ได้ภาพที่มีความละเอียดมากขึ้น"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"พลิกด้านโทรศัพท์เพื่อให้ได้ภาพที่มีความละเอียดมากขึ้น"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"อุปกรณ์ที่พับได้กำลังกางออก"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"อุปกรณ์ที่พับได้กำลังพลิกไปมา"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"เหลือแบตเตอรี่ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1043,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"สลับไปใช้โปรไฟล์งาน"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ปิด"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"การตั้งค่าหน้าจอล็อก"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-th/tiles_states_strings.xml b/packages/SystemUI/res/values-th/tiles_states_strings.xml
index 9cd060f..69449a7 100644
--- a/packages/SystemUI/res/values-th/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-th/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"ปิด"</item>
     <item msgid="5966994759929723339">"เปิด"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"ไม่พร้อมใช้งาน"</item>
+    <item msgid="2478289035899842865">"ปิด"</item>
+    <item msgid="5137565285664080143">"เปิด"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 4eaa89c..d65704a 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Notification shade."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Mga mabilisang setting."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Lock screen."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Lock screen sa trabaho"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Isara"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Brightness"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Pag-invert ng kulay"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Pagtatama ng kulay"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Laki ng font"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Pamahalaan ang mga user"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Tapos na"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Isara"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"pag-record ng screen"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Walang pamagat"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Naka-standby"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Laki ng Font"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Paliitin"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Palakihin"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Window ng Pag-magnify"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Mga Kontrol sa Pag-magnify ng Window"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Mag-zoom in"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Nagkaproblema. Subukan ulit."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Naglo-load"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Pag-cast ng iyong media"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Kina-cast ang <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Hindi aktibo, tingnan ang app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Hindi nahanap"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Hindi available ang kontrol"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Hindi makapag-broadcast"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Hindi ma-save. Subukan ulit."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Hindi ma-save."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Gumamit ng hindi bababa sa 4 na character"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Gumamit ng mas kaunti sa 16 na character"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero ng build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nakopya sa clipboard ang numero ng build."</string>
     <string name="basic_status" msgid="2315371112182658176">"Buksan ang pag-uusap"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• May kahit isang device na available"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pindutin nang matagal: shortcut"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Kanselahin"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"I-flip na ngayon"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"I-unfold ang telepono para sa mas magandang selfie"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"I-flip sa front display para sa magandang selfie?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gamitin ang camera sa harap para sa mas malawak na larawan na may mas mataas na resolution."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Mag-o-off ang screen na ito"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Lumipat na ng screen"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"I-unfold ang telepono"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Lumipat ng screen?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Para sa mas mataas na resolution, gamitin ang camera sa likod"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Para sa mas mataas na resolution, i-flip ang telepono"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Ina-unfold na foldable na device"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Fini-flip na foldable na device"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> baterya na lang ang natitira"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Lumipat sa profile sa trabaho"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Isara"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Mga setting ng lock screen"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Hindi available ang Wi-Fi"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Naka-block ang camera"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Naka-block ang camera at mikropono"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Naka-block ang mikropono"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Naka-on ang Priority mode"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/tiles_states_strings.xml b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
index cd7dcf5..689c2a2 100644
--- a/packages/SystemUI/res/values-tl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Naka-off"</item>
     <item msgid="5966994759929723339">"Naka-on"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Hindi available"</item>
+    <item msgid="2478289035899842865">"Naka-off"</item>
+    <item msgid="5137565285664080143">"Naka-on"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 2e53e64..34b3b1f 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Bildirim gölgesi."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Hızlı ayarlar."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Kilit ekranı"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"İş profili kilit ekranı"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Kapat"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Parlaklık"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Rengi ters çevirme"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Renk düzeltme"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Yazı tipi boyutu"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Kullanıcıları yönet"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Bitti"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Kapat"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ekran kaydı"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Başlıksız"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Beklemeye alınıyor"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Yazı Tipi Boyutu"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Küçült"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Büyüt"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Büyütme Penceresi"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Büyütme Penceresi Kontrolleri"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Yakınlaştır"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Bir hata oluştu. Tekrar deneyin."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Yükleme"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Medyanız yayınlanıyor"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> yayınlanıyor"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Devre dışı, uygulamaya bakın"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Bulunamadı"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrol kullanılamıyor"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Yayınlanamıyor"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kaydedilemiyor. Tekrar deneyin."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kaydedilemiyor."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"En az 4 karakter kullanın."</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"En fazla 16 karakter kullanın"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Derleme numarası"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Derleme numarası panoya kopyalandı."</string>
     <string name="basic_status" msgid="2315371112182658176">"Görüşmeyi aç"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• En az bir cihaz mevcut olmalıdır"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Kısayola dokunup basılı tutun"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"İptal"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Şimdi çevirin"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Daha iyi selfie çekmek için telefonu açın"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Daha iyi bir selfie için ön ekrana geçilsin mi?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Daha yüksek çözünürlüğe sahip daha büyük bir fotoğraf için arka yüz kamerasını kullanın."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Bu ekran kapatılacak"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Ekranı şimdi değiştirin"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Telefonu açın"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Ekran değiştirilsin mi?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Daha yüksek çözünürlük için arka kamerayı kullanın"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Daha yüksek çözünürlük için telefonu çevirin"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Katlanabilir cihaz açılıyor"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Katlanabilir cihaz döndürülüyor"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> pil kaldı"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"İş profiline geç"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Kapat"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Kilit ekranı ayarları"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Kablosuz bağlantı kullanılamıyor"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera engellendi"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera ve mikrofon engellendi"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon engellendi"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Öncelik modu etkin"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/tiles_states_strings.xml b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
index 28ba7dc..a8c7f78 100644
--- a/packages/SystemUI/res/values-tr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Kapalı"</item>
     <item msgid="5966994759929723339">"Açık"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Kullanılamıyor"</item>
+    <item msgid="2478289035899842865">"Kapalı"</item>
+    <item msgid="5137565285664080143">"Açık"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 8b5f7b6..e439bec 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Панель сповіщень."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Швидке налаштування."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Заблокований екран."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Екран блокування завдання"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Закрити"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Яскравість"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Інверсія кольорів"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Корекція кольору"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Розмір шрифту"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Керувати користувачами"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Готово"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Закрити"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"запис відео з екрана"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Без назви"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Режим очікування"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Розмір шрифту"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Зменшити"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Збільшити"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Вікно збільшення"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Елементи керування вікна збільшення"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Наблизити"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Сталася помилка. Повторіть спробу."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Завантаження"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"планшет"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Трансляція медіаконтенту"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Трансляція додатка <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, перейдіть у додаток"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Не знайдено"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Елемент керування недоступний"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Неможливо транслювати"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не вдалося зберегти. Повторіть спробу."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не вдалося зберегти."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Введіть принаймні 4 символи"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Введіть менше ніж 16 символів"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер складання"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Номер складання скопійовано в буфер обміну."</string>
     <string name="basic_status" msgid="2315371112182658176">"Відкрита розмова"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Принаймні один пристрій доступний"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Натисніть і утримуйте ярлик"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Скасувати"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Перевернути"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Розгорніть телефон, щоб зробити краще селфі"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Перемкнути на фронтальну камеру для кращого селфі?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Використовуйте камеру на задній панелі, щоб зробити знімок із ширшим кутом і вищою роздільною здатністю."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Цей екран вимкнеться"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Використовувати інший екран"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Розгорніть телефон"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Використовувати інший екран?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Для вищої роздільної здатності використовуйте основну камеру"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Для вищої роздільної здатності переверніть телефон"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Розкладний пристрій у розкладеному стані"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Розкладний пристрій обертається"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Заряд акумулятора: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Перейти в робочий профіль"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрити"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Параметри заблокованого екрана"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uk/tiles_states_strings.xml b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
index 3f6ca46..4062f1b 100644
--- a/packages/SystemUI/res/values-uk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Вимкнено"</item>
     <item msgid="5966994759929723339">"Увімкнено"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Недоступно"</item>
+    <item msgid="2478289035899842865">"Вимкнено"</item>
+    <item msgid="5137565285664080143">"Увімкнено"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index c1bca22..1d4385d 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -93,8 +93,8 @@
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"دایاں احاطہ <xliff:g id="PERCENT">%1$d</xliff:g> فیصد"</string>
     <string name="screenshot_work_profile_notification" msgid="203041724052970693">"دفتری پروفائل میں <xliff:g id="APP">%1$s</xliff:g> میں محفوظ کی گئی"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"فائلز"</string>
-    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> نے اس اسکرین شاٹ کا پتا لگایا۔"</string>
-    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> اور دیگر کھلی ایپس نے اس اسکرین شاٹ کا پتا لگایا۔"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"‫<xliff:g id="APPNAME">%1$s</xliff:g> نے اس اسکرین شاٹ کا پتا لگایا۔"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"‫<xliff:g id="APPNAME">%1$s</xliff:g> اور دیگر کھلی ایپس نے اس اسکرین شاٹ کا پتا لگایا۔"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"اسکرین ریکارڈر"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"سکرین ریکارڈنگ پروسیس ہورہی ہے"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"اسکرین ریکارڈ سیشن کیلئے جاری اطلاع"</string>
@@ -187,8 +187,8 @@
     <string name="accessibility_battery_level" msgid="5143715405241138822">"بیٹری <xliff:g id="NUMBER">%d</xliff:g> فیصد۔"</string>
     <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"بیٹری <xliff:g id="PERCENTAGE">%1$d</xliff:g> فیصد ہے، <xliff:g id="TIME">%2$s</xliff:g> تک چلے گی"</string>
     <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"بیٹری چارج ہو رہی ہے، اس وقت <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> فیصد ہے۔"</string>
-    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"بیٹری <xliff:g id="PERCENTAGE">%d</xliff:g> فیصد پے، بیٹری کے تحفظ کے لیے چارجنگ موقوف ہو گئی ہے۔"</string>
-    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"بیٹری <xliff:g id="PERCENTAGE">%1$d</xliff:g> فیصد پے، <xliff:g id="TIME">%2$s</xliff:g> تک چلے گی، بیٹری کے تحفظ کے لیے چارجنگ موقوف ہو گئی ہے۔"</string>
+    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"بیٹری <xliff:g id="PERCENTAGE">%d</xliff:g> فیصد، بیٹری کے تحفظ کے لیے چارجنگ موقوف ہو گئی ہے۔"</string>
+    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"بیٹری <xliff:g id="PERCENTAGE">%1$d</xliff:g> فیصد، <xliff:g id="TIME">%2$s</xliff:g>، بیٹری کے تحفظ کے لیے چارجنگ موقوف ہو گئی ہے۔"</string>
     <string name="accessibility_overflow_action" msgid="8555835828182509104">"تمام اطلاعات دیکھیں"</string>
     <string name="accessibility_tty_enabled" msgid="1123180388823381118">"ٹیلی ٹائپ رائٹر فعال ہے۔"</string>
     <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"رنگر وائبریٹ۔"</string>
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"اطلاعاتی شیڈ۔"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"فوری ترتیبات۔"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"مقفل اسکرین۔"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"دفتری مقفل اسکرین"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"بند کریں"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"چمکیلا پن"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"رنگوں کی تقلیب"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"رنگ کی اصلاح"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"فونٹ سائز"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"صارفین کا نظم کریں"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"ہو گیا"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"بند کریں"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"اسکرین ریکارڈنگ"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"کوئی عنوان نہیں ہے"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"اسٹینڈ بائی"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"فونٹ سائز"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"چھوٹا کریں"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"بڑا کریں"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"میگنیفکیشن ونڈو"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"میگنیفکیشن ونڈو کنٹرولز"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"زوم ان کریں"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"کچھ غلط ہوگیا۔ پھر کوشش کریں۔"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"لوڈ ہو رہا ہے"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ٹیبلیٹ"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"آپ کا میڈیا کاسٹ ہو رہا ہے"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> کاسٹ ہو رہا ہے"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"غیر فعال، ایپ چیک کریں"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"نہیں ملا"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"کنٹرول دستیاب نہیں ہے"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"براڈکاسٹ نہیں کیا جا سکتا"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"محفوظ نہیں کیا جا سکا۔ پھر کوشش کریں۔"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"محفوظ نہیں کیا جا سکا۔"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"کم از کم 4 حروف استعمال کریں"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"16 حروف سے کم استعمال کریں"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"بلڈ نمبر"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"بلڈ نمبر کلپ بورڈ میں کاپی ہو گیا۔"</string>
     <string name="basic_status" msgid="2315371112182658176">"گفتگو کھولیں"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• کم از کم ایک آلہ دستیاب ہے"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"شارٹ کٹ ٹچ کریں اور دبائے رکھیں"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"منسوخ کریں"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"اب پلٹائیں"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"بہتر سیلفی کے لیے فون کھولیں"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"بہتر سیلفی کے لیے سامنے والے ڈسپلے پر پلٹائیں؟"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"اعلی ریزولیوشن والی وسیع تصویر کے لیے ییچھے والا کیمرا استعمال کریں۔"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ یہ اسکرین آف ہو جائے گی"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"اب اسکرینز سوئچ کریں"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"فون کھولیں"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"اسکرینز سوئچ کریں؟"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"زیادہ ریزولوشن کے لیے، بَیک کیمرا استعمال کریں"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"زیادہ ریزولوشن کے لیے، فون پلٹائیں"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"فولڈ ہونے والے آلے کو کھولا جا رہا ہے"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"فولڈ ہونے والے آلے کو گھمایا جا رہا ہے"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> بیٹری باقی ہے"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"دفتری پروفائل پر سوئچ کریں"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"بند کریں"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"مقفل اسکرین کی ترتیبات"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"‏Wi-Fi دستیاب نہیں ہے"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"کیمرا مسدود ہے"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"کیمرا اور مائیکروفون مسدود ہے"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"مائیکروفون مسدود ہے"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"ترجیحی موڈ آن ہے"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/tiles_states_strings.xml b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
index 05aa4e9..bb27b9f 100644
--- a/packages/SystemUI/res/values-ur/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"آف"</item>
     <item msgid="5966994759929723339">"آن"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"دستیاب نہیں ہیں"</item>
+    <item msgid="2478289035899842865">"آف ہے"</item>
+    <item msgid="5137565285664080143">"آن ہے"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 284193b..836fea2 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -93,8 +93,8 @@
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Oʻng chegara <xliff:g id="PERCENT">%1$d</xliff:g> foiz"</string>
     <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Ish profilidagi <xliff:g id="APP">%1$s</xliff:g> ilovasiga saqlandi"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fayllar"</string>
-    <string name="screenshot_detected_template" msgid="7940376642921719915">"Bu skrinshotda <xliff:g id="APPNAME">%1$s</xliff:g> aniqlandi."</string>
-    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Bu skrinshotda <xliff:g id="APPNAME">%1$s</xliff:g> va boshqa ochiq ilovalar aniqlandi"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> skrinshot olinganini aniqladi."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> va boshqa ochiq ilovalar skrinshot olinganini aniqladi."</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekrandan yozib olish"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran yozib olinmoqda"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekrandan yozib olish seansi uchun joriy bildirishnoma"</string>
@@ -187,8 +187,8 @@
     <string name="accessibility_battery_level" msgid="5143715405241138822">"Batareya <xliff:g id="NUMBER">%d</xliff:g> foiz."</string>
     <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"Batareya <xliff:g id="PERCENTAGE">%1$d</xliff:g> foiz, <xliff:g id="TIME">%2$s</xliff:g> yetadi."</string>
     <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Batareya quvvat olmoqda, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> foiz."</string>
-    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Batareya <xliff:g id="PERCENTAGE">%d</xliff:g> foiz, batareya himoyasi uchun quvvatlash toʻxtatildi."</string>
-    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"Batareya <xliff:g id="PERCENTAGE">%1$d</xliff:g> foiz, <xliff:g id="TIME">%2$s</xliff:g> yetadi, batareya himoyasi uchun quvvatlash toʻxtatildi."</string>
+    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Batareya <xliff:g id="PERCENTAGE">%d</xliff:g> foiz, batareya himoyasi uchun quvvatlash pauza qilindi."</string>
+    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"Batareya <xliff:g id="PERCENTAGE">%1$d</xliff:g> foiz, <xliff:g id="TIME">%2$s</xliff:g>, batareya himoyasi uchun quvvatlash pauza qilindi."</string>
     <string name="accessibility_overflow_action" msgid="8555835828182509104">"Barcha bildirishnomalarni ko‘rish"</string>
     <string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter yoqildi."</string>
     <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"Vibratsiyali qo‘ng‘iroq"</string>
@@ -197,6 +197,7 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Xabarnoma soyasi."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Tezkor sozlamalar."</string>
+    <string name="accessibility_desc_qs_notification_shade" msgid="8327226953072700376">"Tezkor sozlamalar va eslatma soyasi."</string>
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Qulflash ekrani."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Ishchi ekran qulfi"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Yopish"</string>
@@ -257,6 +258,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Yorqinlik"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Ranglarni akslantirish"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Ranglarni tuzatish"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Shrift oʻlchami"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Foydalanuvchilarni boshqarish"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Tayyor"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Yopish"</string>
@@ -777,6 +779,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ekranni yozuvi"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Nomsiz"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Kutib turing"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Shrift oʻlchami"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Kichiklashtirish"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Kattalashtirish"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Kattalashtirish oynasi"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Kattalashtirish oynasi sozlamalari"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Yaqinlashtirish"</string>
@@ -901,6 +906,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Uzatilmadi"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Saqlanmadi. Qayta urining."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Saqlanmadi."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Parolga kamida 4 ta belgi kiriting."</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Kiritiladigan belgilar 16 tadan oshmasin"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nashr raqami"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nashr raqami vaqtinchalik xotiraga nusxalandi."</string>
     <string name="basic_status" msgid="2315371112182658176">"Suhbatni ochish"</string>
@@ -1020,11 +1027,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Kamida bitta qurilma mavjud"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Bosib turish yorligʻi"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Bekor qilish"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Almashtirish"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Yaxshiroq selfi olish uchun telefonni yoying"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Yaxshiroq selfi uchun old ekranga almashilsinmi?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Keng burchakli va yuqori aniqlikda suratga olish uchun orqa kameradan foydalaning."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Bu ekran oʻchiriladi"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Ekranlarni hozir almashtirish"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Telefonni yoying"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Ekranlar almashtirilsinmi?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Yuqori aniqlik uchun orqa kameradan foydalaning"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Yuqori aniqlik uchun telefonni aylantiring"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Buklanadigan qurilma ochilmoqda"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Buklanadigan qurilma aylantirilmoqda"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Batareya quvvati: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1036,4 +1043,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Ish profiliga almashish"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Yopish"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Qulflangan ekran sozlamalari"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi mavjud emas"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera bloklangan"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"Kamera va mikrofon bloklangan"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Mikrofon bloklangan"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"Imtiyozli rejim yoniq"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/tiles_states_strings.xml b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
index a84f769..4a45f03 100644
--- a/packages/SystemUI/res/values-uz/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Oʻchiq"</item>
     <item msgid="5966994759929723339">"Yoniq"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Mavjud emas"</item>
+    <item msgid="2478289035899842865">"Oʻchiq"</item>
+    <item msgid="5137565285664080143">"Yoniq"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index fe77c10..1cb78ce 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Bóng thông báo."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Cài đặt nhanh."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Màn hình khóa."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Màn hình khóa công việc"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Đóng"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Độ sáng"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Đảo màu"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Chỉnh màu"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Cỡ chữ"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Quản lý người dùng"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Xong"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Đóng"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ghi màn hình"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Không có tiêu đề"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Chế độ chờ"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Cỡ chữ"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Thu nhỏ"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Phóng to"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Cửa sổ phóng to"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Các tùy chọn điều khiển cửa sổ phóng to"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Phóng to"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Đã xảy ra lỗi. Hãy thử lại."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Đang tải"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"máy tính bảng"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Truyền nội dung đa phương tiện"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Đang truyền <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Không hoạt động, hãy kiểm tra ứng dụng"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Không tìm thấy"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Không có chức năng điều khiển"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Không thể truyền"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Không lưu được. Hãy thử lại."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Không lưu được."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Sử dụng ít nhất 4 ký tự"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Sử dụng ít hơn 16 ký tự"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Số bản dựng"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Đã sao chép số bản dựng vào bảng nhớ tạm."</string>
     <string name="basic_status" msgid="2315371112182658176">"Mở cuộc trò chuyện"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Có ít nhất một thiết bị đang hoạt động"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Chạm và giữ phím tắt"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Huỷ"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Lật ngay"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Mở điện thoại ra để tự chụp ảnh chân dung đẹp hơn"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Lật sang màn hình ngoài để tự chụp ảnh chân dung đẹp hơn?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Sử dụng máy ảnh sau để chụp ảnh góc rộng hơn với độ phân giải cao hơn."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Màn hình này sẽ tắt"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Chuyển đổi màn hình ngay"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Mở điện thoại"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Chuyển đổi màn hình?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Để có độ phân giải cao hơn, hãy dùng máy ảnh sau"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Để có độ phân giải cao hơn, hãy lật điện thoại"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Thiết bị có thể gập lại đang được mở ra"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Thiết bị có thể gập lại đang được lật ngược"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Còn <xliff:g id="PERCENTAGE">%s</xliff:g> pin"</string>
@@ -1038,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Chuyển sang hồ sơ công việc"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Đóng"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Cài đặt màn hình khoá"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-vi/tiles_states_strings.xml b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
index 482a32f..201a45b 100644
--- a/packages/SystemUI/res/values-vi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Tắt"</item>
     <item msgid="5966994759929723339">"Đang bật"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Không có sẵn"</item>
+    <item msgid="2478289035899842865">"Đang tắt"</item>
+    <item msgid="5137565285664080143">"Đang bật"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 3cd6a69..25ea39d 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"通知栏。"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"快捷设置。"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"锁定屏幕。"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"工作锁定屏幕"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"关闭"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"亮度"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"颜色反转"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"色彩校正"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"字号"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"管理用户"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"完成"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"关闭"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"屏幕录制"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"无标题"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待机"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"字体大小"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"缩小"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"放大"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"放大窗口"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"放大窗口控件"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"放大"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"无法广播"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"无法保存,请重试。"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"无法保存。"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"必须至少 4 个字符"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"必须少于 16 个字符"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本号"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"已将版本号复制到剪贴板。"</string>
     <string name="basic_status" msgid="2315371112182658176">"开放式对话"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 至少有一台设备可用"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"轻触并按住快捷方式"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"取消"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"立即翻转"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"展开手机可拍出更好的自拍照"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"翻转到外屏后自拍效果更好,要试试吗?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"您可以使用后置摄像头拍摄视角更广、分辨率更高的照片。"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 此屏幕将会关闭"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"立即切换屏幕"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"展开手机"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"切换屏幕?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"若要获得更高的分辨率,请使用后置摄像头"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"若要获得更高的分辨率,请翻转手机"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展开可折叠设备"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻转可折叠设备"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"电池还剩 <xliff:g id="PERCENTAGE">%s</xliff:g> 的电量"</string>
@@ -1036,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"切换到工作资料"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"关闭"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"锁屏设置"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"没有 WLAN 连接"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"已禁用摄像头"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"已禁用摄像头和麦克风"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"已禁用麦克风"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"已开启优先模式"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
index 6ce948d..3ab2d7a 100644
--- a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"关闭"</item>
     <item msgid="5966994759929723339">"已开启"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"不可用"</item>
+    <item msgid="2478289035899842865">"已关闭"</item>
+    <item msgid="5137565285664080143">"已开启"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index e499fe5..2bb1ab8 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -187,8 +187,8 @@
     <string name="accessibility_battery_level" msgid="5143715405241138822">"電池電量為百分之 <xliff:g id="NUMBER">%d</xliff:g>。"</string>
     <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"目前電池電量為 <xliff:g id="PERCENTAGE">%1$d</xliff:g>,剩餘使用時間為 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"正在充電:<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%。"</string>
-    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"目前電池電量為 <xliff:g id="PERCENTAGE">%d</xliff:g>。為保護電池,系統已暫停充電。"</string>
-    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"目前電池電量為 <xliff:g id="PERCENTAGE">%1$d</xliff:g>,剩餘使用時間為 <xliff:g id="TIME">%2$s</xliff:g>。為保護電池,系統已暫停充電。"</string>
+    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"目前電池電量為百分之 <xliff:g id="PERCENTAGE">%d</xliff:g>。為保護電池,系統已暫停充電。"</string>
+    <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"目前電池電量為百分之 <xliff:g id="PERCENTAGE">%1$d</xliff:g>,剩餘使用時間為 <xliff:g id="TIME">%2$s</xliff:g>。為保護電池,系統已暫停充電。"</string>
     <string name="accessibility_overflow_action" msgid="8555835828182509104">"睇所有通知"</string>
     <string name="accessibility_tty_enabled" msgid="1123180388823381118">"TeleTypewriter (TTY) 已啟用。"</string>
     <string name="accessibility_ringer_vibrate" msgid="6261841170896561364">"鈴聲震動。"</string>
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"通知欄。"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"快速設定。"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"上鎖畫面。"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"工作螢幕鎖定"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"關閉"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"亮度"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"色彩反轉"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"色彩校正"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"字型大小"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"管理使用者"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"完成"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"關閉"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"錄製螢幕畫面"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"無標題"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待機"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"字型大小"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"縮小"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"放大"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"放大視窗"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"放大視窗控制項"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"放大"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"發生錯誤,請再試一次。"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"正在載入"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"平板電腦"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"投放媒體"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"投放 <xliff:g id="APP_LABEL">%1$s</xliff:g> 內容"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"已停用,請檢查應用程式"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"找不到"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"無法使用控制功能"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"無法廣播"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"無法儲存,請再試一次。"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"無法儲存。"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"請至少使用 4 個字元"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"請使用少於 16 個字元"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"版本號碼已複製到剪貼簿。"</string>
     <string name="basic_status" msgid="2315371112182658176">"開啟對話"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 至少一部裝置可用"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"輕觸並按住快速鍵"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"取消"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"立即翻轉"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"打開手機,即可拍攝更出色的自拍"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"要翻轉至前方螢幕拍攝更出色的自拍嗎?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"使用後置鏡頭,拍攝更廣角、解像度更高的相片。"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 此螢幕將關閉"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"立即切換螢幕"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"打開手機"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"要切換螢幕嗎?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"如要提高解像度,請使用後置鏡頭"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"如要提高解像度,請切換至手機後置鏡頭"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開折疊式裝置"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"剩餘電量:<xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"切換至工作設定檔"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"關閉"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"上鎖畫面設定"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"無法連線至 Wi-Fi"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"已封鎖相機"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"已封鎖相機和麥克風"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"已封鎖麥克風"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"優先模式已開啟"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
index ab8e961a..89d6628 100644
--- a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"已關閉"</item>
     <item msgid="5966994759929723339">"已開啟"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"無法使用"</item>
+    <item msgid="2478289035899842865">"關閉"</item>
+    <item msgid="5137565285664080143">"開啟"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 26c60e0..612005e 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"通知欄。"</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"快捷設定。"</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"螢幕鎖定。"</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Work 螢幕鎖定"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"關閉"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"亮度"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"色彩反轉"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"色彩校正"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"字型大小"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"管理使用者"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"完成"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"關閉"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"錄製螢幕畫面"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"無標題"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"待機"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"字型大小"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"縮小"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"放大"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"放大視窗"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"放大視窗控制項"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"放大"</string>
@@ -862,10 +868,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"發生錯誤,請再試一次。"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"載入中"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"平板電腦"</string>
-    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
-    <skip />
-    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
-    <skip />
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"投放媒體"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"投放「<xliff:g id="APP_LABEL">%1$s</xliff:g>」的內容"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"無效,請查看應用程式"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"找不到控制項"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"無法使用控制項"</string>
@@ -903,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"無法廣播"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"無法儲存,請再試一次。"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"無法儲存。"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"至少要有 4 個半形字元"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"不得超過 16 個半形字元"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"已將版本號碼複製到剪貼簿。"</string>
     <string name="basic_status" msgid="2315371112182658176">"開放式對話"</string>
@@ -1022,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 至少要有一部可用裝置"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"按住快速鍵"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"取消"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"立即翻轉"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"打開手機自拍效果較佳"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"要翻轉到前螢幕拍攝更優質的自拍照嗎?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"使用後置鏡頭可拍攝視角較寬廣、解析度較高的相片。"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 這麼做會關閉這個螢幕"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"立即切換螢幕"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"展開手機"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"要切換螢幕嗎?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"如要提高解析度,請使用後置鏡頭"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"如要提高解析度,請切換至手機後置鏡頭"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展開的折疊式裝置"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"正在翻轉折疊式裝置"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"剩餘電量:<xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -1038,4 +1044,9 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"切換至工作資料夾"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"關閉"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"螢幕鎖定設定"</string>
+    <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"無法連上 Wi-Fi"</string>
+    <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"已封鎖攝影機"</string>
+    <string name="camera_and_microphone_blocked_dream_overlay_content_description" msgid="7891078093416249764">"已封鎖攝影機和麥克風"</string>
+    <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"已封鎖麥克風"</string>
+    <string name="priority_mode_dream_overlay_content_description" msgid="6044561000253314632">"優先模式已開啟"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
index 3d6a546..a046e33 100644
--- a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"已關閉"</item>
     <item msgid="5966994759929723339">"已開啟"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"無法使用"</item>
+    <item msgid="2478289035899842865">"關閉"</item>
+    <item msgid="5137565285664080143">"開啟"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index b585b6c..b3f96b0 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -197,6 +197,8 @@
     <skip />
     <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Umthunzi wesaziso."</string>
     <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Izilingiselelo ezisheshayo."</string>
+    <!-- no translation found for accessibility_desc_qs_notification_shade (8327226953072700376) -->
+    <skip />
     <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Khiya isikrini."</string>
     <string name="accessibility_desc_work_lock" msgid="4355620395354680575">"Ukukhiya isikrini somsebenzi"</string>
     <string name="accessibility_desc_close" msgid="8293708213442107755">"Vala"</string>
@@ -257,6 +259,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Ukugqama"</string>
     <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Ukuguqulwa kombala"</string>
     <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Ukulungiswa kombala"</string>
+    <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Usayizi wefonti"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"Phatha abasebenzisi"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Kwenziwe"</string>
     <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"Vala"</string>
@@ -777,6 +780,9 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"ukurekhoda isikrini"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"Asikho isihloko"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Ilindile"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"Usayizi Wefonti"</string>
+    <string name="font_scaling_smaller" msgid="1012032217622008232">"Yenza kube kuncane"</string>
+    <string name="font_scaling_larger" msgid="5476242157436806760">"Yenza kube kukhulu"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Iwindi Lesikhulisi"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Izilawuli Zewindi Lesikhulisi"</string>
     <string name="accessibility_control_zoom_in" msgid="1189272315480097417">"Sondeza"</string>
@@ -901,6 +907,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ayikwazi ukusakaza"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ayikwazi ukulondoloza. Zama futhi."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ayikwazi ukulondoloza."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Sebenzisa okungenani izinhlamvu ezi-4"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Sebenzisa isinhlamvu ezimbalwa kuneziyi-16"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Yakha inombolo"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Yakha inombolo ekopishelwe kubhodi yokunamathisela."</string>
     <string name="basic_status" msgid="2315371112182658176">"Vula ingxoxo"</string>
@@ -1020,11 +1028,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Okungenani idivayisi eyodwa iyatholakala"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Thinta futhi ubambe isinqamuleli"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Khansela"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Phendula manje"</string>
-    <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Vula ifoni ukuze ube nesithombe ozishuthe sona esingcono"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Phendulela kwisibonisi sangaphambili ukuba nesithombe ozishuthe sona esingcono?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Sebenzisa ikhamera ebheke ngemuva ukuze uthole isithombe esibanzi esinokucaca okuphezulu."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Lesi sikrini sizovala"</b></string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Shintsha izikrini manje"</string>
+    <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Vula ifoni"</string>
+    <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Shintsha izikrini?"</string>
+    <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Ukuze uthole ukulungiswa okuphezulu, sebenzisa ikhamera yangemuva"</string>
+    <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Ukuze uthole ukulungiswa okuphezulu, phendula ifoni"</string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Idivayisi egoqekayo iyembulwa"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Idivayisi egoqekayo iphendulwa nxazonke"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> ibhethri elisele"</string>
@@ -1036,4 +1044,14 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Shintshela kuphrofayela yomsebenzi"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Vala"</string>
     <string name="lock_screen_settings" msgid="9197175446592718435">"Amasethingi okukhiya isikrini"</string>
+    <!-- no translation found for wifi_unavailable_dream_overlay_content_description (2024166212194640100) -->
+    <skip />
+    <!-- no translation found for camera_blocked_dream_overlay_content_description (4074759493559418130) -->
+    <skip />
+    <!-- no translation found for camera_and_microphone_blocked_dream_overlay_content_description (7891078093416249764) -->
+    <skip />
+    <!-- no translation found for microphone_blocked_dream_overlay_content_description (5466897982130007033) -->
+    <skip />
+    <!-- no translation found for priority_mode_dream_overlay_content_description (6044561000253314632) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zu/tiles_states_strings.xml b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
index 81c4636..e35840b 100644
--- a/packages/SystemUI/res/values-zu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
@@ -176,4 +176,9 @@
     <item msgid="8014986104355098744">"Valiwe"</item>
     <item msgid="5966994759929723339">"Vuliwe"</item>
   </string-array>
+  <string-array name="tile_states_font_scaling">
+    <item msgid="3173069902082305985">"Ayitholakali"</item>
+    <item msgid="2478289035899842865">"Valiwe"</item>
+    <item msgid="5137565285664080143">"Vuliwe"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index d48ea214..bf949a0 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -616,8 +616,7 @@
     <dimen name="qs_dual_tile_padding_horizontal">6dp</dimen>
     <dimen name="qs_panel_elevation">4dp</dimen>
     <dimen name="qs_panel_padding_bottom">@dimen/footer_actions_height</dimen>
-    <dimen name="qs_panel_padding_top">48dp</dimen>
-    <dimen name="qs_panel_padding_top_combined_headers">80dp</dimen>
+    <dimen name="qs_panel_padding_top">80dp</dimen>
 
     <dimen name="qs_data_usage_text_size">14sp</dimen>
     <dimen name="qs_data_usage_usage_text_size">36sp</dimen>
@@ -1154,11 +1153,13 @@
 
     <!-- Home Controls -->
     <dimen name="controls_header_menu_size">48dp</dimen>
+    <dimen name="controls_header_menu_button_size">48dp</dimen>
     <dimen name="controls_header_bottom_margin">16dp</dimen>
+    <dimen name="controls_header_horizontal_padding">12dp</dimen>
     <dimen name="controls_header_app_icon_size">24dp</dimen>
     <dimen name="controls_top_margin">48dp</dimen>
-    <dimen name="controls_padding_horizontal">0dp</dimen>
-    <dimen name="control_header_text_size">20sp</dimen>
+    <dimen name="controls_content_margin_horizontal">0dp</dimen>
+    <dimen name="control_header_text_size">24sp</dimen>
     <dimen name="control_item_text_size">16sp</dimen>
     <dimen name="control_menu_item_text_size">16sp</dimen>
     <dimen name="control_menu_item_min_height">56dp</dimen>
@@ -1189,6 +1190,8 @@
     <item name="controls_task_view_width_percentage" translatable="false" format="float" type="dimen">1.0</item>
     <dimen name="controls_task_view_right_margin">0dp</dimen>
 
+    <dimen name="controls_panel_corner_radius">42dp</dimen>
+
     <!-- Home Controls activity view detail panel-->
     <dimen name="controls_activity_view_corner_radius">@*android:dimen/config_bottomDialogCornerRadius</dimen>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e6ac59e..464ce03 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -479,6 +479,8 @@
     <string name="accessibility_desc_notification_shade">Notification shade.</string>
     <!-- Content description for the quick settings panel (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_desc_quick_settings">Quick settings.</string>
+    <!-- Content description for the split notification shade that also includes QS (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_desc_qs_notification_shade">Quick settings and Notification shade.</string>
     <!-- Content description for the lock screen (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_desc_lock_screen">Lock screen.</string>
     <!-- Content description for the work profile lock screen. This prevents work profile apps from being used, but personal apps can be used as normal (not shown on the screen). [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/screenshot/AndroidManifest.xml b/packages/SystemUI/screenshot/AndroidManifest.xml
index a405836..ba3dc8c 100644
--- a/packages/SystemUI/screenshot/AndroidManifest.xml
+++ b/packages/SystemUI/screenshot/AndroidManifest.xml
@@ -20,6 +20,7 @@
     <application>
         <activity
             android:name="com.android.systemui.testing.screenshot.ScreenshotActivity"
+            android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
             android:exported="true"
             android:theme="@style/Theme.SystemUI.Screenshot" />
     </application>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt b/packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt
index c9a25b0..b6aae69 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt
@@ -145,7 +145,7 @@
     override val namespace: String,
     override val default: Boolean = false,
 ) : SysPropFlag<Boolean> {
-    // TODO(b/223379190): Teamfood not supported for sysprop flags yet.
+    // TODO(b/268520433): Teamfood not supported for sysprop flags yet.
     override val teamfood: Boolean = false
 }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
index ead1a10..c4f1ce8 100644
--- a/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
@@ -29,8 +29,9 @@
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED
-import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_WAKE
+import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS
+import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD
 import android.util.Log
 import com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser
 import com.android.systemui.Dumpable
@@ -60,9 +61,27 @@
      * Indicates the origin for an active unlock request.
      */
     enum class ActiveUnlockRequestOrigin {
+        /**
+         * Trigger ActiveUnlock on wake ups that'd trigger FaceAuth, see [FaceWakeUpTriggersConfig]
+         */
         WAKE,
+
+        /**
+         * Trigger ActiveUnlock on unlock intents. This includes the bouncer showing or tapping on
+         * a notification. May also include wakeups: [wakeupsConsideredUnlockIntents].
+         */
         UNLOCK_INTENT,
+
+        /**
+         * Trigger ActiveUnlock on biometric failures. This may include soft errors depending on
+         * the other settings. See: [faceErrorsToTriggerBiometricFailOn],
+         * [faceAcquireInfoToTriggerBiometricFailOn].
+         */
         BIOMETRIC_FAIL,
+
+        /**
+         * Trigger ActiveUnlock when the assistant is triggered.
+         */
         ASSISTANT,
     }
 
@@ -85,6 +104,7 @@
     private var faceAcquireInfoToTriggerBiometricFailOn = mutableSetOf<Int>()
     private var onUnlockIntentWhenBiometricEnrolled = mutableSetOf<Int>()
     private var wakeupsConsideredUnlockIntents = mutableSetOf<Int>()
+    private var wakeupsToForceDismissKeyguard = mutableSetOf<Int>()
 
     private val settingsObserver = object : ContentObserver(handler) {
         private val wakeUri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_WAKE)
@@ -97,6 +117,8 @@
                 secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED)
         private val wakeupsConsideredUnlockIntentsUri =
             secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS)
+        private val wakeupsToForceDismissKeyguardUri =
+            secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD)
 
         fun register() {
             registerUri(
@@ -108,6 +130,7 @@
                         faceAcquireInfoUri,
                         unlockIntentWhenBiometricEnrolledUri,
                         wakeupsConsideredUnlockIntentsUri,
+                        wakeupsToForceDismissKeyguardUri,
                     )
             )
 
@@ -182,6 +205,15 @@
                     wakeupsConsideredUnlockIntents,
                     setOf(WAKE_REASON_UNFOLD_DEVICE))
             }
+
+            if (selfChange || uris.contains(wakeupsToForceDismissKeyguardUri)) {
+                processStringArray(
+                    secureSettings.getStringForUser(
+                        ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD,
+                        getCurrentUser()),
+                    wakeupsToForceDismissKeyguard,
+                    setOf(WAKE_REASON_UNFOLD_DEVICE))
+            }
         }
 
         /**
@@ -249,6 +281,14 @@
     }
 
     /**
+     * Whether the PowerManager wake reason should force dismiss the keyguard if active
+     * unlock is successful.
+     */
+    fun shouldWakeupForceDismissKeyguard(pmWakeReason: Int): Boolean {
+        return wakeupsToForceDismissKeyguard.contains(pmWakeReason)
+    }
+
+    /**
      * Whether to trigger active unlock based on where the request is coming from and
      * the current settings.
      */
@@ -321,6 +361,9 @@
         pw.println("   activeUnlockWakeupsConsideredUnlockIntents=${
             wakeupsConsideredUnlockIntents.map { PowerManager.wakeReasonToString(it) }
         }")
+        pw.println("   activeUnlockFromWakeupsToAlwaysDismissKeyguard=${
+            wakeupsToForceDismissKeyguard.map { PowerManager.wakeReasonToString(it) }
+        }")
 
         pw.println("Current state:")
         keyguardUpdateMonitor?.let {
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index 1254e1e..92ee373 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -48,7 +48,7 @@
 import com.android.systemui.plugins.log.LogBuffer
 import com.android.systemui.plugins.log.LogLevel.DEBUG
 import com.android.systemui.shared.regionsampling.RegionSampler
-import com.android.systemui.plugins.Weather
+import com.android.systemui.plugins.WeatherData
 import com.android.systemui.statusbar.policy.BatteryController
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback
 import com.android.systemui.statusbar.policy.ConfigurationController
@@ -291,10 +291,8 @@
                 clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context))
             }
 
-            override fun onWeatherDataChanged(data: Weather?) {
-                if (data != null) {
-                    clock?.events?.onWeatherDataChanged(data)
-                }
+            override fun onWeatherDataChanged(data: WeatherData) {
+                clock?.events?.onWeatherDataChanged(data)
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
index a25b281..c5a06b4 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
@@ -24,7 +24,6 @@
 import android.widget.Button;
 
 import com.android.internal.util.EmergencyAffordanceManager;
-import com.android.internal.widget.LockPatternUtils;
 
 /**
  * This class implements a smart emergency button that updates itself based
@@ -40,8 +39,6 @@
     private int mDownY;
     private boolean mLongPressWasDragged;
 
-    private LockPatternUtils mLockPatternUtils;
-
     private final boolean mEnableEmergencyCallWhileSimLocked;
 
     public EmergencyButton(Context context) {
@@ -58,7 +55,6 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mLockPatternUtils = new LockPatternUtils(mContext);
         if (mEmergencyAffordanceManager.needsEmergencyAffordance()) {
             setOnLongClickListener(v -> {
                 if (!mLongPressWasDragged
@@ -95,7 +91,8 @@
         return super.performLongClick();
     }
 
-    void updateEmergencyCallButton(boolean isInCall, boolean hasTelephonyRadio, boolean simLocked) {
+    void updateEmergencyCallButton(boolean isInCall, boolean hasTelephonyRadio, boolean simLocked,
+            boolean isSecure) {
         boolean visible = false;
         if (hasTelephonyRadio) {
             // Emergency calling requires a telephony radio.
@@ -107,7 +104,7 @@
                     visible = mEnableEmergencyCallWhileSimLocked;
                 } else {
                     // Only show if there is a secure screen (pin/pattern/SIM pin/SIM puk);
-                    visible = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser());
+                    visible = isSecure;
                 }
             }
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
index ea808eb..f7e8eb4 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
@@ -18,6 +18,7 @@
 
 import static com.android.systemui.DejankUtils.whitelistIpcs;
 
+import android.annotation.SuppressLint;
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
 import android.content.Intent;
@@ -31,16 +32,22 @@
 import android.util.Log;
 
 import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.dagger.KeyguardBouncerScope;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 import com.android.systemui.util.EmergencyDialerConstants;
 import com.android.systemui.util.ViewController;
 
+import java.util.concurrent.Executor;
+
 import javax.inject.Inject;
 
 /** View Controller for {@link com.android.keyguard.EmergencyButton}. */
@@ -57,6 +64,9 @@
     private final MetricsLogger mMetricsLogger;
 
     private EmergencyButtonCallback mEmergencyButtonCallback;
+    private LockPatternUtils mLockPatternUtils;
+    private Executor mMainExecutor;
+    private Executor mBackgroundExecutor;
 
     private final KeyguardUpdateMonitorCallback mInfoCallback =
             new KeyguardUpdateMonitorCallback() {
@@ -78,12 +88,15 @@
         }
     };
 
-    private EmergencyButtonController(@Nullable EmergencyButton view,
+    @VisibleForTesting
+    public EmergencyButtonController(@Nullable EmergencyButton view,
             ConfigurationController configurationController,
             KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager,
             PowerManager powerManager, ActivityTaskManager activityTaskManager,
             ShadeController shadeController,
-            @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger) {
+            @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger,
+            LockPatternUtils lockPatternUtils,
+            Executor mainExecutor, Executor backgroundExecutor) {
         super(view);
         mConfigurationController = configurationController;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -93,6 +106,9 @@
         mShadeController = shadeController;
         mTelecomManager = telecomManager;
         mMetricsLogger = metricsLogger;
+        mLockPatternUtils = lockPatternUtils;
+        mMainExecutor = mainExecutor;
+        mBackgroundExecutor = backgroundExecutor;
     }
 
     @Override
@@ -113,13 +129,27 @@
         mConfigurationController.removeCallback(mConfigurationListener);
     }
 
-    private void updateEmergencyCallButton() {
+    /**
+     * Updates the visibility of the emergency button.
+     *
+     * This method runs binder calls in a background thread.
+     */
+    @VisibleForTesting
+    @SuppressLint("MissingPermission")
+    public void updateEmergencyCallButton() {
         if (mView != null) {
-            mView.updateEmergencyCallButton(
-                    mTelecomManager != null && mTelecomManager.isInCall(),
-                    getContext().getPackageManager().hasSystemFeature(
-                            PackageManager.FEATURE_TELEPHONY),
-                    mKeyguardUpdateMonitor.isSimPinVoiceSecure());
+            // Run in bg thread to avoid throttling the main thread with binder call.
+            mBackgroundExecutor.execute(() -> {
+                boolean isInCall = mTelecomManager != null && mTelecomManager.isInCall();
+                boolean isSecure = mLockPatternUtils
+                        .isSecure(KeyguardUpdateMonitor.getCurrentUser());
+                mMainExecutor.execute(() -> mView.updateEmergencyCallButton(
+                        /* isInCall= */ isInCall,
+                        /* hasTelephonyRadio= */ getContext().getPackageManager()
+                                .hasSystemFeature(PackageManager.FEATURE_TELEPHONY),
+                        /* simLocked= */ mKeyguardUpdateMonitor.isSimPinVoiceSecure(),
+                        /* isSecure= */ isSecure));
+            });
         }
     }
 
@@ -129,6 +159,7 @@
     /**
      * Shows the emergency dialer or returns the user to the existing call.
      */
+    @SuppressLint("MissingPermission")
     public void takeEmergencyCallAction() {
         mMetricsLogger.action(MetricsEvent.ACTION_EMERGENCY_CALL);
         if (mPowerManager != null) {
@@ -136,29 +167,35 @@
         }
         mActivityTaskManager.stopSystemLockTaskMode();
         mShadeController.collapseShade(false);
-        if (mTelecomManager != null && mTelecomManager.isInCall()) {
-            mTelecomManager.showInCallScreen(false);
-            if (mEmergencyButtonCallback != null) {
-                mEmergencyButtonCallback.onEmergencyButtonClickedWhenInCall();
-            }
-        } else {
-            mKeyguardUpdateMonitor.reportEmergencyCallAction(true /* bypassHandler */);
-            if (mTelecomManager == null) {
-                Log.wtf(LOG_TAG, "TelecomManager was null, cannot launch emergency dialer");
-                return;
-            }
-            Intent emergencyDialIntent =
-                    mTelecomManager.createLaunchEmergencyDialerIntent(null /* number*/)
-                            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
-                                    | Intent.FLAG_ACTIVITY_CLEAR_TOP)
-                            .putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
-                                    EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON);
+        // Run in bg thread to avoid throttling the main thread with binder call.
+        mBackgroundExecutor.execute(() -> {
+            boolean isInCall = mTelecomManager != null && mTelecomManager.isInCall();
+            mMainExecutor.execute(() -> {
+                if (isInCall) {
+                    mTelecomManager.showInCallScreen(false);
+                    if (mEmergencyButtonCallback != null) {
+                        mEmergencyButtonCallback.onEmergencyButtonClickedWhenInCall();
+                    }
+                } else {
+                    mKeyguardUpdateMonitor.reportEmergencyCallAction(true /* bypassHandler */);
+                    if (mTelecomManager == null) {
+                        Log.wtf(LOG_TAG, "TelecomManager was null, cannot launch emergency dialer");
+                        return;
+                    }
+                    Intent emergencyDialIntent =
+                            mTelecomManager.createLaunchEmergencyDialerIntent(null /* number*/)
+                                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                                            | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+                                            | Intent.FLAG_ACTIVITY_CLEAR_TOP)
+                                    .putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
+                                            EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON);
 
-            getContext().startActivityAsUser(emergencyDialIntent,
-                    ActivityOptions.makeCustomAnimation(getContext(), 0, 0).toBundle(),
-                    new UserHandle(KeyguardUpdateMonitor.getCurrentUser()));
-        }
+                    getContext().startActivityAsUser(emergencyDialIntent,
+                            ActivityOptions.makeCustomAnimation(getContext(), 0, 0).toBundle(),
+                            new UserHandle(KeyguardUpdateMonitor.getCurrentUser()));
+                }
+            });
+        });
     }
 
     /** */
@@ -178,13 +215,19 @@
         @Nullable
         private final TelecomManager mTelecomManager;
         private final MetricsLogger mMetricsLogger;
+        private final LockPatternUtils mLockPatternUtils;
+        private final Executor mMainExecutor;
+        private final Executor mBackgroundExecutor;
 
         @Inject
         public Factory(ConfigurationController configurationController,
                 KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager,
                 PowerManager powerManager, ActivityTaskManager activityTaskManager,
                 ShadeController shadeController,
-                @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger) {
+                @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger,
+                LockPatternUtils lockPatternUtils,
+                @Main Executor mainExecutor,
+                @Background Executor backgroundExecutor) {
 
             mConfigurationController = configurationController;
             mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -194,14 +237,17 @@
             mShadeController = shadeController;
             mTelecomManager = telecomManager;
             mMetricsLogger = metricsLogger;
+            mLockPatternUtils = lockPatternUtils;
+            mMainExecutor = mainExecutor;
+            mBackgroundExecutor = backgroundExecutor;
         }
 
         /** Construct an {@link com.android.keyguard.EmergencyButtonController}. */
         public EmergencyButtonController create(EmergencyButton view) {
             return new EmergencyButtonController(view, mConfigurationController,
                     mKeyguardUpdateMonitor, mTelephonyManager, mPowerManager, mActivityTaskManager,
-                    mShadeController,
-                    mTelecomManager, mMetricsLogger);
+                    mShadeController, mTelecomManager, mMetricsLogger, mLockPatternUtils,
+                    mMainExecutor, mBackgroundExecutor);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt b/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt
index a0c43fb..788a66d 100644
--- a/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt
+++ b/packages/SystemUI/src/com/android/keyguard/FaceWakeUpTriggersConfig.kt
@@ -29,7 +29,7 @@
 import java.util.stream.Collectors
 import javax.inject.Inject
 
-/** Determines which device wake-ups should trigger face authentication. */
+/** Determines which device wake-ups should trigger passive authentication. */
 @SysUISingleton
 class FaceWakeUpTriggersConfig
 @Inject
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
deleted file mode 100644
index 2a389b6..0000000
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.keyguard;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.widget.FrameLayout;
-
-/**
- * Base class for keyguard view.  {@link #reset} is where you should
- * reset the state of your view.  Use the {@link KeyguardViewCallback} via
- * {@link #getCallback()} to send information back (such as poking the wake lock,
- * or finishing the keyguard).
- *
- * Handles intercepting of media keys that still work when the keyguard is
- * showing.
- */
-public class KeyguardHostView extends FrameLayout {
-
-    protected ViewMediatorCallback mViewMediatorCallback;
-    private boolean mIsInteractable;
-
-    public KeyguardHostView(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardHostView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void dispatchDraw(Canvas canvas) {
-        super.dispatchDraw(canvas);
-        if (mViewMediatorCallback != null) {
-            mViewMediatorCallback.keyguardDoneDrawing();
-        }
-    }
-
-    public void setViewMediatorCallback(ViewMediatorCallback viewMediatorCallback) {
-        mViewMediatorCallback = viewMediatorCallback;
-    }
-
-    /** Set true if the view can be interacted with */
-    public void setInteractable(boolean isInteractable) {
-        mIsInteractable = isInteractable;
-    }
-
-    /**
-     * Make sure to disallow touches while transitioning the bouncer, otherwise
-     * it can remain interactable even when barely visible.
-     */
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        return !mIsInteractable;
-    }
-
-    /** True to consume any events that are sent to it */
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        return true;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
deleted file mode 100644
index 77f6318..0000000
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
+++ /dev/null
@@ -1,538 +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.keyguard;
-
-import android.app.ActivityManager;
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.media.AudioManager;
-import android.os.SystemClock;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-import android.util.MathUtils;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.View.OnKeyListener;
-import android.view.ViewTreeObserver;
-import android.widget.FrameLayout;
-import android.window.OnBackAnimationCallback;
-
-import androidx.annotation.NonNull;
-
-import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback;
-import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.keyguard.dagger.KeyguardBouncerScope;
-import com.android.settingslib.Utils;
-import com.android.systemui.R;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.util.ViewController;
-
-import java.io.File;
-
-import javax.inject.Inject;
-
-/** Controller for a {@link KeyguardHostView}. */
-@KeyguardBouncerScope
-public class KeyguardHostViewController extends ViewController<KeyguardHostView> {
-    private static final String TAG = "KeyguardViewBase";
-    public static final boolean DEBUG = KeyguardConstants.DEBUG;
-    // Whether the volume keys should be handled by keyguard. If true, then
-    // they will be handled here for specific media types such as music, otherwise
-    // the audio service will bring up the volume dialog.
-    private static final boolean KEYGUARD_MANAGES_VOLUME = false;
-
-    private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
-
-    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-    private final KeyguardSecurityContainerController mKeyguardSecurityContainerController;
-    private final TelephonyManager mTelephonyManager;
-    private final ViewMediatorCallback mViewMediatorCallback;
-    private final AudioManager mAudioManager;
-
-    private ActivityStarter.OnDismissAction mDismissAction;
-    private Runnable mCancelAction;
-    private int mTranslationY;
-
-    private final KeyguardUpdateMonitorCallback mUpdateCallback =
-            new KeyguardUpdateMonitorCallback() {
-                @Override
-                public void onTrustGrantedForCurrentUser(
-                        boolean dismissKeyguard,
-                        boolean newlyUnlocked,
-                        TrustGrantFlags flags,
-                        String message
-                ) {
-                    if (dismissKeyguard) {
-                        if (!mView.isVisibleToUser()) {
-                            // The trust agent dismissed the keyguard without the user proving
-                            // that they are present (by swiping up to show the bouncer). That's
-                            // fine if the user proved presence via some other way to the trust
-                            // agent.
-                            Log.i(TAG, "TrustAgent dismissed Keyguard.");
-                        }
-                        mSecurityCallback.dismiss(
-                                false /* authenticated */,
-                                KeyguardUpdateMonitor.getCurrentUser(),
-                                /* bypassSecondaryLockScreen */ false,
-                                SecurityMode.Invalid
-                        );
-                    } else {
-                        if (flags.isInitiatedByUser() || flags.dismissKeyguardRequested()) {
-                            mViewMediatorCallback.playTrustedSound();
-                        }
-                    }
-                }
-            };
-
-    private final SecurityCallback mSecurityCallback = new SecurityCallback() {
-
-        @Override
-        public boolean dismiss(boolean authenticated, int targetUserId,
-                boolean bypassSecondaryLockScreen, SecurityMode expectedSecurityMode) {
-            return mKeyguardSecurityContainerController.showNextSecurityScreenOrFinish(
-                    authenticated, targetUserId, bypassSecondaryLockScreen, expectedSecurityMode);
-        }
-
-        @Override
-        public void userActivity() {
-            mViewMediatorCallback.userActivity();
-        }
-
-        @Override
-        public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput) {
-            mViewMediatorCallback.setNeedsInput(needsInput);
-        }
-
-        /**
-         * Authentication has happened and it's time to dismiss keyguard. This function
-         * should clean up and inform KeyguardViewMediator.
-         *
-         * @param strongAuth whether the user has authenticated with strong authentication like
-         *                   pattern, password or PIN but not by trust agents or fingerprint
-         * @param targetUserId a user that needs to be the foreground user at the dismissal
-         *                    completion.
-         */
-        @Override
-        public void finish(boolean strongAuth, int targetUserId) {
-            // If there's a pending runnable because the user interacted with a widget
-            // and we're leaving keyguard, then run it.
-            boolean deferKeyguardDone = false;
-            if (mDismissAction != null) {
-                deferKeyguardDone = mDismissAction.onDismiss();
-                mDismissAction = null;
-                mCancelAction = null;
-            }
-            if (mViewMediatorCallback != null) {
-                if (deferKeyguardDone) {
-                    mViewMediatorCallback.keyguardDonePending(strongAuth, targetUserId);
-                } else {
-                    mViewMediatorCallback.keyguardDone(strongAuth, targetUserId);
-                }
-            }
-        }
-
-        @Override
-        public void reset() {
-            mViewMediatorCallback.resetKeyguard();
-        }
-
-        @Override
-        public void onCancelClicked() {
-            mViewMediatorCallback.onCancelClicked();
-        }
-    };
-
-    private OnKeyListener mOnKeyListener = (v, keyCode, event) -> interceptMediaKey(event);
-
-    @Inject
-    public KeyguardHostViewController(KeyguardHostView view,
-            KeyguardUpdateMonitor keyguardUpdateMonitor,
-            AudioManager audioManager,
-            TelephonyManager telephonyManager,
-            ViewMediatorCallback viewMediatorCallback,
-            KeyguardSecurityContainerController.Factory
-                    keyguardSecurityContainerControllerFactory) {
-        super(view);
-        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
-        mAudioManager = audioManager;
-        mTelephonyManager = telephonyManager;
-        mViewMediatorCallback = viewMediatorCallback;
-        mKeyguardSecurityContainerController = keyguardSecurityContainerControllerFactory.create(
-                mSecurityCallback);
-    }
-
-    /** Initialize the Controller. */
-    public void onInit() {
-        mKeyguardSecurityContainerController.init();
-        updateResources();
-    }
-
-    @Override
-    protected void onViewAttached() {
-        mView.setViewMediatorCallback(mViewMediatorCallback);
-        // Update ViewMediator with the current input method requirements
-        mViewMediatorCallback.setNeedsInput(mKeyguardSecurityContainerController.needsInput());
-        mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
-        mView.setOnKeyListener(mOnKeyListener);
-        mKeyguardSecurityContainerController.showPrimarySecurityScreen(false);
-    }
-
-    @Override
-    protected void onViewDetached() {
-        mKeyguardUpdateMonitor.removeCallback(mUpdateCallback);
-        mView.setOnKeyListener(null);
-    }
-
-     /** Called before this view is being removed. */
-    public void cleanUp() {
-        mKeyguardSecurityContainerController.onPause();
-    }
-
-    public void resetSecurityContainer() {
-        mKeyguardSecurityContainerController.reset();
-    }
-
-    /**
-     * Reinflate the view flipper child view.
-     */
-    public void reinflateViewFlipper() {
-        mKeyguardSecurityContainerController.reinflateViewFlipper();
-    }
-
-    /**
-     * Dismisses the keyguard by going to the next screen or making it gone.
-     * @param targetUserId a user that needs to be the foreground user at the dismissal completion.
-     * @return True if the keyguard is done.
-     */
-    public boolean dismiss(int targetUserId) {
-        return mSecurityCallback.dismiss(false, targetUserId, false,
-                getCurrentSecurityMode());
-    }
-
-    /**
-     * Called when the Keyguard is actively shown on the screen.
-     */
-    public void onResume() {
-        if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
-        mKeyguardSecurityContainerController.onResume(KeyguardSecurityView.SCREEN_ON);
-        mView.requestFocus();
-    }
-
-    public CharSequence getAccessibilityTitleForCurrentMode() {
-        return mKeyguardSecurityContainerController.getTitle();
-    }
-
-    /**
-     * Starts the animation when the Keyguard gets shown.
-     */
-    public void appear() {
-        // We might still be collapsed and the view didn't have time to layout yet or still
-        // be small, let's wait on the predraw to do the animation in that case.
-        mView.getViewTreeObserver().addOnPreDrawListener(
-                new ViewTreeObserver.OnPreDrawListener() {
-                    @Override
-                    public boolean onPreDraw() {
-                        mView.getViewTreeObserver().removeOnPreDrawListener(this);
-                        mKeyguardSecurityContainerController.startAppearAnimation();
-                        return true;
-                    }
-                });
-        mView.requestLayout();
-    }
-
-    /**
-     * Show a string explaining why the security view needs to be solved.
-     *
-     * @param reason a flag indicating which string should be shown, see
-     *               {@link KeyguardSecurityView#PROMPT_REASON_NONE},
-     *               {@link KeyguardSecurityView#PROMPT_REASON_RESTART},
-     *               {@link KeyguardSecurityView#PROMPT_REASON_TIMEOUT}, and
-     *               {@link KeyguardSecurityView#PROMPT_REASON_PREPARE_FOR_UPDATE}.
-     */
-    public void showPromptReason(int reason) {
-        mKeyguardSecurityContainerController.showPromptReason(reason);
-    }
-
-    public void showMessage(CharSequence message, ColorStateList colorState) {
-        mKeyguardSecurityContainerController.showMessage(message, colorState);
-    }
-
-    public void showErrorMessage(CharSequence customMessage) {
-        showMessage(customMessage, Utils.getColorError(mView.getContext()));
-    }
-
-    /**
-     * Sets an action to run when keyguard finishes.
-     *
-     * @param action
-     */
-    public void setOnDismissAction(ActivityStarter.OnDismissAction action, Runnable cancelAction) {
-        if (mCancelAction != null) {
-            mCancelAction.run();
-            mCancelAction = null;
-        }
-        mDismissAction = action;
-        mCancelAction = cancelAction;
-    }
-
-    public void cancelDismissAction() {
-        setOnDismissAction(null, null);
-    }
-
-    public void startDisappearAnimation(Runnable finishRunnable) {
-        if (!mKeyguardSecurityContainerController.startDisappearAnimation(finishRunnable)
-                && finishRunnable != null) {
-            finishRunnable.run();
-        }
-    }
-
-    /**
-     * Called when the Keyguard is not actively shown anymore on the screen.
-     */
-    public void onPause() {
-        if (DEBUG) {
-            Log.d(TAG, String.format("screen off, instance %s at %s",
-                    Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
-        }
-        mKeyguardSecurityContainerController.showPrimarySecurityScreen(true);
-        mKeyguardSecurityContainerController.onPause();
-        mView.clearFocus();
-    }
-
-    /**
-     * Called when the view needs to be shown.
-     */
-    public void showPrimarySecurityScreen() {
-        if (DEBUG) Log.d(TAG, "show()");
-        mKeyguardSecurityContainerController.showPrimarySecurityScreen(false);
-    }
-
-    /**
-     * Fades and translates in/out the security screen.
-     * Fades in as expansion approaches 0.
-     * Animation duration is between 0.33f and 0.67f of panel expansion fraction.
-     * @param fraction amount of the screen that should show.
-     */
-    public void setExpansion(float fraction) {
-        float scaledFraction = BouncerPanelExpansionCalculator.showBouncerProgress(fraction);
-        mView.setAlpha(MathUtils.constrain(1 - scaledFraction, 0f, 1f));
-        mView.setTranslationY(scaledFraction * mTranslationY);
-    }
-
-    /**
-     * When bouncer was visible and is starting to become hidden.
-     */
-    public void onStartingToHide() {
-        mKeyguardSecurityContainerController.onStartingToHide();
-    }
-
-    /** Called when bouncer visibility changes. */
-    public void onBouncerVisibilityChanged(@View.Visibility int visibility) {
-        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(visibility);
-    }
-
-    public boolean hasDismissActions() {
-        return mDismissAction != null || mCancelAction != null;
-    }
-
-    public SecurityMode getCurrentSecurityMode() {
-        return mKeyguardSecurityContainerController.getCurrentSecurityMode();
-    }
-
-    public int getTop() {
-        int top = mView.getTop();
-        // The password view has an extra top padding that should be ignored.
-        if (getCurrentSecurityMode() == SecurityMode.Password) {
-            View messageArea = mView.findViewById(R.id.keyguard_message_area);
-            top += messageArea.getTop();
-        }
-        return top;
-    }
-
-    public boolean handleBackKey() {
-        SecurityMode securityMode = mKeyguardSecurityContainerController.getCurrentSecurityMode();
-        if (securityMode != SecurityMode.None) {
-            mKeyguardSecurityContainerController.dismiss(
-                    false, KeyguardUpdateMonitor.getCurrentUser(), securityMode);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * In general, we enable unlocking the insecure keyguard with the menu key. However, there are
-     * some cases where we wish to disable it, notably when the menu button placement or technology
-     * is prone to false positives.
-     *
-     * @return true if the menu key should be enabled
-     */
-    public boolean shouldEnableMenuKey() {
-        final Resources res = mView.getResources();
-        final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen);
-        final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
-        final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
-        return !configDisabled || isTestHarness || fileOverride;
-    }
-
-    /**
-     * @return true if the current bouncer is password
-     */
-    public boolean dispatchBackKeyEventPreIme() {
-        if (mKeyguardSecurityContainerController.getCurrentSecurityMode()
-                == SecurityMode.Password) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * @return the {@link OnBackAnimationCallback} to animate this view during a back gesture.
-     */
-    @NonNull
-    public OnBackAnimationCallback getBackCallback() {
-        return mKeyguardSecurityContainerController.getBackCallback();
-    }
-
-    /**
-     * Allows the media keys to work when the keyguard is showing.
-     * The media keys should be of no interest to the actual keyguard view(s),
-     * so intercepting them here should not be of any harm.
-     * @param event The key event
-     * @return whether the event was consumed as a media key.
-     */
-    public boolean interceptMediaKey(KeyEvent event) {
-        int keyCode = event.getKeyCode();
-        if (event.getAction() == KeyEvent.ACTION_DOWN) {
-            switch (keyCode) {
-                case KeyEvent.KEYCODE_MEDIA_PLAY:
-                case KeyEvent.KEYCODE_MEDIA_PAUSE:
-                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
-                    /* Suppress PLAY/PAUSE toggle when phone is ringing or
-                     * in-call to avoid music playback */
-                    if (mTelephonyManager != null &&
-                            mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
-                        return true;  // suppress key event
-                    }
-                case KeyEvent.KEYCODE_MUTE:
-                case KeyEvent.KEYCODE_HEADSETHOOK:
-                case KeyEvent.KEYCODE_MEDIA_STOP:
-                case KeyEvent.KEYCODE_MEDIA_NEXT:
-                case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
-                case KeyEvent.KEYCODE_MEDIA_REWIND:
-                case KeyEvent.KEYCODE_MEDIA_RECORD:
-                case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
-                case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
-                    handleMediaKeyEvent(event);
-                    return true;
-                }
-
-                case KeyEvent.KEYCODE_VOLUME_UP:
-                case KeyEvent.KEYCODE_VOLUME_DOWN:
-                case KeyEvent.KEYCODE_VOLUME_MUTE: {
-                    if (KEYGUARD_MANAGES_VOLUME) {
-                        // Volume buttons should only function for music (local or remote).
-                        // TODO: Actually handle MUTE.
-                        mAudioManager.adjustSuggestedStreamVolume(
-                                keyCode == KeyEvent.KEYCODE_VOLUME_UP
-                                        ? AudioManager.ADJUST_RAISE
-                                        : AudioManager.ADJUST_LOWER /* direction */,
-                                AudioManager.STREAM_MUSIC /* stream */, 0 /* flags */);
-                        // Don't execute default volume behavior
-                        return true;
-                    } else {
-                        return false;
-                    }
-                }
-            }
-        } else if (event.getAction() == KeyEvent.ACTION_UP) {
-            switch (keyCode) {
-                case KeyEvent.KEYCODE_MUTE:
-                case KeyEvent.KEYCODE_HEADSETHOOK:
-                case KeyEvent.KEYCODE_MEDIA_PLAY:
-                case KeyEvent.KEYCODE_MEDIA_PAUSE:
-                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
-                case KeyEvent.KEYCODE_MEDIA_STOP:
-                case KeyEvent.KEYCODE_MEDIA_NEXT:
-                case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
-                case KeyEvent.KEYCODE_MEDIA_REWIND:
-                case KeyEvent.KEYCODE_MEDIA_RECORD:
-                case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
-                case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
-                    handleMediaKeyEvent(event);
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-
-    private void handleMediaKeyEvent(KeyEvent keyEvent) {
-        mAudioManager.dispatchMediaKeyEvent(keyEvent);
-    }
-
-    public void finish(boolean strongAuth, int currentUser) {
-        mSecurityCallback.finish(strongAuth, currentUser);
-    }
-
-    /**
-     * Apply keyguard configuration from the currently active resources. This can be called when the
-     * device configuration changes, to re-apply some resources that are qualified on the device
-     * configuration.
-     */
-    public void updateResources() {
-        int gravity;
-
-        Resources resources = mView.getResources();
-
-        if (resources.getBoolean(R.bool.can_use_one_handed_bouncer)) {
-            gravity = resources.getInteger(
-                    R.integer.keyguard_host_view_one_handed_gravity);
-        } else {
-            gravity = resources.getInteger(R.integer.keyguard_host_view_gravity);
-        }
-
-        mTranslationY = resources
-                .getDimensionPixelSize(R.dimen.keyguard_host_view_translation_y);
-        // Android SysUI uses a FrameLayout as the top-level, but Auto uses RelativeLayout.
-        // We're just changing the gravity here though (which can't be applied to RelativeLayout),
-        // so only attempt the update if mView is inside a FrameLayout.
-        if (mView.getLayoutParams() instanceof FrameLayout.LayoutParams) {
-            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mView.getLayoutParams();
-            if (lp.gravity != gravity) {
-                lp.gravity = gravity;
-                mView.setLayoutParams(lp);
-            }
-        }
-
-        if (mKeyguardSecurityContainerController != null) {
-            mKeyguardSecurityContainerController.updateResources();
-        }
-    }
-
-    /** Update keyguard position based on a tapped X coordinate. */
-    public void updateKeyguardPosition(float x) {
-        if (mKeyguardSecurityContainerController != null) {
-            mKeyguardSecurityContainerController.updateKeyguardPosition(x);
-        }
-    }
-
-    /** Set true if the view can be interacted with */
-    public void setInteractable(boolean isInteractable) {
-        mView.setInteractable(isInteractable);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
index b143c5b..7054393 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
@@ -51,26 +51,7 @@
     // The following is used to ignore callbacks from SecurityViews that are no longer current
     // (e.g. face unlock). This avoids unwanted asynchronous events from messing with the
     // state for the current security method.
-    private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {
-        @Override
-        public void userActivity() { }
-        @Override
-        public void reportUnlockAttempt(int userId, boolean success, int timeoutMs) { }
-        @Override
-        public boolean isVerifyUnlockOnly() {
-            return false;
-        }
-        @Override
-        public void dismiss(boolean securityVerified, int targetUserId,
-                SecurityMode expectedSecurityMode) { }
-        @Override
-        public void dismiss(boolean authenticated, int targetId,
-                boolean bypassSecondaryLockScreen, SecurityMode expectedSecurityMode) { }
-        @Override
-        public void onUserInput() { }
-        @Override
-        public void reset() {}
-    };
+    private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {};
 
     protected KeyguardInputViewController(T view, SecurityMode securityMode,
             KeyguardSecurityCallback keyguardSecurityCallback,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java
index bc72f79..bf9c3bb 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java
@@ -25,7 +25,9 @@
      * @param targetUserId a user that needs to be the foreground user at the dismissal completion.
      * @param expectedSecurityMode The security mode that is invoking this dismiss.
      */
-    void dismiss(boolean securityVerified, int targetUserId, SecurityMode expectedSecurityMode);
+    default void dismiss(boolean securityVerified, int targetUserId,
+            SecurityMode expectedSecurityMode) {
+    }
 
     /**
      * Dismiss the given security screen.
@@ -35,19 +37,26 @@
      *                                  if any, during this dismissal.
      * @param expectedSecurityMode The security mode that is invoking this dismiss.
      */
-    void dismiss(boolean securityVerified, int targetUserId, boolean bypassSecondaryLockScreen,
-            SecurityMode expectedSecurityMode);
+    default boolean dismiss(boolean securityVerified, int targetUserId,
+            boolean bypassSecondaryLockScreen,
+            SecurityMode expectedSecurityMode) {
+        return false;
+    }
 
     /**
      * Manually report user activity to keep the device awake.
      */
-    void userActivity();
+    default void userActivity() {
+    }
 
     /**
      * Checks if keyguard is in "verify credentials" mode.
+     *
      * @return true if user has been asked to verify security.
      */
-    boolean isVerifyUnlockOnly();
+    default boolean isVerifyUnlockOnly() {
+        return false;
+    }
 
     /**
      * Call to report an unlock attempt.
@@ -56,12 +65,14 @@
      * @param timeoutMs timeout in milliseconds to wait before reattempting an unlock.
      *                  Only nonzero if 'success' is false
      */
-    void reportUnlockAttempt(int userId, boolean success, int timeoutMs);
+    default void reportUnlockAttempt(int userId, boolean success, int timeoutMs) {
+    }
 
     /**
      * Resets the keyguard view.
      */
-    void reset();
+    default void reset() {
+    }
 
     /**
      * Call when cancel button is pressed in bouncer.
@@ -73,5 +84,19 @@
     /**
      * Invoked whenever users are typing their password or drawing a pattern.
      */
-    void onUserInput();
+    default void onUserInput() {
+    }
+
+
+    /**
+     * Dismisses keyguard and go to unlocked state.
+     */
+    default void finish(boolean strongAuth, int targetUserId) {
+    }
+
+    /**
+     * Specifies that security mode has changed.
+     */
+    default void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput) {
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 9f07a20..f164e7d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -50,6 +50,7 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BlendMode;
+import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
@@ -164,6 +165,8 @@
     private boolean mDisappearAnimRunning;
     private SwipeListener mSwipeListener;
     private ViewMode mViewMode = new DefaultViewMode();
+    private boolean mIsInteractable;
+    protected ViewMediatorCallback mViewMediatorCallback;
     /*
      * Using MODE_UNINITIALIZED to mean the view mode is set to DefaultViewMode, but init() has not
      * yet been called on it. This will happen when the ViewController is initialized.
@@ -265,31 +268,6 @@
         return mBackCallback;
     }
 
-    // Used to notify the container when something interesting happens.
-    public interface SecurityCallback {
-        /**
-         * Potentially dismiss the current security screen, after validating that all device
-         * security has been unlocked. Otherwise show the next screen.
-         */
-        boolean dismiss(boolean authenticated, int targetUserId, boolean bypassSecondaryLockScreen,
-                SecurityMode expectedSecurityMode);
-
-        void userActivity();
-
-        void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput);
-
-        /**
-         * @param strongAuth   wheher the user has authenticated with strong authentication like
-         *                     pattern, password or PIN but not by trust agents or fingerprint
-         * @param targetUserId a user that needs to be the foreground user at the finish completion.
-         */
-        void finish(boolean strongAuth, int targetUserId);
-
-        void reset();
-
-        void onCancelClicked();
-    }
-
     public interface SwipeListener {
         void onSwipeUp();
     }
@@ -342,7 +320,7 @@
 
     public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-        mSpringAnimation = new SpringAnimation(this, DynamicAnimation.Y);
+        mSpringAnimation = new SpringAnimation(this, DynamicAnimation.TRANSLATION_Y);
         mViewConfiguration = ViewConfiguration.get(context);
         mDoubleTapDetector = new GestureDetector(context, new DoubleTapListener());
     }
@@ -445,6 +423,11 @@
         mViewMode.reset();
     }
 
+    /** Set true if the view can be interacted with */
+    public void setInteractable(boolean isInteractable) {
+        mIsInteractable = isInteractable;
+    }
+
     @Override
     public boolean shouldDelayChildPressedState() {
         return true;
@@ -452,6 +435,10 @@
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent event) {
+        if (!mIsInteractable) {
+            return true;
+        }
+
         boolean result =  mMotionEventListeners.stream().anyMatch(
                 listener -> listener.onInterceptTouchEvent(event))
                 || super.onInterceptTouchEvent(event);
@@ -505,12 +492,14 @@
             case MotionEvent.ACTION_MOVE:
                 mVelocityTracker.addMovement(event);
                 int pointerIndex = event.findPointerIndex(mActivePointerId);
-                float y = event.getY(pointerIndex);
-                if (mLastTouchY != -1) {
-                    float dy = y - mLastTouchY;
-                    setTranslationY(getTranslationY() + dy * TOUCH_Y_MULTIPLIER);
+                if (pointerIndex != -1) {
+                    float y = event.getY(pointerIndex);
+                    if (mLastTouchY != -1) {
+                        float dy = y - mLastTouchY;
+                        setTranslationY(getTranslationY() + dy * TOUCH_Y_MULTIPLIER);
+                    }
+                    mLastTouchY = y;
                 }
-                mLastTouchY = y;
                 break;
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_CANCEL:
@@ -639,6 +628,18 @@
         return insets.inset(0, 0, 0, inset);
     }
 
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        super.dispatchDraw(canvas);
+        if (mViewMediatorCallback != null) {
+            mViewMediatorCallback.keyguardDoneDrawing();
+        }
+    }
+
+    public void setViewMediatorCallback(ViewMediatorCallback viewMediatorCallback) {
+        mViewMediatorCallback = viewMediatorCallback;
+    }
+
     private void showDialog(String title, String message) {
         if (mAlertDialog != null) {
             mAlertDialog.dismiss();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index d9b8895..b8bb260 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -17,7 +17,6 @@
 package com.android.keyguard;
 
 import static android.app.StatusBarManager.SESSION_KEYGUARD;
-import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
 
 import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_BIOMETRIC;
 import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_EXTENDED_ACCESS;
@@ -29,18 +28,26 @@
 import static com.android.keyguard.KeyguardSecurityContainer.USER_TYPE_WORK_PROFILE;
 import static com.android.systemui.DejankUtils.whitelistIpcs;
 
+import android.app.ActivityManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.Intent;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.hardware.biometrics.BiometricOverlayConstants;
-import android.hardware.biometrics.BiometricSourceType;
+import android.media.AudioManager;
 import android.metrics.LogMaker;
+import android.os.SystemClock;
 import android.os.UserHandle;
+import android.telephony.TelephonyManager;
 import android.util.Log;
+import android.util.MathUtils;
 import android.util.Slog;
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewTreeObserver;
+import android.widget.FrameLayout;
 import android.window.OnBackAnimationCallback;
 
 import androidx.annotation.NonNull;
@@ -54,7 +61,6 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardSecurityContainer.BouncerUiEvent;
-import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback;
 import com.android.keyguard.KeyguardSecurityContainer.SwipeListener;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.keyguard.dagger.KeyguardBouncerScope;
@@ -68,6 +74,7 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.log.SessionTracker;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.shared.system.SysUiStatsLog;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -76,6 +83,7 @@
 import com.android.systemui.util.ViewController;
 import com.android.systemui.util.settings.GlobalSettings;
 
+import java.io.File;
 import java.util.Optional;
 
 import javax.inject.Inject;
@@ -96,7 +104,6 @@
     private final UiEventLogger mUiEventLogger;
     private final KeyguardStateController mKeyguardStateController;
     private final KeyguardSecurityViewFlipperController mSecurityViewFlipperController;
-    private final SecurityCallback mSecurityCallback;
     private final ConfigurationController mConfigurationController;
     private final FalsingCollector mFalsingCollector;
     private final FalsingManager mFalsingManager;
@@ -106,6 +113,20 @@
     private final SessionTracker mSessionTracker;
     private final Optional<SideFpsController> mSideFpsController;
     private final FalsingA11yDelegate mFalsingA11yDelegate;
+    private int mTranslationY;
+    // Whether the volume keys should be handled by keyguard. If true, then
+    // they will be handled here for specific media types such as music, otherwise
+    // the audio service will bring up the volume dialog.
+    private static final boolean KEYGUARD_MANAGES_VOLUME = false;
+
+    private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
+
+    private final TelephonyManager mTelephonyManager;
+    private final ViewMediatorCallback mViewMediatorCallback;
+    private final AudioManager mAudioManager;
+    private View.OnKeyListener mOnKeyListener = (v, keyCode, event) -> interceptMediaKey(event);
+    private ActivityStarter.OnDismissAction mDismissAction;
+    private Runnable mCancelAction;
 
     private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED;
 
@@ -150,11 +171,6 @@
     };
 
     private KeyguardSecurityCallback mKeyguardSecurityCallback = new KeyguardSecurityCallback() {
-        public void userActivity() {
-            if (mSecurityCallback != null) {
-                mSecurityCallback.userActivity();
-            }
-        }
 
         @Override
         public void onUserInput() {
@@ -169,16 +185,23 @@
         }
 
         @Override
-        public void dismiss(boolean authenticated, int targetId,
+        public boolean dismiss(boolean authenticated, int targetId,
                 boolean bypassSecondaryLockScreen, SecurityMode expectedSecurityMode) {
-            mSecurityCallback.dismiss(authenticated, targetId, bypassSecondaryLockScreen,
-                    expectedSecurityMode);
+            return showNextSecurityScreenOrFinish(
+                    authenticated, targetId, bypassSecondaryLockScreen, expectedSecurityMode);
         }
 
+        @Override
+        public void userActivity() {
+            mViewMediatorCallback.userActivity();
+        }
+
+        @Override
         public boolean isVerifyUnlockOnly() {
             return false;
         }
 
+        @Override
         public void reportUnlockAttempt(int userId, boolean success, int timeoutMs) {
             int bouncerSide = SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__SIDE__DEFAULT;
             if (mView.isSidedSecurityMode()) {
@@ -215,12 +238,47 @@
                             : BouncerUiEvent.BOUNCER_PASSWORD_FAILURE, getSessionId());
         }
 
+        @Override
         public void reset() {
-            mSecurityCallback.reset();
+            mViewMediatorCallback.resetKeyguard();
         }
 
+        @Override
         public void onCancelClicked() {
-            mSecurityCallback.onCancelClicked();
+            mViewMediatorCallback.onCancelClicked();
+        }
+
+        /**
+         * Authentication has happened and it's time to dismiss keyguard. This function
+         * should clean up and inform KeyguardViewMediator.
+         *
+         * @param strongAuth whether the user has authenticated with strong authentication like
+         *                   pattern, password or PIN but not by trust agents or fingerprint
+         * @param targetUserId a user that needs to be the foreground user at the dismissal
+         *                    completion.
+         */
+        @Override
+        public void finish(boolean strongAuth, int targetUserId) {
+            // If there's a pending runnable because the user interacted with a widget
+            // and we're leaving keyguard, then run it.
+            boolean deferKeyguardDone = false;
+            if (mDismissAction != null) {
+                deferKeyguardDone = mDismissAction.onDismiss();
+                mDismissAction = null;
+                mCancelAction = null;
+            }
+            if (mViewMediatorCallback != null) {
+                if (deferKeyguardDone) {
+                    mViewMediatorCallback.keyguardDonePending(strongAuth, targetUserId);
+                } else {
+                    mViewMediatorCallback.keyguardDone(strongAuth, targetUserId);
+                }
+            }
+        }
+
+        @Override
+        public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput) {
+            mViewMediatorCallback.setNeedsInput(needsInput);
         }
     };
 
@@ -260,29 +318,44 @@
                     KeyguardSecurityContainerController.this.onDensityOrFontScaleChanged();
                 }
             };
-    private boolean mBouncerVisible = false;
     private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
             new KeyguardUpdateMonitorCallback() {
                 @Override
-                public void onDevicePolicyManagerStateChanged() {
-                    showPrimarySecurityScreen(false);
-                }
-
-                @Override
-                public void onBiometricRunningStateChanged(boolean running,
-                        BiometricSourceType biometricSourceType) {
-                    if (biometricSourceType == FINGERPRINT) {
-                        updateSideFpsVisibility();
+                public void onTrustGrantedForCurrentUser(
+                        boolean dismissKeyguard,
+                        boolean newlyUnlocked,
+                        TrustGrantFlags flags,
+                        String message
+                ) {
+                    if (dismissKeyguard) {
+                        if (!mView.isVisibleToUser()) {
+                            // The trust agent dismissed the keyguard without the user proving
+                            // that they are present (by swiping up to show the bouncer). That's
+                            // fine if the user proved presence via some other way to the trust
+                            // agent.
+                            Log.i(TAG, "TrustAgent dismissed Keyguard.");
+                        }
+                        mKeyguardSecurityCallback.dismiss(
+                                false /* authenticated */,
+                                KeyguardUpdateMonitor.getCurrentUser(),
+                                /* bypassSecondaryLockScreen */ false,
+                                SecurityMode.Invalid
+                        );
+                    } else {
+                        if (flags.isInitiatedByUser() || flags.dismissKeyguardRequested()) {
+                            mViewMediatorCallback.playTrustedSound();
+                        }
                     }
                 }
 
                 @Override
-                public void onStrongAuthStateChanged(int userId) {
-                    updateSideFpsVisibility();
+                public void onDevicePolicyManagerStateChanged() {
+                    showPrimarySecurityScreen(false);
                 }
             };
 
-    private KeyguardSecurityContainerController(KeyguardSecurityContainer view,
+    @Inject
+    public KeyguardSecurityContainerController(KeyguardSecurityContainer view,
             AdminSecondaryLockScreenController.Factory adminSecondaryLockScreenControllerFactory,
             LockPatternUtils lockPatternUtils,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
@@ -290,7 +363,6 @@
             MetricsLogger metricsLogger,
             UiEventLogger uiEventLogger,
             KeyguardStateController keyguardStateController,
-            SecurityCallback securityCallback,
             KeyguardSecurityViewFlipperController securityViewFlipperController,
             ConfigurationController configurationController,
             FalsingCollector falsingCollector,
@@ -300,7 +372,11 @@
             GlobalSettings globalSettings,
             SessionTracker sessionTracker,
             Optional<SideFpsController> sideFpsController,
-            FalsingA11yDelegate falsingA11yDelegate) {
+            FalsingA11yDelegate falsingA11yDelegate,
+            TelephonyManager telephonyManager,
+            ViewMediatorCallback viewMediatorCallback,
+            AudioManager audioManager
+    ) {
         super(view);
         mLockPatternUtils = lockPatternUtils;
         mUpdateMonitor = keyguardUpdateMonitor;
@@ -308,7 +384,6 @@
         mMetricsLogger = metricsLogger;
         mUiEventLogger = uiEventLogger;
         mKeyguardStateController = keyguardStateController;
-        mSecurityCallback = securityCallback;
         mSecurityViewFlipperController = securityViewFlipperController;
         mAdminSecondaryLockScreenController = adminSecondaryLockScreenControllerFactory.create(
                 mKeyguardSecurityCallback);
@@ -322,11 +397,15 @@
         mSessionTracker = sessionTracker;
         mSideFpsController = sideFpsController;
         mFalsingA11yDelegate = falsingA11yDelegate;
+        mTelephonyManager = telephonyManager;
+        mViewMediatorCallback = viewMediatorCallback;
+        mAudioManager = audioManager;
     }
 
     @Override
     public void onInit() {
         mSecurityViewFlipperController.init();
+        updateResources();
         configureMode();
     }
 
@@ -337,6 +416,11 @@
         mView.addMotionEventListener(mGlobalTouchListener);
         mConfigurationController.addCallback(mConfigurationListener);
         mUserSwitcherController.addUserSwitchCallback(mUserSwitchCallback);
+        mView.setViewMediatorCallback(mViewMediatorCallback);
+        // Update ViewMediator with the current input method requirements
+        mViewMediatorCallback.setNeedsInput(needsInput());
+        mView.setOnKeyListener(mOnKeyListener);
+        showPrimarySecurityScreen(false);
     }
 
     @Override
@@ -349,39 +433,34 @@
 
     /** */
     public void onPause() {
+        if (DEBUG) {
+            Log.d(TAG, String.format("screen off, instance %s at %s",
+                    Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
+        }
+        showPrimarySecurityScreen(true);
         mAdminSecondaryLockScreenController.hide();
         if (mCurrentSecurityMode != SecurityMode.None) {
             getCurrentSecurityController().onPause();
         }
         mView.onPause();
-        // It might happen that onStartingToHide is not called when the device is locked while on
-        // bouncer.
-        setBouncerVisible(false);
+        mView.clearFocus();
     }
 
-    private void updateSideFpsVisibility() {
+    /**
+     * Shows and hides the side finger print sensor animation.
+     *
+     * @param isVisible sets whether we show or hide the side fps animation
+     */
+    public void updateSideFpsVisibility(boolean isVisible) {
         if (!mSideFpsController.isPresent()) {
             return;
         }
-        final boolean sfpsEnabled = getResources().getBoolean(
-                R.bool.config_show_sidefps_hint_on_bouncer);
-        final boolean fpsDetectionRunning = mUpdateMonitor.isFingerprintDetectionRunning();
-        final boolean isUnlockingWithFpAllowed =
-                mUpdateMonitor.isUnlockingWithFingerprintAllowed();
 
-        boolean toShow = mBouncerVisible && sfpsEnabled && fpsDetectionRunning
-                && isUnlockingWithFpAllowed;
-
-        if (DEBUG) {
-            Log.d(TAG, "sideFpsToShow=" + toShow + ", "
-                    + "mBouncerVisible=" + mBouncerVisible + ", "
-                    + "configEnabled=" + sfpsEnabled + ", "
-                    + "fpsDetectionRunning=" + fpsDetectionRunning + ", "
-                    + "isUnlockingWithFpAllowed=" + isUnlockingWithFpAllowed);
-        }
-        if (toShow) {
-            mSideFpsController.get().show(SideFpsUiRequestSource.PRIMARY_BOUNCER,
-                    BiometricOverlayConstants.REASON_AUTH_KEYGUARD);
+        if (isVisible) {
+            mSideFpsController.get().show(
+                    SideFpsUiRequestSource.PRIMARY_BOUNCER,
+                    BiometricOverlayConstants.REASON_AUTH_KEYGUARD
+            );
         } else {
             mSideFpsController.get().hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
         }
@@ -393,12 +472,22 @@
      * @param turningOff true if the device is being turned off
      */
     public void showPrimarySecurityScreen(boolean turningOff) {
+        if (DEBUG) Log.d(TAG, "show()");
         SecurityMode securityMode = whitelistIpcs(() -> mSecurityModel.getSecurityMode(
                 KeyguardUpdateMonitor.getCurrentUser()));
         if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
         showSecurityScreen(securityMode);
     }
 
+    /**
+     * Show a string explaining why the security view needs to be solved.
+     *
+     * @param reason a flag indicating which string should be shown, see
+     *               {@link KeyguardSecurityView#PROMPT_REASON_NONE},
+     *               {@link KeyguardSecurityView#PROMPT_REASON_RESTART},
+     *               {@link KeyguardSecurityView#PROMPT_REASON_TIMEOUT}, and
+     *               {@link KeyguardSecurityView#PROMPT_REASON_PREPARE_FOR_UPDATE}.
+     */
     @Override
     public void showPromptReason(int reason) {
         if (mCurrentSecurityMode != SecurityMode.None) {
@@ -415,8 +504,32 @@
         }
     }
 
-    public SecurityMode getCurrentSecurityMode() {
-        return mCurrentSecurityMode;
+    /**
+     * Sets an action to run when keyguard finishes.
+     *
+     * @param action callback to be invoked when keyguard disappear animation completes.
+     */
+    public void setOnDismissAction(ActivityStarter.OnDismissAction action, Runnable cancelAction) {
+        if (mCancelAction != null) {
+            mCancelAction.run();
+            mCancelAction = null;
+        }
+        mDismissAction = action;
+        mCancelAction = cancelAction;
+    }
+
+    /**
+     * @return whether dismiss action or cancel action has been set.
+     */
+    public boolean hasDismissActions() {
+        return mDismissAction != null || mCancelAction != null;
+    }
+
+    /**
+     * Remove any dismiss action or cancel action that was set.
+     */
+    public void cancelDismissAction() {
+        setOnDismissAction(null, null);
     }
 
     /**
@@ -428,17 +541,64 @@
         mKeyguardSecurityCallback.dismiss(authenticated, targetUserId, expectedSecurityMode);
     }
 
+    /**
+     * Dismisses the keyguard by going to the next screen or making it gone.
+     * @param targetUserId a user that needs to be the foreground user at the dismissal completion.
+     * @return True if the keyguard is done.
+     */
+    public boolean dismiss(int targetUserId) {
+        return mKeyguardSecurityCallback.dismiss(false, targetUserId, false,
+                getCurrentSecurityMode());
+    }
+
+    public SecurityMode getCurrentSecurityMode() {
+        return mCurrentSecurityMode;
+    }
+
+    /**
+     * @return the top of the corresponding view.
+     */
+    public int getTop() {
+        int top = mView.getTop();
+        // The password view has an extra top padding that should be ignored.
+        if (getCurrentSecurityMode() == SecurityMode.Password) {
+            View messageArea = mView.findViewById(R.id.keyguard_message_area);
+            top += messageArea.getTop();
+        }
+        return top;
+    }
+
+    /** Set true if the view can be interacted with */
+    public void setInteractable(boolean isInteractable) {
+        mView.setInteractable(isInteractable);
+    }
+
+    /**
+     * Dismiss keyguard due to a user unlock event.
+     */
+    public void finish(boolean strongAuth, int currentUser) {
+        mKeyguardSecurityCallback.finish(strongAuth, currentUser);
+    }
+
+    /**
+     * @return the text of the KeyguardMessageArea.
+     */
+    public CharSequence getTitle() {
+        return mView.getTitle();
+    }
+
+    /**
+     *  Resets the state of the views.
+     */
     public void reset() {
         mView.reset();
         mSecurityViewFlipperController.reset();
     }
 
-    public CharSequence getTitle() {
-        return mView.getTitle();
-    }
-
     @Override
     public void onResume(int reason) {
+        if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
+        mView.requestFocus();
         if (mCurrentSecurityMode != SecurityMode.None) {
             int state = SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN;
             if (mView.isSidedSecurityMode()) {
@@ -449,13 +609,31 @@
             SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED, state);
 
             getCurrentSecurityController().onResume(reason);
-            updateSideFpsVisibility();
         }
         mView.onResume(
                 mSecurityModel.getSecurityMode(KeyguardUpdateMonitor.getCurrentUser()),
                 mKeyguardStateController.isFaceAuthEnabled());
     }
 
+    /**
+     * Show the bouncer and start appear animations.
+     *
+     */
+    public void appear() {
+        // We might still be collapsed and the view didn't have time to layout yet or still
+        // be small, let's wait on the predraw to do the animation in that case.
+        mView.getViewTreeObserver().addOnPreDrawListener(
+                new ViewTreeObserver.OnPreDrawListener() {
+                    @Override
+                    public boolean onPreDraw() {
+                        mView.getViewTreeObserver().removeOnPreDrawListener(this);
+                        startAppearAnimation();
+                        return true;
+                    }
+                });
+        mView.requestLayout();
+    }
+
     public void startAppearAnimation() {
         if (mCurrentSecurityMode != SecurityMode.None) {
             mView.setAlpha(1f);
@@ -465,34 +643,34 @@
     }
 
     public boolean startDisappearAnimation(Runnable onFinishRunnable) {
+        boolean didRunAnimation = false;
+
         if (mCurrentSecurityMode != SecurityMode.None) {
             mView.startDisappearAnimation(mCurrentSecurityMode);
-            return getCurrentSecurityController().startDisappearAnimation(onFinishRunnable);
+            didRunAnimation = getCurrentSecurityController().startDisappearAnimation(
+                    onFinishRunnable);
         }
 
-        return false;
+        if (!didRunAnimation && onFinishRunnable != null) {
+            onFinishRunnable.run();
+        }
+
+        return didRunAnimation;
     }
 
     public void onStartingToHide() {
         if (mCurrentSecurityMode != SecurityMode.None) {
             getCurrentSecurityController().onStartingToHide();
         }
-        setBouncerVisible(false);
     }
 
     /** Called when the bouncer changes visibility. */
-    public void onBouncerVisibilityChanged(@View.Visibility int visibility) {
-        setBouncerVisible(visibility == View.VISIBLE);
-        if (visibility == View.INVISIBLE) {
+    public void onBouncerVisibilityChanged(boolean isVisible) {
+        if (!isVisible) {
             mView.resetScale();
         }
     }
 
-    private void setBouncerVisible(boolean visible) {
-        mBouncerVisible = visible;
-        updateSideFpsVisibility();
-    }
-
     /**
      * Shows the next security screen if there is one.
      * @param authenticated true if the user entered the correct authentication
@@ -585,7 +763,7 @@
             mUiEventLogger.log(uiEvent, getSessionId());
         }
         if (finish) {
-            mSecurityCallback.finish(strongAuth, targetUserId);
+            mKeyguardSecurityCallback.finish(strongAuth, targetUserId);
         }
         return finish;
     }
@@ -598,11 +776,114 @@
      * @return the {@link OnBackAnimationCallback} to animate this view during a back gesture.
      */
     @NonNull
-    OnBackAnimationCallback getBackCallback() {
+    public OnBackAnimationCallback getBackCallback() {
         return mView.getBackCallback();
     }
 
     /**
+     * @return whether we should dispatch the back key event before Ime.
+     */
+    public boolean dispatchBackKeyEventPreIme() {
+        return getCurrentSecurityMode() == SecurityMode.Password;
+    }
+
+    /**
+     * Allows the media keys to work when the keyguard is showing.
+     * The media keys should be of no interest to the actual keyguard view(s),
+     * so intercepting them here should not be of any harm.
+     * @param event The key event
+     * @return whether the event was consumed as a media key.
+     */
+    public boolean interceptMediaKey(KeyEvent event) {
+        int keyCode = event.getKeyCode();
+        if (event.getAction() == KeyEvent.ACTION_DOWN) {
+            switch (keyCode) {
+                case KeyEvent.KEYCODE_MEDIA_PLAY:
+                case KeyEvent.KEYCODE_MEDIA_PAUSE:
+                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+                    /* Suppress PLAY/PAUSE toggle when phone is ringing or
+                     * in-call to avoid music playback */
+                    if (mTelephonyManager != null
+                            && mTelephonyManager.getCallState()
+                            != TelephonyManager.CALL_STATE_IDLE) {
+                        return true;  // suppress key event
+                    }
+                    return false;
+                case KeyEvent.KEYCODE_MUTE:
+                case KeyEvent.KEYCODE_HEADSETHOOK:
+                case KeyEvent.KEYCODE_MEDIA_STOP:
+                case KeyEvent.KEYCODE_MEDIA_NEXT:
+                case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+                case KeyEvent.KEYCODE_MEDIA_REWIND:
+                case KeyEvent.KEYCODE_MEDIA_RECORD:
+                case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+                case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
+                    handleMediaKeyEvent(event);
+                    return true;
+                }
+
+                case KeyEvent.KEYCODE_VOLUME_UP:
+                case KeyEvent.KEYCODE_VOLUME_DOWN:
+                case KeyEvent.KEYCODE_VOLUME_MUTE: {
+                    if (KEYGUARD_MANAGES_VOLUME) {
+                        // Volume buttons should only function for music (local or remote).
+                        // TODO: Actually handle MUTE.
+                        mAudioManager.adjustSuggestedStreamVolume(
+                                keyCode == KeyEvent.KEYCODE_VOLUME_UP
+                                        ? AudioManager.ADJUST_RAISE
+                                        : AudioManager.ADJUST_LOWER /* direction */,
+                                AudioManager.STREAM_MUSIC /* stream */, 0 /* flags */);
+                        // Don't execute default volume behavior
+                        return true;
+                    } else {
+                        return false;
+                    }
+                }
+            }
+        } else if (event.getAction() == KeyEvent.ACTION_UP) {
+            switch (keyCode) {
+                case KeyEvent.KEYCODE_MUTE:
+                case KeyEvent.KEYCODE_HEADSETHOOK:
+                case KeyEvent.KEYCODE_MEDIA_PLAY:
+                case KeyEvent.KEYCODE_MEDIA_PAUSE:
+                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+                case KeyEvent.KEYCODE_MEDIA_STOP:
+                case KeyEvent.KEYCODE_MEDIA_NEXT:
+                case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+                case KeyEvent.KEYCODE_MEDIA_REWIND:
+                case KeyEvent.KEYCODE_MEDIA_RECORD:
+                case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+                case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
+                    handleMediaKeyEvent(event);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+
+    private void handleMediaKeyEvent(KeyEvent keyEvent) {
+        mAudioManager.dispatchMediaKeyEvent(keyEvent);
+    }
+
+    /**
+     * In general, we enable unlocking the insecure keyguard with the menu key. However, there are
+     * some cases where we wish to disable it, notably when the menu button placement or technology
+     * is prone to false positives.
+     *
+     * @return true if the menu key should be enabled
+     */
+    public boolean shouldEnableMenuKey() {
+        final Resources res = mView.getResources();
+        final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen);
+        final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
+        final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
+        return !configDisabled || isTestHarness || fileOverride;
+    }
+
+
+    /**
      * Switches to the given security view unless it's already being shown, in which case
      * this is a no-op.
      *
@@ -630,7 +911,7 @@
             configureMode();
         }
 
-        mSecurityCallback.onSecurityModeChanged(
+        mKeyguardSecurityCallback.onSecurityModeChanged(
                 securityMode, newView != null && newView.needsInput());
     }
 
@@ -728,6 +1009,30 @@
      * configuration.
      */
     public void updateResources() {
+        int gravity;
+
+        Resources resources = mView.getResources();
+
+        if (resources.getBoolean(R.bool.can_use_one_handed_bouncer)) {
+            gravity = resources.getInteger(
+                    R.integer.keyguard_host_view_one_handed_gravity);
+        } else {
+            gravity = resources.getInteger(R.integer.keyguard_host_view_gravity);
+        }
+
+        mTranslationY = resources
+                .getDimensionPixelSize(R.dimen.keyguard_host_view_translation_y);
+        // Android SysUI uses a FrameLayout as the top-level, but Auto uses RelativeLayout.
+        // We're just changing the gravity here though (which can't be applied to RelativeLayout),
+        // so only attempt the update if mView is inside a FrameLayout.
+        if (mView.getLayoutParams() instanceof FrameLayout.LayoutParams) {
+            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mView.getLayoutParams();
+            if (lp.gravity != gravity) {
+                lp.gravity = gravity;
+                mView.setLayoutParams(lp);
+            }
+        }
+
         int newOrientation = getResources().getConfiguration().orientation;
         if (newOrientation != mLastOrientation) {
             mLastOrientation = newOrientation;
@@ -764,77 +1069,15 @@
                 mKeyguardSecurityCallback);
     }
 
-    static class Factory {
-
-        private final KeyguardSecurityContainer mView;
-        private final AdminSecondaryLockScreenController.Factory
-                mAdminSecondaryLockScreenControllerFactory;
-        private final LockPatternUtils mLockPatternUtils;
-        private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-        private final KeyguardSecurityModel mKeyguardSecurityModel;
-        private final MetricsLogger mMetricsLogger;
-        private final UiEventLogger mUiEventLogger;
-        private final KeyguardStateController mKeyguardStateController;
-        private final KeyguardSecurityViewFlipperController mSecurityViewFlipperController;
-        private final ConfigurationController mConfigurationController;
-        private final FalsingCollector mFalsingCollector;
-        private final FalsingManager mFalsingManager;
-        private final GlobalSettings mGlobalSettings;
-        private final FeatureFlags mFeatureFlags;
-        private final UserSwitcherController mUserSwitcherController;
-        private final SessionTracker mSessionTracker;
-        private final Optional<SideFpsController> mSidefpsController;
-        private final FalsingA11yDelegate mFalsingA11yDelegate;
-
-        @Inject
-        Factory(KeyguardSecurityContainer view,
-                AdminSecondaryLockScreenController.Factory
-                        adminSecondaryLockScreenControllerFactory,
-                LockPatternUtils lockPatternUtils,
-                KeyguardUpdateMonitor keyguardUpdateMonitor,
-                KeyguardSecurityModel keyguardSecurityModel,
-                MetricsLogger metricsLogger,
-                UiEventLogger uiEventLogger,
-                KeyguardStateController keyguardStateController,
-                KeyguardSecurityViewFlipperController securityViewFlipperController,
-                ConfigurationController configurationController,
-                FalsingCollector falsingCollector,
-                FalsingManager falsingManager,
-                UserSwitcherController userSwitcherController,
-                FeatureFlags featureFlags,
-                GlobalSettings globalSettings,
-                SessionTracker sessionTracker,
-                Optional<SideFpsController> sidefpsController,
-                FalsingA11yDelegate falsingA11yDelegate) {
-            mView = view;
-            mAdminSecondaryLockScreenControllerFactory = adminSecondaryLockScreenControllerFactory;
-            mLockPatternUtils = lockPatternUtils;
-            mKeyguardUpdateMonitor = keyguardUpdateMonitor;
-            mKeyguardSecurityModel = keyguardSecurityModel;
-            mMetricsLogger = metricsLogger;
-            mUiEventLogger = uiEventLogger;
-            mKeyguardStateController = keyguardStateController;
-            mSecurityViewFlipperController = securityViewFlipperController;
-            mConfigurationController = configurationController;
-            mFalsingCollector = falsingCollector;
-            mFalsingManager = falsingManager;
-            mFeatureFlags = featureFlags;
-            mGlobalSettings = globalSettings;
-            mUserSwitcherController = userSwitcherController;
-            mSessionTracker = sessionTracker;
-            mSidefpsController = sidefpsController;
-            mFalsingA11yDelegate = falsingA11yDelegate;
-        }
-
-        public KeyguardSecurityContainerController create(
-                SecurityCallback securityCallback) {
-            return new KeyguardSecurityContainerController(mView,
-                    mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils,
-                    mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger,
-                    mKeyguardStateController, securityCallback, mSecurityViewFlipperController,
-                    mConfigurationController, mFalsingCollector, mFalsingManager,
-                    mUserSwitcherController, mFeatureFlags, mGlobalSettings, mSessionTracker,
-                    mSidefpsController, mFalsingA11yDelegate);
-        }
+    /**
+     * Fades and translates in/out the security screen.
+     * Fades in as expansion approaches 0.
+     * Animation duration is between 0.33f and 0.67f of panel expansion fraction.
+     * @param fraction amount of the screen that should show.
+     */
+    public void setExpansion(float fraction) {
+        float scaledFraction = BouncerPanelExpansionCalculator.showBouncerProgress(fraction);
+        mView.setAlpha(MathUtils.constrain(1 - scaledFraction, 0f, 1f));
+        mView.setTranslationY(scaledFraction * mTranslationY);
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index b53b868..f4c5815 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -21,8 +21,6 @@
 
 import com.android.keyguard.KeyguardClockSwitch.ClockSize;
 import com.android.keyguard.logging.KeyguardLogger;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.ClockAnimations;
 import com.android.systemui.statusbar.notification.AnimatableProperty;
 import com.android.systemui.statusbar.notification.PropertyAnimator;
@@ -62,7 +60,6 @@
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             ConfigurationController configurationController,
             DozeParameters dozeParameters,
-            FeatureFlags featureFlags,
             ScreenOffAnimationController screenOffAnimationController,
             KeyguardLogger logger) {
         super(keyguardStatusView);
@@ -73,8 +70,6 @@
         mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
                 dozeParameters, screenOffAnimationController, /* animateYPos= */ true,
                 logger.getBuffer());
-        mKeyguardVisibilityHelper.setOcclusionTransitionFlagEnabled(
-                featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION));
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 7499cf6..84dd368 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -145,7 +145,7 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.dump.DumpsysTableLogger;
 import com.android.systemui.log.SessionTracker;
-import com.android.systemui.plugins.Weather;
+import com.android.systemui.plugins.WeatherData;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.system.TaskStackChangeListener;
@@ -1925,11 +1925,23 @@
             FACE_AUTH_UPDATED_STARTED_WAKING_UP.setExtraInfo(pmWakeReason);
             updateFaceListeningState(BIOMETRIC_ACTION_UPDATE,
                     FACE_AUTH_UPDATED_STARTED_WAKING_UP);
-            requestActiveUnlock(
+
+            final ActiveUnlockConfig.ActiveUnlockRequestOrigin requestOrigin =
                     mActiveUnlockConfig.isWakeupConsideredUnlockIntent(pmWakeReason)
                             ? ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
-                            : ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE,
-                    "wakingUp - " + PowerManager.wakeReasonToString(pmWakeReason));
+                            : ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE;
+            final String reason = "wakingUp - " + PowerManager.wakeReasonToString(pmWakeReason);
+            if (mActiveUnlockConfig.shouldWakeupForceDismissKeyguard(pmWakeReason)) {
+                requestActiveUnlockDismissKeyguard(
+                        requestOrigin,
+                        reason
+                );
+            } else {
+                requestActiveUnlock(
+                        requestOrigin,
+                        reason
+                );
+            }
         } else {
             mLogger.logSkipUpdateFaceListeningOnWakeup(pmWakeReason);
         }
@@ -2584,6 +2596,7 @@
         }
     }
 
+
     /**
      * Attempts to trigger active unlock from trust agent.
      * Only dismisses the keyguard under certain conditions.
@@ -2746,7 +2759,8 @@
 
         boolean shouldListen = shouldListenKeyguardState && shouldListenUserState
                 && shouldListenBouncerState && shouldListenUdfpsState
-                && shouldListenSideFpsState;
+                && shouldListenSideFpsState
+                && !isFingerprintLockedOut();
         logListenerModelData(
                 new KeyguardFingerprintListenModel(
                     System.currentTimeMillis(),
@@ -2805,7 +2819,8 @@
         final boolean supportsDetect = !mFaceSensorProperties.isEmpty()
                 && mFaceSensorProperties.get(0).supportsFaceDetection
                 && canBypass && !mPrimaryBouncerIsOrWillBeShowing
-                && !isUserInLockdown(user);
+                && !isUserInLockdown(user)
+                && !isFingerprintLockedOut();
         final boolean faceAuthAllowedOrDetectionIsNeeded = faceAuthAllowed || supportsDetect;
 
         // If the face or fp has recently been authenticated do not attempt to authenticate again.
@@ -3262,12 +3277,12 @@
     /**
      * @param data the weather data (temp, conditions, unit) for weather clock to use
      */
-    public void sendWeatherData(Weather data) {
+    public void sendWeatherData(WeatherData data) {
         mHandler.post(()-> {
             handleWeatherDataUpdate(data); });
     }
 
-    private void handleWeatherDataUpdate(Weather data) {
+    private void handleWeatherDataUpdate(WeatherData data) {
         Assert.isMainThread();
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -3775,7 +3790,7 @@
     }
 
     // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
-    // (KeyguardViewMediator, KeyguardHostView)
+    // (KeyguardViewMediator, KeyguardSecurityContainer)
     /**
      * Dispatch wakeup events to:
      *  - update biometric listening states
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 0da799e..38f3e50 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -23,7 +23,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.settingslib.fuelgauge.BatteryStatus;
-import com.android.systemui.plugins.Weather;
+import com.android.systemui.plugins.WeatherData;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 
 import java.util.TimeZone;
@@ -61,7 +61,7 @@
     /**
      * Called when receive new weather data.
      */
-    public void onWeatherDataChanged(Weather data) { }
+    public void onWeatherDataChanged(WeatherData data) { }
 
     /**
      * Called when the carrier PLMN or SPN changes.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
index 7e48193..a678edc 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java
@@ -28,7 +28,6 @@
 import com.android.systemui.statusbar.notification.AnimatableProperty;
 import com.android.systemui.statusbar.notification.PropertyAnimator;
 import com.android.systemui.statusbar.notification.stack.AnimationProperties;
-import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -49,7 +48,6 @@
     private boolean mAnimateYPos;
     private boolean mKeyguardViewVisibilityAnimating;
     private boolean mLastOccludedState = false;
-    private boolean mIsUnoccludeTransitionFlagEnabled = false;
     private final AnimationProperties mAnimationProperties = new AnimationProperties();
     private final LogBuffer mLogBuffer;
 
@@ -77,10 +75,6 @@
         return mKeyguardViewVisibilityAnimating;
     }
 
-    public void setOcclusionTransitionFlagEnabled(boolean enabled) {
-        mIsUnoccludeTransitionFlagEnabled = enabled;
-    }
-
     /**
      * Set the visibility of a keyguard view based on some new state.
      */
@@ -156,24 +150,9 @@
                 // since it may need to be cancelled due to keyguard lifecycle events.
                 mScreenOffAnimationController.animateInKeyguard(
                         mView, mAnimateKeyguardStatusViewVisibleEndRunnable);
-            } else if (!mIsUnoccludeTransitionFlagEnabled && mLastOccludedState && !isOccluded) {
-                // An activity was displayed over the lock screen, and has now gone away
-                log("Unoccluded transition");
-                mView.setVisibility(View.VISIBLE);
-                mView.setAlpha(0f);
-
-                mView.animate()
-                        .setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP)
-                        .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                        .alpha(1f)
-                        .withEndAction(mAnimateKeyguardStatusViewVisibleEndRunnable)
-                        .start();
             } else {
                 log("Direct set Visibility to VISIBLE");
                 mView.setVisibility(View.VISIBLE);
-                if (!mIsUnoccludeTransitionFlagEnabled) {
-                    mView.setAlpha(1f);
-                }
             }
         } else {
             log("Direct set Visibility to GONE");
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index 0a4880e..3b0644e 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -33,7 +33,6 @@
 
 import androidx.annotation.Nullable;
 
-import com.android.internal.widget.LockPatternUtils;
 import com.android.settingslib.Utils;
 import com.android.systemui.R;
 
@@ -46,7 +45,6 @@
 
     private final TextView mDigitText;
     private final TextView mKlondikeText;
-    private final LockPatternUtils mLockPatternUtils;
     private final PowerManager mPM;
 
     private int mDigit = -1;
@@ -107,7 +105,6 @@
         setOnHoverListener(new LiftToActivateListener(
                 (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE)));
 
-        mLockPatternUtils = new LockPatternUtils(context);
         mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerComponent.java
index 5ad21df..154b0ed 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerComponent.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerComponent.java
@@ -18,7 +18,7 @@
 
 import android.view.ViewGroup;
 
-import com.android.keyguard.KeyguardHostViewController;
+import com.android.keyguard.KeyguardSecurityContainerController;
 import com.android.systemui.dagger.qualifiers.RootView;
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
 
@@ -37,6 +37,6 @@
         KeyguardBouncerComponent create(@BindsInstance @RootView ViewGroup bouncerContainer);
     }
 
-    /** Returns a {@link KeyguardHostViewController}. */
-    KeyguardHostViewController getKeyguardHostViewController();
+    /** Returns a {@link KeyguardSecurityContainerController}. */
+    KeyguardSecurityContainerController getSecurityContainerController();
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
index cb7a0a9..38f252a 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerModule.java
@@ -23,7 +23,6 @@
 import android.view.LayoutInflater;
 import android.view.ViewGroup;
 
-import com.android.keyguard.KeyguardHostView;
 import com.android.keyguard.KeyguardSecurityContainer;
 import com.android.keyguard.KeyguardSecurityViewFlipper;
 import com.android.systemui.R;
@@ -47,19 +46,13 @@
     /** */
     @Provides
     @KeyguardBouncerScope
-    static KeyguardHostView providesKeyguardHostView(@RootView ViewGroup rootView,
+    static KeyguardSecurityContainer providesKeyguardSecurityContainer(@RootView ViewGroup rootView,
             LayoutInflater layoutInflater) {
-        KeyguardHostView hostView = (KeyguardHostView) layoutInflater.inflate(
-                R.layout.keyguard_host_view, rootView, false);
-        rootView.addView(hostView);
-        return hostView;
-    }
-
-    /** */
-    @Provides
-    @KeyguardBouncerScope
-    static KeyguardSecurityContainer providesKeyguardSecurityContainer(KeyguardHostView hostView) {
-        return hostView.findViewById(R.id.keyguard_security_container);
+        KeyguardSecurityContainer securityContainer =
+                (KeyguardSecurityContainer) layoutInflater.inflate(
+                        R.layout.keyguard_security_container_view, rootView, false);
+        rootView.addView(securityContainer);
+        return securityContainer;
     }
 
     /** */
diff --git a/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt b/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt
index 0f00a04..603471b 100644
--- a/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt
+++ b/packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt
@@ -73,6 +73,10 @@
     @BinderThread
     fun onScreenTurnedOn() {
         foldAodAnimationController?.onScreenTurnedOn()
+    }
+
+    @BinderThread
+    fun onScreenTurnedOff() {
         pendingTasks.reset()
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
index 03d999f..ce42534 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
@@ -24,6 +24,7 @@
 import android.animation.LayoutTransition;
 import android.animation.ObjectAnimator;
 import android.annotation.IntDef;
+import android.annotation.IntRange;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -195,7 +196,13 @@
         return false;
     }
 
-    void onBatteryLevelChanged(int level, boolean pluggedIn) {
+    /**
+     * Update battery level
+     *
+     * @param level     int between 0 and 100 (representing percentage value)
+     * @param pluggedIn whether the device is plugged in or not
+     */
+    public void onBatteryLevelChanged(@IntRange(from = 0, to = 100) int level, boolean pluggedIn) {
         mDrawable.setCharging(pluggedIn);
         mDrawable.setBatteryLevel(level);
         mCharging = pluggedIn;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
index 3ea3cd1..709ddf5 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
@@ -231,21 +231,29 @@
             if (isReverseDefaultRotation) (rotation + 1) % 4 else rotation
 
     @RawRes
-    private fun getSideFpsAnimationForTransition(rotation: Int): Int = when (rotation) {
-        Surface.ROTATION_90 -> if (isDeviceFolded) {
-            R.raw.biometricprompt_folded_base_topleft
-        } else {
-            R.raw.biometricprompt_portrait_base_topleft
-        }
-        Surface.ROTATION_270 -> if (isDeviceFolded) {
-            R.raw.biometricprompt_folded_base_bottomright
-        } else {
-            R.raw.biometricprompt_portrait_base_bottomright
-        }
-        else -> if (isDeviceFolded) {
-            R.raw.biometricprompt_folded_base_default
-        } else {
-            R.raw.biometricprompt_landscape_base
+    private fun getSideFpsAnimationForTransition(rotation: Int): Int {
+        when (rotation) {
+            Surface.ROTATION_90 -> if (context.isInRearDisplayMode()) {
+                return R.raw.biometricprompt_rear_portrait_reverse_base
+            } else if (isDeviceFolded) {
+                return R.raw.biometricprompt_folded_base_topleft
+            } else {
+                return R.raw.biometricprompt_portrait_base_topleft
+            }
+            Surface.ROTATION_270 -> if (context.isInRearDisplayMode()) {
+                return R.raw.biometricprompt_rear_portrait_base
+            } else if (isDeviceFolded) {
+                return R.raw.biometricprompt_folded_base_bottomright
+            } else {
+                return R.raw.biometricprompt_portrait_base_bottomright
+            }
+            else -> if (context.isInRearDisplayMode()) {
+                return R.raw.biometricprompt_rear_landscape_base
+            } else if (isDeviceFolded) {
+                return R.raw.biometricprompt_folded_base_default
+            } else {
+                return R.raw.biometricprompt_landscape_base
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index e12c170..a7b6e6a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -658,6 +658,7 @@
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
         mIconController.onConfigurationChanged(newConfig);
+        updateState(mSavedState.getInt(AuthDialog.KEY_BIOMETRIC_STATE));
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index febf75e..68e1f72 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -847,7 +847,7 @@
         final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT,
                 ViewGroup.LayoutParams.MATCH_PARENT,
-                WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,
+                WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL,
                 windowFlags,
                 PixelFormat.TRANSLUCENT);
         lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 2dc0cd3..3302073 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -129,7 +129,6 @@
     private float mScaleFactor = 1f;
     // sensor locations without any resolution scaling nor rotation adjustments:
     @Nullable private final Point mFaceSensorLocationDefault;
-    @Nullable private final Point mFingerprintSensorLocationDefault;
     // cached sensor locations:
     @Nullable private Point mFaceSensorLocation;
     @Nullable private Point mFingerprintSensorLocation;
@@ -586,11 +585,23 @@
     @Nullable private Point getFingerprintSensorLocationInNaturalOrientation() {
         if (getUdfpsLocation() != null) {
             return getUdfpsLocation();
+        } else {
+            int xFpLocation = mCachedDisplayInfo.getNaturalWidth() / 2;
+            try {
+                xFpLocation = mContext.getResources().getDimensionPixelSize(
+                        com.android.systemui.R.dimen
+                                .physical_fingerprint_sensor_center_screen_location_x);
+            } catch (Resources.NotFoundException e) {
+            }
+
+            return new Point(
+                    (int) (xFpLocation * mScaleFactor),
+                    (int) (mContext.getResources().getDimensionPixelSize(
+                            com.android.systemui.R.dimen
+                                    .physical_fingerprint_sensor_center_screen_location_y)
+                            * mScaleFactor)
+            );
         }
-        return new Point(
-                (int) (mFingerprintSensorLocationDefault.x * mScaleFactor),
-                (int) (mFingerprintSensorLocationDefault.y * mScaleFactor)
-        );
     }
 
     /**
@@ -774,19 +785,6 @@
         }
 
         mDisplay = mContext.getDisplay();
-        mDisplay.getDisplayInfo(mCachedDisplayInfo);
-        int xFpLocation = mCachedDisplayInfo.getNaturalWidth() / 2;
-        try {
-            xFpLocation = mContext.getResources().getDimensionPixelSize(
-                    com.android.systemui.R.dimen
-                            .physical_fingerprint_sensor_center_screen_location_x);
-        } catch (Resources.NotFoundException e) {
-        }
-        mFingerprintSensorLocationDefault = new Point(
-                xFpLocation,
-                mContext.getResources().getDimensionPixelSize(com.android.systemui.R.dimen
-                        .physical_fingerprint_sensor_center_screen_location_y)
-        );
         updateSensorLocations();
 
         IntentFilter filter = new IntentFilter();
@@ -1246,7 +1244,6 @@
         pw.println("  mScaleFactor=" + mScaleFactor);
         pw.println("  faceAuthSensorLocationDefault=" + mFaceSensorLocationDefault);
         pw.println("  faceAuthSensorLocation=" + getFaceSensorLocation());
-        pw.println("  fingerprintSensorLocationDefault=" + mFingerprintSensorLocationDefault);
         pw.println("  fingerprintSensorLocationInNaturalOrientation="
                 + getFingerprintSensorLocationInNaturalOrientation());
         pw.println("  fingerprintSensorLocation=" + getFingerprintSensorLocation());
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
index 58b230f..4b32759 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
@@ -75,7 +75,7 @@
         }
     private var radius: Float = 0f
         set(value) {
-            rippleShader.setMaxSize(value * 2f, value * 2f)
+            rippleShader.rippleSize.setMaxSize(value * 2f, value * 2f)
             field = value
         }
     private var origin: Point = Point()
@@ -364,7 +364,7 @@
 
         if (drawRipple) {
             canvas?.drawCircle(origin.x.toFloat(), origin.y.toFloat(),
-                    rippleShader.currentWidth, ripplePaint)
+                    rippleShader.rippleSize.currentWidth, ripplePaint)
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
index 6c49078..ac6a22c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
@@ -172,12 +172,16 @@
                 override fun show(
                     sensorId: Int,
                     @BiometricOverlayConstants.ShowReason reason: Int
-                ) =
-                    if (reason.isReasonToAutoShow(activityTaskManager)) {
+                ) {
+                    if (
+                        reason.isReasonToAutoShow(activityTaskManager) &&
+                            !context.isInRearDisplayMode()
+                    ) {
                         show(SideFpsUiRequestSource.AUTO_SHOW, reason)
                     } else {
                         hide(SideFpsUiRequestSource.AUTO_SHOW)
                     }
+                }
 
                 override fun hide(sensorId: Int) = hide(SideFpsUiRequestSource.AUTO_SHOW)
             }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
index d0d6f4c..3d56326 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
@@ -36,6 +36,7 @@
 import android.view.accessibility.AccessibilityEvent
 import android.view.accessibility.AccessibilityManager
 import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.R
 import java.lang.annotation.Retention
 import java.lang.annotation.RetentionPolicy
 
@@ -117,4 +118,7 @@
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(CREDENTIAL_PIN, CREDENTIAL_PATTERN, CREDENTIAL_PASSWORD)
     internal annotation class CredentialType
-}
\ No newline at end of file
+}
+
+fun Context.isInRearDisplayMode(): Boolean = resources.getIntArray(
+        com.android.internal.R.array.config_rearDisplayDeviceStates).isNotEmpty()
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java
index 8e062bd..653c12e 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java
@@ -46,11 +46,11 @@
     @VisibleForTesting
     protected View mDialogView;
     private MediaOutputDialogFactory mMediaOutputDialogFactory;
-    private String mSwitchBroadcastApp;
+    private String mCurrentBroadcastApp;
     private String mOutputPackageName;
 
     public BroadcastDialog(Context context, MediaOutputDialogFactory mediaOutputDialogFactory,
-            String switchBroadcastApp, String outputPkgName, UiEventLogger uiEventLogger) {
+            String currentBroadcastApp, String outputPkgName, UiEventLogger uiEventLogger) {
         super(context);
         if (DEBUG) {
             Log.d(TAG, "Init BroadcastDialog");
@@ -58,7 +58,7 @@
 
         mContext = getContext();
         mMediaOutputDialogFactory = mediaOutputDialogFactory;
-        mSwitchBroadcastApp = switchBroadcastApp;
+        mCurrentBroadcastApp = currentBroadcastApp;
         mOutputPackageName = outputPkgName;
         mUiEventLogger = uiEventLogger;
     }
@@ -77,20 +77,18 @@
 
         TextView title = mDialogView.requireViewById(R.id.dialog_title);
         TextView subTitle = mDialogView.requireViewById(R.id.dialog_subtitle);
-        title.setText(
-                mContext.getString(R.string.bt_le_audio_broadcast_dialog_title,
-                        MediaDataUtils.getAppLabel(mContext, mOutputPackageName,
-                                mContext.getString(
-                                        R.string.bt_le_audio_broadcast_dialog_unknown_name))));
-        subTitle.setText(
-                mContext.getString(R.string.bt_le_audio_broadcast_dialog_sub_title,
-                        mSwitchBroadcastApp));
+        title.setText(mContext.getString(
+                R.string.bt_le_audio_broadcast_dialog_title, mCurrentBroadcastApp));
+        String switchBroadcastApp = MediaDataUtils.getAppLabel(mContext, mOutputPackageName,
+                mContext.getString(R.string.bt_le_audio_broadcast_dialog_unknown_name));
+        subTitle.setText(mContext.getString(
+                R.string.bt_le_audio_broadcast_dialog_sub_title, switchBroadcastApp));
 
         Button switchBroadcast = mDialogView.requireViewById(R.id.switch_broadcast);
         Button changeOutput = mDialogView.requireViewById(R.id.change_output);
         Button cancelBtn = mDialogView.requireViewById(R.id.cancel);
         switchBroadcast.setText(mContext.getString(
-                R.string.bt_le_audio_broadcast_dialog_switch_app, mSwitchBroadcastApp), null);
+                R.string.bt_le_audio_broadcast_dialog_switch_app, switchBroadcastApp));
         changeOutput.setOnClickListener((view) -> {
             mMediaOutputDialogFactory.create(mOutputPackageName, true, null);
             dismiss();
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialogController.java b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialogController.java
index 8a54345..1b699e8 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialogController.java
@@ -47,10 +47,15 @@
         mMediaOutputDialogFactory = mediaOutputDialogFactory;
     }
 
-    public void createBroadcastDialog(String switchAppName, String outputPkgName,
+    /** Creates a [BroadcastDialog] for the user to switch broadcast or change the output device
+     *
+     * @param currentBroadcastAppName Indicates the APP name currently broadcasting
+     * @param outputPkgName Indicates the output media package name to be switched
+     */
+    public void createBroadcastDialog(String currentBroadcastAppName, String outputPkgName,
             boolean aboveStatusBar, View view) {
         BroadcastDialog broadcastDialog = new BroadcastDialog(mContext, mMediaOutputDialogFactory,
-                switchAppName, outputPkgName, mUiEventLogger);
+                currentBroadcastAppName, outputPkgName, mUiEventLogger);
         if (view != null) {
             mDialogLaunchAnimator.showFromView(broadcastDialog, view);
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java
index 36103f8..cef415c 100644
--- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingLayout.java
@@ -33,7 +33,9 @@
 import com.android.settingslib.Utils;
 import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
+import com.android.systemui.shared.recents.utilities.Utilities;
 import com.android.systemui.surfaceeffects.ripple.RippleAnimationConfig;
+import com.android.systemui.surfaceeffects.ripple.RippleShader;
 import com.android.systemui.surfaceeffects.ripple.RippleShader.RippleShape;
 import com.android.systemui.surfaceeffects.ripple.RippleView;
 
@@ -44,10 +46,12 @@
  */
 final class WirelessChargingLayout extends FrameLayout {
     private static final long CIRCLE_RIPPLE_ANIMATION_DURATION = 1500;
-    private static final long ROUNDED_BOX_RIPPLE_ANIMATION_DURATION = 1750;
+    private static final long ROUNDED_BOX_RIPPLE_ANIMATION_DURATION = 3000;
     private static final int SCRIM_COLOR = 0x4C000000;
     private static final int SCRIM_FADE_DURATION = 300;
     private RippleView mRippleView;
+    // This is only relevant to the rounded box ripple.
+    private RippleShader.SizeAtProgress[] mSizeAtProgressArray;
 
     WirelessChargingLayout(Context context, int transmittingBatteryLevel, int batteryLevel,
             boolean isDozing, RippleShape rippleShape) {
@@ -125,20 +129,23 @@
         AnimatorSet animatorSet = new AnimatorSet();
         animatorSet.playTogether(textSizeAnimator, textOpacityAnimator, textFadeAnimator);
 
-        ValueAnimator scrimFadeInAnimator = ObjectAnimator.ofArgb(this,
-                "backgroundColor", Color.TRANSPARENT, SCRIM_COLOR);
-        scrimFadeInAnimator.setDuration(SCRIM_FADE_DURATION);
-        scrimFadeInAnimator.setInterpolator(Interpolators.LINEAR);
-        ValueAnimator scrimFadeOutAnimator = ObjectAnimator.ofArgb(this,
-                "backgroundColor", SCRIM_COLOR, Color.TRANSPARENT);
-        scrimFadeOutAnimator.setDuration(SCRIM_FADE_DURATION);
-        scrimFadeOutAnimator.setInterpolator(Interpolators.LINEAR);
-        scrimFadeOutAnimator.setStartDelay((rippleShape == RippleShape.CIRCLE
-                ? CIRCLE_RIPPLE_ANIMATION_DURATION : ROUNDED_BOX_RIPPLE_ANIMATION_DURATION)
-                - SCRIM_FADE_DURATION);
-        AnimatorSet animatorSetScrim = new AnimatorSet();
-        animatorSetScrim.playTogether(scrimFadeInAnimator, scrimFadeOutAnimator);
-        animatorSetScrim.start();
+        // For tablet docking animation, we don't play the background scrim.
+        if (!Utilities.isTablet(context)) {
+            ValueAnimator scrimFadeInAnimator = ObjectAnimator.ofArgb(this,
+                    "backgroundColor", Color.TRANSPARENT, SCRIM_COLOR);
+            scrimFadeInAnimator.setDuration(SCRIM_FADE_DURATION);
+            scrimFadeInAnimator.setInterpolator(Interpolators.LINEAR);
+            ValueAnimator scrimFadeOutAnimator = ObjectAnimator.ofArgb(this,
+                    "backgroundColor", SCRIM_COLOR, Color.TRANSPARENT);
+            scrimFadeOutAnimator.setDuration(SCRIM_FADE_DURATION);
+            scrimFadeOutAnimator.setInterpolator(Interpolators.LINEAR);
+            scrimFadeOutAnimator.setStartDelay((rippleShape == RippleShape.CIRCLE
+                    ? CIRCLE_RIPPLE_ANIMATION_DURATION : ROUNDED_BOX_RIPPLE_ANIMATION_DURATION)
+                    - SCRIM_FADE_DURATION);
+            AnimatorSet animatorSetScrim = new AnimatorSet();
+            animatorSetScrim.playTogether(scrimFadeInAnimator, scrimFadeOutAnimator);
+            animatorSetScrim.start();
+        }
 
         mRippleView = findViewById(R.id.wireless_charging_ripple);
         mRippleView.setupShader(rippleShape);
@@ -147,7 +154,26 @@
         if (mRippleView.getRippleShape() == RippleShape.ROUNDED_BOX) {
             mRippleView.setDuration(ROUNDED_BOX_RIPPLE_ANIMATION_DURATION);
             mRippleView.setSparkleStrength(0.22f);
-            mRippleView.setColor(color, 28);
+            mRippleView.setColor(color, 102); // 40% of opacity.
+            mRippleView.setBaseRingFadeParams(
+                    /* fadeInStart = */ 0f,
+                    /* fadeInEnd = */ 0f,
+                    /* fadeOutStart = */ 0.2f,
+                    /* fadeOutEnd= */ 0.47f
+            );
+            mRippleView.setSparkleRingFadeParams(
+                    /* fadeInStart = */ 0f,
+                    /* fadeInEnd = */ 0f,
+                    /* fadeOutStart = */ 0.2f,
+                    /* fadeOutEnd= */ 1f
+            );
+            mRippleView.setCenterFillFadeParams(
+                    /* fadeInStart = */ 0f,
+                    /* fadeInEnd = */ 0f,
+                    /* fadeOutStart = */ 0f,
+                    /* fadeOutEnd= */ 0.2f
+            );
+            mRippleView.setBlur(6.5f, 2.5f);
         } else {
             mRippleView.setDuration(CIRCLE_RIPPLE_ANIMATION_DURATION);
             mRippleView.setColor(color, RippleAnimationConfig.RIPPLE_DEFAULT_ALPHA);
@@ -246,9 +272,7 @@
             int height = getMeasuredHeight();
             mRippleView.setCenter(width * 0.5f, height * 0.5f);
             if (mRippleView.getRippleShape() == RippleShape.ROUNDED_BOX) {
-                // Those magic numbers are introduced for visual polish. This aspect ratio maps with
-                // the tablet's docking station.
-                mRippleView.setMaxSize(width * 1.36f, height * 1.46f);
+                updateRippleSizeAtProgressList(width, height);
             } else {
                 float maxSize = Math.max(width, height);
                 mRippleView.setMaxSize(maxSize, maxSize);
@@ -257,4 +281,36 @@
 
         super.onLayout(changed, left, top, right, bottom);
     }
+
+    private void updateRippleSizeAtProgressList(float width, float height) {
+        if (mSizeAtProgressArray == null) {
+            float maxSize = Math.max(width, height);
+            mSizeAtProgressArray = new RippleShader.SizeAtProgress[] {
+                    // Those magic numbers are introduced for visual polish. It starts from a pill
+                    // shape and expand to a full circle.
+                    new RippleShader.SizeAtProgress(0f, 0f, 0f),
+                    new RippleShader.SizeAtProgress(0.3f, width * 0.4f, height * 0.4f),
+                    new RippleShader.SizeAtProgress(1f, maxSize, maxSize)
+            };
+        } else {
+            // Same multipliers, just need to recompute with the new width and height.
+            RippleShader.SizeAtProgress first = mSizeAtProgressArray[0];
+            first.setT(0f);
+            first.setWidth(0f);
+            first.setHeight(0f);
+
+            RippleShader.SizeAtProgress second = mSizeAtProgressArray[1];
+            second.setT(0.3f);
+            second.setWidth(width * 0.4f);
+            second.setHeight(height * 0.4f);
+
+            float maxSize = Math.max(width, height);
+            RippleShader.SizeAtProgress last = mSizeAtProgressArray[2];
+            last.setT(1f);
+            last.setWidth(maxSize);
+            last.setHeight(maxSize);
+        }
+
+        mRippleView.setSizeAtProgresses(mSizeAtProgressArray);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
index e9ac840..f6b7133 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
@@ -402,7 +402,7 @@
                 || mAccessibilityManager.isTouchExplorationEnabled()
                 || mDataProvider.isA11yAction()
                 || (mFeatureFlags.isEnabled(Flags.FALSING_OFF_FOR_UNFOLDED)
-                    && !mDataProvider.isFolded());
+                    && mDataProvider.isUnfolded());
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
index 5f347c1..bc0f995 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
@@ -380,8 +380,8 @@
         return mBatteryController.isWirelessCharging() || mDockManager.isDocked();
     }
 
-    public boolean isFolded() {
-        return Boolean.TRUE.equals(mFoldStateListener.getFolded());
+    public boolean isUnfolded() {
+        return Boolean.FALSE.equals(mFoldStateListener.getFolded());
     }
 
     /** Implement to be alerted abotu the beginning and ending of falsing tracking. */
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java b/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java
index 8262539..1833202 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java
@@ -110,7 +110,7 @@
 
         mSeekbar.setOnSeekBarChangeListener(mSeekBarListener);
 
-        mIconStart.setOnClickListener((view) -> {
+        mIconStartFrame.setOnClickListener((view) -> {
             final int progress = mSeekbar.getProgress();
             if (progress > 0) {
                 mSeekbar.setProgress(progress - 1);
@@ -118,7 +118,7 @@
             }
         });
 
-        mIconEnd.setOnClickListener((view) -> {
+        mIconEndFrame.setOnClickListener((view) -> {
             final int progress = mSeekbar.getProgress();
             if (progress < mSeekbar.getMax()) {
                 mSeekbar.setProgress(progress + 1);
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
index d8d8c0e..bf0a692 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
@@ -68,7 +68,7 @@
 
         getLifecycle().addObserver(
             ControlsAnimations.observerForAnimations(
-                requireViewById<ViewGroup>(R.id.control_detail_root),
+                requireViewById(R.id.control_detail_root),
                 window,
                 intent,
                 !featureFlags.isEnabled(Flags.USE_APP_PANELS)
@@ -95,7 +95,7 @@
     override fun onStart() {
         super.onStart()
 
-        parent = requireViewById<ViewGroup>(R.id.global_actions_controls)
+        parent = requireViewById(R.id.control_detail_root)
         parent.alpha = 0f
         if (featureFlags.isEnabled(Flags.USE_APP_PANELS) && !keyguardStateController.isUnlocked) {
             controlsSettingsDialogManager.maybeShowDialog(this) {
@@ -134,7 +134,8 @@
         super.onStop()
         mExitToDream = false
 
-        uiController.hide()
+        // parent is set in onStart, so the field is initialized when we get here
+        uiController.hide(parent)
         controlsSettingsDialogManager.closeDialog()
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
index c1cec9d..58673bb 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
@@ -31,7 +31,13 @@
     }
 
     fun show(parent: ViewGroup, onDismiss: Runnable, activityContext: Context)
-    fun hide()
+
+    /**
+     * Hide the controls content if it's attached to this parent.
+     */
+    fun hide(parent: ViewGroup)
+
+    val isShowing: Boolean
 
     /**
      * Returns the preferred activity to start, depending on if the user has favorited any
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index 58f4835..860601b 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -168,6 +168,9 @@
     private lateinit var activityContext: Context
     private lateinit var listingCallback: ControlsListingController.ControlsListingCallback
 
+    override val isShowing: Boolean
+        get() = !hidden
+
     init {
         dumpManager.registerDumpable(javaClass.name, this)
     }
@@ -543,8 +546,12 @@
             RenderInfo.registerComponentIcon(it.componentName, it.icon)
         }
 
-        var adapter = ItemAdapter(context, R.layout.controls_spinner_item).apply {
-            addAll(items)
+        val adapter = ItemAdapter(context, R.layout.controls_spinner_item).apply {
+            add(selected)
+            addAll(items
+                    .filter { it !== selected }
+                    .sortedBy { it.appName.toString() }
+            )
         }
 
         val iconSize = context.resources
@@ -727,21 +734,27 @@
         controlActionCoordinator.closeDialogs()
     }
 
-    override fun hide() {
-        hidden = true
+    override fun hide(parent: ViewGroup) {
+        // We need to check for the parent because it's possible that  we have started showing in a
+        // different activity. In that case, make sure to only clear things associated with the
+        // passed parent
+        if (parent == this.parent) {
+            Log.d(ControlsUiController.TAG, "hide()")
+            hidden = true
 
-        closeDialogs(true)
-        controlsController.get().unsubscribe()
-        taskViewController?.dismiss()
-        taskViewController = null
+            closeDialogs(true)
+            controlsController.get().unsubscribe()
+            taskViewController?.dismiss()
+            taskViewController = null
 
+            controlsById.clear()
+            controlViewsById.clear()
+
+            controlsListingController.get().removeCallback(listingCallback)
+
+            if (!retainCache) RenderInfo.clearCache()
+        }
         parent.removeAllViews()
-        controlsById.clear()
-        controlViewsById.clear()
-
-        controlsListingController.get().removeCallback(listingCallback)
-
-        if (!retainCache) RenderInfo.clearCache()
     }
 
     override fun onRefreshState(componentName: ComponentName, controls: List<Control>) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
index 3b6ab20..78e87ca 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
@@ -71,7 +71,7 @@
                 taskView.post {
                     val roundedCorner =
                         activityContext.resources.getDimensionPixelSize(
-                            R.dimen.notification_corner_radius
+                            R.dimen.controls_panel_corner_radius
                         )
                     val radii = FloatArray(8) { roundedCorner.toFloat() }
                     taskView.background =
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
index 03a1dc0..378b7bb 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
@@ -52,6 +52,7 @@
 import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.dagger.StartCentralSurfacesModule;
+import com.android.systemui.statusbar.events.StatusBarEventsModule;
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
 import com.android.systemui.statusbar.phone.DozeServiceHost;
@@ -101,6 +102,7 @@
         QSModule.class,
         ReferenceScreenshotModule.class,
         RotationLockModule.class,
+        StatusBarEventsModule.class,
         StartCentralSurfacesModule.class,
         VolumeModule.class
 })
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 5b4ce06..f0ee443 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -255,6 +255,11 @@
     @BindsOptionalOf
     abstract FingerprintInteractiveToAuthProvider optionalFingerprintInteractiveToAuthProvider();
 
+    @BindsOptionalOf
+    //TODO(b/269430792 remove full qualifier. Full qualifier is used to avoid merge conflict.)
+    abstract com.android.systemui.statusbar.events.SystemStatusAnimationScheduler
+    optionalSystemStatusAnimationScheduler();
+
     @SysUISingleton
     @Binds
     abstract SystemClock bindSystemClock(SystemClockImpl systemClock);
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index 5aebc32..9660aae 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -195,7 +195,14 @@
             mDreamOverlayTouchMonitor.init();
 
             mStateController.setShouldShowComplications(shouldShowComplications());
-            addOverlayWindowLocked(layoutParams);
+
+            // If we are not able to add the overlay window, reset the overlay.
+            if (!addOverlayWindowLocked(layoutParams)) {
+                resetCurrentDreamOverlayLocked();
+                return;
+            }
+
+
             setCurrentStateLocked(Lifecycle.State.RESUMED);
             mStateController.setOverlayActive(true);
             final ComponentName dreamComponent = getDreamComponent();
@@ -241,7 +248,7 @@
      * @param layoutParams The {@link android.view.WindowManager.LayoutParams} which allow inserting
      *                     into the dream window.
      */
-    private void addOverlayWindowLocked(WindowManager.LayoutParams layoutParams) {
+    private boolean addOverlayWindowLocked(WindowManager.LayoutParams layoutParams) {
         mWindow = new PhoneWindow(mContext);
         // Default to SystemUI name for TalkBack.
         mWindow.setTitle("");
@@ -266,9 +273,22 @@
         // risk an IllegalStateException in some cases when setting the container view as the
         // window's content view and the container view hasn't been properly removed previously).
         removeContainerViewFromParentLocked();
+
         mWindow.setContentView(mDreamOverlayContainerViewController.getContainerView());
 
-        mWindowManager.addView(mWindow.getDecorView(), mWindow.getAttributes());
+        // It is possible that a dream's window (and the dream as a whole) is no longer valid by
+        // the time the overlay service processes the dream. This can happen for example if
+        // another dream is started immediately after the existing dream begins. In this case, the
+        // overlay service should identify the situation through the thrown exception and tear down
+        // the overlay.
+        try {
+            mWindowManager.addView(mWindow.getDecorView(), mWindow.getAttributes());
+            return true;
+        } catch (WindowManager.BadTokenException exception) {
+            Log.e(TAG, "Dream activity window invalid: " + layoutParams.packageName,
+                    exception);
+            return false;
+        }
     }
 
     private void removeContainerViewFromParentLocked() {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java
index e39073b..ff1f312 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java
@@ -28,6 +28,8 @@
 import com.android.systemui.CoreStartable;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.BcSmartspaceDataPlugin;
 import com.android.systemui.shared.condition.Monitor;
 import com.android.systemui.util.condition.ConditionalCoreStartable;
@@ -68,6 +70,7 @@
         private final DreamSmartspaceController mSmartSpaceController;
         private final DreamOverlayStateController mDreamOverlayStateController;
         private final SmartSpaceComplication mComplication;
+        private final FeatureFlags mFeatureFlags;
 
         private final BcSmartspaceDataPlugin.SmartspaceTargetListener mSmartspaceListener =
                 new BcSmartspaceDataPlugin.SmartspaceTargetListener() {
@@ -85,15 +88,21 @@
                 DreamOverlayStateController dreamOverlayStateController,
                 SmartSpaceComplication smartSpaceComplication,
                 DreamSmartspaceController smartSpaceController,
-                @Named(DREAM_PRETEXT_MONITOR) Monitor monitor) {
+                @Named(DREAM_PRETEXT_MONITOR) Monitor monitor,
+                FeatureFlags featureFlags) {
             super(monitor);
             mDreamOverlayStateController = dreamOverlayStateController;
             mComplication = smartSpaceComplication;
             mSmartSpaceController = smartSpaceController;
+            mFeatureFlags = featureFlags;
         }
 
         @Override
         public void onStart() {
+            if (mFeatureFlags.isEnabled(Flags.HIDE_SMARTSPACE_ON_DREAM_OVERLAY)) {
+                return;
+            }
+
             mDreamOverlayStateController.addCallback(new DreamOverlayStateController.Callback() {
                 @Override
                 public void onStateChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
index 88c02b8..13563df 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
@@ -29,7 +29,7 @@
 import com.android.systemui.dreams.DreamOverlayService;
 import com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule;
 import com.android.systemui.dreams.touch.scrim.dagger.ScrimModule;
-import com.android.systemui.process.condition.UserProcessCondition;
+import com.android.systemui.process.condition.SystemProcessCondition;
 import com.android.systemui.shared.condition.Condition;
 import com.android.systemui.shared.condition.Monitor;
 
@@ -126,7 +126,7 @@
     @Binds
     @IntoSet
     @Named(DREAM_PRETEXT_CONDITIONS)
-    Condition bindsUserProcessCondition(UserProcessCondition condition);
+    Condition bindSystemProcessCondition(SystemProcessCondition condition);
 
     /** */
     @Provides
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/BouncerScrimController.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/BouncerScrimController.java
index f5bbba7..776b7bd 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/BouncerScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/BouncerScrimController.java
@@ -34,7 +34,7 @@
 
     @Override
     public void show() {
-        mStatusBarKeyguardViewManager.showBouncer(false);
+        mStatusBarKeyguardViewManager.showPrimaryBouncer(false);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt
index dc7fc28..06ca0ad 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.statusbar.commandline.CommandRegistry
 import com.android.systemui.util.InitializationChecker
+import com.android.systemui.util.concurrency.DelayableExecutor
 import dagger.Binds
 import dagger.Module
 import dagger.multibindings.ClassKey
@@ -36,7 +37,9 @@
     private val flagCommand: FlagCommand,
     private val featureFlags: FeatureFlagsDebug,
     private val broadcastSender: BroadcastSender,
-    private val initializationChecker: InitializationChecker
+    private val initializationChecker: InitializationChecker,
+    private val restartDozeListener: RestartDozeListener,
+    private val delayableExecutor: DelayableExecutor
 ) : CoreStartable {
 
     init {
@@ -52,6 +55,9 @@
             // protected broadcast should only be sent for the main process
             val intent = Intent(FlagManager.ACTION_SYSUI_STARTED)
             broadcastSender.sendBroadcast(intent)
+
+            restartDozeListener.init()
+            delayableExecutor.executeDelayed({ restartDozeListener.maybeRestartSleep() }, 1000)
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt
index d088d74..133e67f 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt
@@ -18,6 +18,8 @@
 
 import com.android.systemui.CoreStartable
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.util.InitializationChecker
+import com.android.systemui.util.concurrency.DelayableExecutor
 import dagger.Binds
 import dagger.Module
 import dagger.multibindings.ClassKey
@@ -26,7 +28,13 @@
 
 class FeatureFlagsReleaseStartable
 @Inject
-constructor(dumpManager: DumpManager, featureFlags: FeatureFlags) : CoreStartable {
+constructor(
+    dumpManager: DumpManager,
+    featureFlags: FeatureFlags,
+    private val initializationChecker: InitializationChecker,
+    private val restartDozeListener: RestartDozeListener,
+    private val delayableExecutor: DelayableExecutor
+) : CoreStartable {
 
     init {
         dumpManager.registerCriticalDumpable(FeatureFlagsRelease.TAG) { pw, args ->
@@ -35,7 +43,10 @@
     }
 
     override fun start() {
-        // no-op
+        if (initializationChecker.initializeComponents()) {
+            restartDozeListener.init()
+            delayableExecutor.executeDelayed({ restartDozeListener.maybeRestartSleep() }, 1000)
+        }
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 343fcb0..4fb763f 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -59,10 +59,10 @@
         )
 
     // TODO(b/254512517): Tracking Bug
-    val FSI_REQUIRES_KEYGUARD = unreleasedFlag(110, "fsi_requires_keyguard", teamfood = true)
+    val FSI_REQUIRES_KEYGUARD = releasedFlag(110, "fsi_requires_keyguard")
 
     // TODO(b/259130119): Tracking Bug
-    val FSI_ON_DND_UPDATE = unreleasedFlag(259130119, "fsi_on_dnd_update", teamfood = true)
+    val FSI_ON_DND_UPDATE = releasedFlag(259130119, "fsi_on_dnd_update")
 
     // TODO(b/265804648): Tracking Bug
     @JvmField val DISABLE_FSI = unreleasedFlag(265804648, "disable_fsi")
@@ -187,11 +187,7 @@
 
     // TODO(b/262780002): Tracking Bug
     @JvmField
-    val REVAMPED_WALLPAPER_UI = unreleasedFlag(222, "revamped_wallpaper_ui", teamfood = false)
-
-    /** A different path for unocclusion transitions back to keyguard */
-    // TODO(b/262859270): Tracking Bug
-    @JvmField val UNOCCLUSION_TRANSITION = releasedFlag(223, "unocclusion_transition")
+    val REVAMPED_WALLPAPER_UI = unreleasedFlag(222, "revamped_wallpaper_ui", teamfood = true)
 
     // flag for controlling auto pin confirmation and material u shapes in bouncer
     @JvmField
@@ -217,6 +213,7 @@
         unreleasedFlag(
             228,
             "lock_screen_long_press_enabled",
+            teamfood = true,
         )
 
     // 300 - power menu
@@ -234,10 +231,12 @@
     val SMARTSPACE_DATE_WEATHER_DECOUPLED =
         sysPropBooleanFlag(403, "persist.sysui.ss.dw_decoupled", default = false)
 
+    // TODO(b/270223352): Tracking Bug
+    @JvmField
+    val HIDE_SMARTSPACE_ON_DREAM_OVERLAY = unreleasedFlag(404, "hide_smartspace_on_dream_overlay")
+
     // 500 - quick settings
 
-    // TODO(b/254512321): Tracking Bug
-    @JvmField val COMBINED_QS_HEADERS = releasedFlag(501, "combined_qs_headers")
     val PEOPLE_TILE = resourceBooleanFlag(502, R.bool.flag_conversations, "people_tile")
 
     @JvmField
@@ -248,6 +247,9 @@
             "qs_user_detail_shortcut"
         )
 
+    @JvmField
+    val QS_PIPELINE_NEW_HOST = unreleasedFlag(504, "qs_pipeline_new_host", teamfood = false)
+
     // TODO(b/254512383): Tracking Bug
     @JvmField
     val FULL_SCREEN_USER_SWITCHER =
@@ -262,6 +264,17 @@
     val QS_SECONDARY_DATA_SUB_INFO =
         unreleasedFlag(508, "qs_secondary_data_sub_info", teamfood = true)
 
+    /** Enables Font Scaling Quick Settings tile */
+    // TODO(b/269341316): Tracking Bug
+    @JvmField
+    val ENABLE_FONT_SCALING_TILE = unreleasedFlag(509, "enable_font_scaling_tile", teamfood = false)
+
+    /** Enables new QS Edit Mode visual refresh */
+    // TODO(b/269787742): Tracking Bug
+    @JvmField
+    val ENABLE_NEW_QS_EDIT_MODE =
+        unreleasedFlag(510, "enable_new_qs_edit_mode", teamfood = false)
+
     // 600- status bar
 
     // TODO(b/256614753): Tracking Bug
@@ -288,6 +301,9 @@
     val NEW_STATUS_BAR_ICONS_DEBUG_COLORING =
         unreleasedFlag(611, "new_status_bar_icons_debug_coloring")
 
+    // TODO(b/265892345): Tracking Bug
+    val PLUG_IN_STATUS_BAR_CHIP = unreleasedFlag(265892345, "plug_in_status_bar_chip")
+
     // 700 - dialer/calls
     // TODO(b/254512734): Tracking Bug
     val ONGOING_CALL_STATUS_BAR_CHIP = releasedFlag(700, "ongoing_call_status_bar_chip")
@@ -361,6 +377,9 @@
     // TODO(b/267166152) : Tracking Bug
     val MEDIA_RETAIN_RECOMMENDATIONS = unreleasedFlag(916, "media_retain_recommendations")
 
+    // TODO(b/270437894): Tracking Bug
+    val MEDIA_REMOTE_RESUME = unreleasedFlag(917, "media_remote_resume")
+
     // 1000 - dock
     val SIMULATE_DOCK_THROUGH_CHARGING = releasedFlag(1000, "simulate_dock_through_charging")
 
@@ -471,8 +490,7 @@
         sysPropBooleanFlag(1202, "persist.wm.debug.predictive_back_always_enforce", default = false)
 
     // TODO(b/254512728): Tracking Bug
-    @JvmField
-    val NEW_BACK_AFFORDANCE = unreleasedFlag(1203, "new_back_affordance", teamfood = true)
+    @JvmField val NEW_BACK_AFFORDANCE = unreleasedFlag(1203, "new_back_affordance", teamfood = true)
 
     // TODO(b/255854141): Tracking Bug
     @JvmField
@@ -595,7 +613,8 @@
     @JvmField val UDFPS_ELLIPSE_DETECTION = unreleasedFlag(2202, "udfps_ellipse_detection")
 
     // 2300 - stylus
-    @JvmField val TRACK_STYLUS_EVER_USED = releasedFlag(2300, "track_stylus_ever_used")
+    @JvmField
+    val TRACK_STYLUS_EVER_USED = unreleasedFlag(2300, "track_stylus_ever_used", teamfood = true)
     @JvmField val ENABLE_STYLUS_CHARGING_UI = unreleasedFlag(2301, "enable_stylus_charging_ui")
     @JvmField
     val ENABLE_USI_BATTERY_NOTIFICATIONS = unreleasedFlag(2302, "enable_usi_battery_notifications")
diff --git a/packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt b/packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt
new file mode 100644
index 0000000..bd74f4e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.flags
+
+import android.os.PowerManager
+import android.util.Log
+import com.android.internal.annotations.VisibleForTesting
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.util.settings.SecureSettings
+import com.android.systemui.util.time.SystemClock
+import javax.inject.Inject
+
+@SysUISingleton
+class RestartDozeListener
+@Inject
+constructor(
+    private val settings: SecureSettings,
+    private val statusBarStateController: StatusBarStateController,
+    private val powerManager: PowerManager,
+    private val systemClock: SystemClock,
+) {
+
+    companion object {
+        @VisibleForTesting val RESTART_NAP_KEY = "restart_nap_after_start"
+    }
+
+    private var inited = false
+
+    val listener =
+        object : StatusBarStateController.StateListener {
+            override fun onDreamingChanged(isDreaming: Boolean) {
+                settings.putBool(RESTART_NAP_KEY, isDreaming)
+            }
+        }
+
+    fun init() {
+        if (inited) {
+            return
+        }
+        inited = true
+
+        statusBarStateController.addCallback(listener)
+    }
+
+    fun destroy() {
+        statusBarStateController.removeCallback(listener)
+    }
+
+    fun maybeRestartSleep() {
+        if (settings.getBool(RESTART_NAP_KEY, false)) {
+            Log.d("RestartDozeListener", "Restarting sleep state")
+            powerManager.wakeUp(systemClock.uptimeMillis())
+            powerManager.goToSleep(systemClock.uptimeMillis())
+            settings.putBool(RESTART_NAP_KEY, false)
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt b/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
index e225b10..9b748d0 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
@@ -57,16 +57,16 @@
         override fun onPropertiesChanged(properties: DeviceConfig.Properties) {
             if (isTestHarness) {
                 Log.w(TAG, "Ignore server flag changes in Test Harness mode.")
+                return
             }
             if (properties.namespace != namespace) {
                 return
             }
 
-
             for ((listener, flags) in listeners) {
                 propLoop@ for (propName in properties.keyset) {
                     for (flag in flags) {
-                        if (propName == getServerOverrideName(flag.id) || propName == flag.name) {
+                        if (propName == flag.name) {
                             listener.onChange(flag)
                             break@propLoop
                         }
@@ -103,10 +103,6 @@
         }
         listeners.add(Pair(listener, flags))
     }
-
-    private fun getServerOverrideName(flagId: Int): String {
-        return "flag_override_$flagId"
-    }
 }
 
 @Module
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt
index e9b8908..496c64e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt
@@ -17,6 +17,14 @@
 
 package com.android.systemui.keyboard
 
+import com.android.systemui.keyboard.data.repository.KeyboardRepository
+import com.android.systemui.keyboard.data.repository.KeyboardRepositoryImpl
+import dagger.Binds
 import dagger.Module
 
-@Module abstract class KeyboardModule
+@Module
+abstract class KeyboardModule {
+
+    @Binds
+    abstract fun bindKeyboardRepository(repository: KeyboardRepositoryImpl): KeyboardRepository
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/data/model/BacklightModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/data/model/BacklightModel.kt
new file mode 100644
index 0000000..ea15a9f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/data/model/BacklightModel.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyboard.data.model
+
+/**
+ * Model for current state of keyboard backlight brightness. [level] indicates current level of
+ * backlight brightness and [maxLevel] its max possible value.
+ */
+data class BacklightModel(val level: Int, val maxLevel: Int)
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt
new file mode 100644
index 0000000..70faf40
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyboard.data.repository
+
+import android.hardware.input.InputManager
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.keyboard.data.model.BacklightModel
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.shareIn
+
+interface KeyboardRepository {
+    val keyboardConnected: Flow<Boolean>
+    val backlight: Flow<BacklightModel>
+}
+
+@SysUISingleton
+class KeyboardRepositoryImpl
+@Inject
+constructor(
+    @Application private val applicationScope: CoroutineScope,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
+    private val inputManager: InputManager,
+) : KeyboardRepository {
+
+    private val connectedDeviceIds: Flow<Set<Int>> =
+        conflatedCallbackFlow {
+                fun send(element: Set<Int>) = trySendWithFailureLogging(element, TAG)
+
+                var connectedKeyboards = inputManager.inputDeviceIds.toSet()
+                val listener =
+                    object : InputManager.InputDeviceListener {
+                        override fun onInputDeviceAdded(deviceId: Int) {
+                            connectedKeyboards = connectedKeyboards + deviceId
+                            send(connectedKeyboards)
+                        }
+
+                        override fun onInputDeviceChanged(deviceId: Int) = Unit
+
+                        override fun onInputDeviceRemoved(deviceId: Int) {
+                            connectedKeyboards = connectedKeyboards - deviceId
+                            send(connectedKeyboards)
+                        }
+                    }
+                send(connectedKeyboards)
+                inputManager.registerInputDeviceListener(listener, /* handler= */ null)
+                awaitClose { inputManager.unregisterInputDeviceListener(listener) }
+            }
+            .shareIn(
+                scope = applicationScope,
+                started = SharingStarted.Lazily,
+                replay = 1,
+            )
+
+    override val keyboardConnected: Flow<Boolean> =
+        connectedDeviceIds
+            .map { it.any { deviceId -> isPhysicalFullKeyboard(deviceId) } }
+            .distinctUntilChanged()
+            .flowOn(backgroundDispatcher)
+
+    override val backlight: Flow<BacklightModel> =
+        conflatedCallbackFlow {
+            // TODO(b/268645734) register BacklightListener
+        }
+
+    private fun isPhysicalFullKeyboard(deviceId: Int): Boolean {
+        val device = inputManager.getInputDevice(deviceId)
+        return !device.isVirtual && device.isFullKeyboard
+    }
+
+    companion object {
+        const val TAG = "KeyboardRepositoryImpl"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt b/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
index 680c504..27a5974 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
@@ -131,7 +131,7 @@
             throw UnsupportedOperationException()
         }
 
-        return insertSelection(values)
+        return runBlocking(mainDispatcher) { insertSelection(values) }
     }
 
     override fun query(
@@ -171,7 +171,7 @@
             throw UnsupportedOperationException()
         }
 
-        return deleteSelection(uri, selectionArgs)
+        return runBlocking(mainDispatcher) { deleteSelection(uri, selectionArgs) }
     }
 
     override fun call(method: String, arg: String?, extras: Bundle?): Bundle? {
@@ -189,7 +189,7 @@
         }
     }
 
-    private fun insertSelection(values: ContentValues?): Uri? {
+    private suspend fun insertSelection(values: ContentValues?): Uri? {
         if (values == null) {
             throw IllegalArgumentException("Cannot insert selection, no values passed in!")
         }
@@ -311,7 +311,7 @@
             }
     }
 
-    private fun querySlots(): Cursor {
+    private suspend fun querySlots(): Cursor {
         return MatrixCursor(
                 arrayOf(
                     Contract.LockScreenQuickAffordances.SlotTable.Columns.ID,
@@ -330,7 +330,7 @@
             }
     }
 
-    private fun queryFlags(): Cursor {
+    private suspend fun queryFlags(): Cursor {
         return MatrixCursor(
                 arrayOf(
                     Contract.FlagsTable.Columns.NAME,
@@ -353,7 +353,7 @@
             }
     }
 
-    private fun deleteSelection(
+    private suspend fun deleteSelection(
         uri: Uri,
         selectionArgs: Array<out String>?,
     ): Int {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 47872d2..4d40db0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -638,6 +638,7 @@
             checkPermission();
             mKeyguardViewMediator.onScreenTurnedOff();
             mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_OFF);
+            mScreenOnCoordinator.onScreenTurnedOff();
         }
 
         @Override // Binder interface
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 6db1f89..d914bf5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -58,6 +58,7 @@
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.SoundPool;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.DeadObjectException;
 import android.os.Handler;
@@ -66,6 +67,7 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.Trace;
@@ -101,6 +103,7 @@
 import com.android.internal.policy.IKeyguardExitCallback;
 import com.android.internal.policy.IKeyguardStateCallback;
 import com.android.internal.policy.ScreenDecorationsUtils;
+import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardConstants;
@@ -123,8 +126,6 @@
 import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.dagger.KeyguardModule;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -269,6 +270,8 @@
     private AlarmManager mAlarmManager;
     private AudioManager mAudioManager;
     private StatusBarManager mStatusBarManager;
+    private final IStatusBarService mStatusBarService;
+    private final IBinder mStatusBarDisableToken = new Binder();
     private final UserTracker mUserTracker;
     private final SysuiStatusBarStateController mStatusBarStateController;
     private final Executor mUiBgExecutor;
@@ -510,8 +513,6 @@
 
     private CentralSurfaces mCentralSurfaces;
 
-    private boolean mUnocclusionTransitionFlagEnabled = false;
-
     private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
             new DeviceConfig.OnPropertiesChangedListener() {
             @Override
@@ -963,9 +964,6 @@
                 public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
                         RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
                         IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
-                    if (!mUnocclusionTransitionFlagEnabled) {
-                        setOccluded(true /* isOccluded */, true /* animate */);
-                    }
                     if (apps == null || apps.length == 0 || apps[0] == null) {
                         if (DEBUG) {
                             Log.d(TAG, "No apps provided to the OccludeByDream runner; "
@@ -1016,7 +1014,7 @@
                             @Override
                             public void onAnimationEnd(Animator animation) {
                                 try {
-                                    if (!mIsCancelled && mUnocclusionTransitionFlagEnabled) {
+                                    if (!mIsCancelled) {
                                         // We're already on the main thread, don't queue this call
                                         handleSetOccluded(true /* isOccluded */,
                                                 false /* animate */);
@@ -1193,7 +1191,6 @@
             ScreenOnCoordinator screenOnCoordinator,
             InteractionJankMonitor interactionJankMonitor,
             DreamOverlayStateController dreamOverlayStateController,
-            FeatureFlags featureFlags,
             Lazy<ShadeController> shadeControllerLazy,
             Lazy<NotificationShadeWindowController> notificationShadeWindowControllerLazy,
             Lazy<ActivityLaunchAnimator> activityLaunchAnimator,
@@ -1211,6 +1208,8 @@
         mPM = powerManager;
         mTrustManager = trustManager;
         mUserSwitcherController = userSwitcherController;
+        mStatusBarService = IStatusBarService.Stub.asInterface(
+                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
         mKeyguardDisplayManager = keyguardDisplayManager;
         mShadeController = shadeControllerLazy;
         dumpManager.registerDumpable(getClass().getName(), this);
@@ -1250,7 +1249,6 @@
 
         mDreamOpenAnimationDuration = (int) DREAMING_ANIMATION_DURATION_MS;
         mDreamCloseAnimationDuration = (int) LOCKSCREEN_ANIMATION_DURATION_MS;
-        mUnocclusionTransitionFlagEnabled = featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION);
     }
 
     public void userActivity() {
@@ -2931,7 +2929,12 @@
             // 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) {
-                mStatusBarManager.disable(flags);
+                try {
+                    mStatusBarService.disableForUser(flags, mStatusBarDisableToken,
+                            mContext.getPackageName(), mUserTracker.getUserId());
+                } catch (RemoteException e) {
+                    Log.d(TAG, "Failed to force clear flags", e);
+                }
             }
 
             if (forceHideHomeRecentsButtons || isShowingAndNotOccluded()) {
@@ -2947,7 +2950,12 @@
                         +  " --> flags=0x" + Integer.toHexString(flags));
             }
 
-            mStatusBarManager.disable(flags);
+            try {
+                mStatusBarService.disableForUser(flags, mStatusBarDisableToken,
+                        mContext.getPackageName(), mUserTracker.getUserId());
+            } catch (RemoteException e) {
+                Log.d(TAG, "Failed to set disable flags: " + flags, e);
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
index 98d3570..47ef0fa 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -39,7 +39,6 @@
 import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.keyguard.KeyguardViewMediator;
@@ -113,7 +112,6 @@
             ScreenOnCoordinator screenOnCoordinator,
             InteractionJankMonitor interactionJankMonitor,
             DreamOverlayStateController dreamOverlayStateController,
-            FeatureFlags featureFlags,
             Lazy<ShadeController> shadeController,
             Lazy<NotificationShadeWindowController> notificationShadeWindowController,
             Lazy<ActivityLaunchAnimator> activityLaunchAnimator,
@@ -144,7 +142,6 @@
                 screenOnCoordinator,
                 interactionJankMonitor,
                 dreamOverlayStateController,
-                featureFlags,
                 shadeController,
                 notificationShadeWindowController,
                 activityLaunchAnimator,
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 baadc66..84abf57 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
@@ -24,8 +24,10 @@
 import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback
 import android.os.Looper
 import android.os.UserHandle
+import android.util.Log
 import com.android.internal.widget.LockPatternUtils
 import com.android.systemui.Dumpable
+import com.android.systemui.R
 import com.android.systemui.biometrics.AuthController
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
@@ -35,6 +37,7 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.keyguard.shared.model.DevicePosture
 import com.android.systemui.user.data.repository.UserRepository
 import java.io.PrintWriter
 import javax.inject.Inject
@@ -47,8 +50,10 @@
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.flow.transformLatest
@@ -82,6 +87,12 @@
 
     /** Whether fingerprint feature is enabled for the current user by the DevicePolicy */
     val isFingerprintEnabledByDevicePolicy: StateFlow<Boolean>
+
+    /**
+     * Whether face authentication is supported for the current device posture. Face auth can be
+     * restricted to specific postures using [R.integer.config_face_auth_supported_posture]
+     */
+    val isFaceAuthSupportedInCurrentPosture: Flow<Boolean>
 }
 
 @SysUISingleton
@@ -98,11 +109,27 @@
     @Background backgroundDispatcher: CoroutineDispatcher,
     biometricManager: BiometricManager?,
     @Main looper: Looper,
+    devicePostureRepository: DevicePostureRepository,
     dumpManager: DumpManager,
 ) : BiometricSettingsRepository, Dumpable {
 
+    override val isFaceAuthSupportedInCurrentPosture: Flow<Boolean>
+
     init {
         dumpManager.registerDumpable(this)
+        val configFaceAuthSupportedPosture =
+            DevicePosture.toPosture(
+                context.resources.getInteger(R.integer.config_face_auth_supported_posture)
+            )
+        isFaceAuthSupportedInCurrentPosture =
+            if (configFaceAuthSupportedPosture == DevicePosture.UNKNOWN) {
+                    flowOf(true)
+                } else {
+                    devicePostureRepository.currentDevicePosture.map {
+                        it == configFaceAuthSupportedPosture
+                    }
+                }
+                .onEach { Log.d(TAG, "isFaceAuthSupportedInCurrentPosture value changed to: $it") }
     }
 
     override fun dump(pw: PrintWriter, args: Array<String?>) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DevicePostureRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DevicePostureRepository.kt
new file mode 100644
index 0000000..adb1e01
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DevicePostureRepository.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.data.repository
+
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.shared.model.DevicePosture
+import com.android.systemui.statusbar.policy.DevicePostureController
+import javax.inject.Inject
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+
+/** Provide current device posture state. */
+interface DevicePostureRepository {
+    /** Provides the current device posture. */
+    val currentDevicePosture: Flow<DevicePosture>
+}
+
+@SysUISingleton
+class DevicePostureRepositoryImpl
+@Inject
+constructor(private val postureController: DevicePostureController) : DevicePostureRepository {
+    override val currentDevicePosture: Flow<DevicePosture>
+        get() = conflatedCallbackFlow {
+            val sendPostureUpdate = { posture: Int ->
+                val currentDevicePosture = DevicePosture.toPosture(posture)
+                trySendWithFailureLogging(
+                    currentDevicePosture,
+                    TAG,
+                    "Error sending posture update to $currentDevicePosture"
+                )
+            }
+            val callback = DevicePostureController.Callback { sendPostureUpdate(it) }
+            postureController.addCallback(callback)
+            sendPostureUpdate(postureController.devicePosture)
+
+            awaitClose { postureController.removeCallback(callback) }
+        }
+
+    companion object {
+        const val TAG = "PostureRepositoryImpl"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt
index 4331fe6..0e85347 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt
@@ -60,7 +60,6 @@
      */
     val panelExpansionAmount: StateFlow<Float>
     val keyguardPosition: StateFlow<Float>
-    val onScreenTurnedOff: StateFlow<Boolean>
     val isBackButtonEnabled: StateFlow<Boolean?>
     /** Determines if user is already unlocked */
     val keyguardAuthenticated: StateFlow<Boolean?>
@@ -70,6 +69,8 @@
     val bouncerErrorMessage: CharSequence?
     val alternateBouncerVisible: StateFlow<Boolean>
     val alternateBouncerUIAvailable: StateFlow<Boolean>
+    val sideFpsShowing: StateFlow<Boolean>
+
     var lastAlternateBouncerVisibleTime: Long
 
     fun setPrimaryScrimmed(isScrimmed: Boolean)
@@ -98,11 +99,11 @@
 
     fun setIsBackButtonEnabled(isBackButtonEnabled: Boolean)
 
-    fun setOnScreenTurnedOff(onScreenTurnedOff: Boolean)
-
     fun setAlternateVisible(isVisible: Boolean)
 
     fun setAlternateBouncerUIAvailable(isAvailable: Boolean)
+
+    fun setSideFpsShowing(isShowing: Boolean)
 }
 
 @SysUISingleton
@@ -142,8 +143,6 @@
     override val panelExpansionAmount = _panelExpansionAmount.asStateFlow()
     private val _keyguardPosition = MutableStateFlow(0f)
     override val keyguardPosition = _keyguardPosition.asStateFlow()
-    private val _onScreenTurnedOff = MutableStateFlow(false)
-    override val onScreenTurnedOff = _onScreenTurnedOff.asStateFlow()
     private val _isBackButtonEnabled = MutableStateFlow<Boolean?>(null)
     override val isBackButtonEnabled = _isBackButtonEnabled.asStateFlow()
     private val _keyguardAuthenticated = MutableStateFlow<Boolean?>(null)
@@ -165,6 +164,8 @@
     private val _alternateBouncerUIAvailable = MutableStateFlow(false)
     override val alternateBouncerUIAvailable: StateFlow<Boolean> =
         _alternateBouncerUIAvailable.asStateFlow()
+    private val _sideFpsShowing = MutableStateFlow(false)
+    override val sideFpsShowing: StateFlow<Boolean> = _sideFpsShowing.asStateFlow()
 
     init {
         setUpLogging()
@@ -235,8 +236,8 @@
         _isBackButtonEnabled.value = isBackButtonEnabled
     }
 
-    override fun setOnScreenTurnedOff(onScreenTurnedOff: Boolean) {
-        _onScreenTurnedOff.value = onScreenTurnedOff
+    override fun setSideFpsShowing(isShowing: Boolean) {
+        _sideFpsShowing.value = isShowing
     }
 
     /** Sets up logs for state flows. */
@@ -276,9 +277,6 @@
             .map { it.toInt() }
             .logDiffsForTable(buffer, "", "KeyguardPosition", -1)
             .launchIn(applicationScope)
-        onScreenTurnedOff
-            .logDiffsForTable(buffer, "", "OnScreenTurnedOff", false)
-            .launchIn(applicationScope)
         isBackButtonEnabled
             .filterNotNull()
             .logDiffsForTable(buffer, "", "IsBackButtonEnabled", false)
@@ -293,6 +291,9 @@
         alternateBouncerUIAvailable
             .logDiffsForTable(buffer, "", "IsAlternateBouncerUIAvailable", false)
             .launchIn(applicationScope)
+        sideFpsShowing
+            .logDiffsForTable(buffer, "", "isSideFpsShowing", false)
+            .launchIn(applicationScope)
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthManager.kt
new file mode 100644
index 0000000..2069891
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthManager.kt
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.data.repository
+
+import android.app.StatusBarManager
+import android.content.Context
+import android.hardware.face.FaceManager
+import android.os.CancellationSignal
+import com.android.internal.logging.InstanceId
+import com.android.internal.logging.UiEventLogger
+import com.android.keyguard.FaceAuthUiEvent
+import com.android.systemui.Dumpable
+import com.android.systemui.R
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.keyguard.shared.model.AcquiredAuthenticationStatus
+import com.android.systemui.keyguard.shared.model.AuthenticationStatus
+import com.android.systemui.keyguard.shared.model.DetectionStatus
+import com.android.systemui.keyguard.shared.model.ErrorAuthenticationStatus
+import com.android.systemui.keyguard.shared.model.FailedAuthenticationStatus
+import com.android.systemui.keyguard.shared.model.HelpAuthenticationStatus
+import com.android.systemui.keyguard.shared.model.SuccessAuthenticationStatus
+import com.android.systemui.log.FaceAuthenticationLogger
+import com.android.systemui.log.SessionTracker
+import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.user.data.repository.UserRepository
+import java.io.PrintWriter
+import java.util.Arrays
+import java.util.stream.Collectors
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+/**
+ * API to run face authentication and detection for device entry / on keyguard (as opposed to the
+ * biometric prompt).
+ */
+interface KeyguardFaceAuthManager {
+    /**
+     * Trigger face authentication.
+     *
+     * [uiEvent] provided should be logged whenever face authentication runs. Invocation should be
+     * ignored if face authentication is already running. Results should be propagated through
+     * [authenticationStatus]
+     */
+    suspend fun authenticate(uiEvent: FaceAuthUiEvent)
+
+    /**
+     * Trigger face detection.
+     *
+     * Invocation should be ignored if face authentication is currently running.
+     */
+    suspend fun detect()
+
+    /** Stop currently running face authentication or detection. */
+    fun cancel()
+
+    /** Provide the current status of face authentication. */
+    val authenticationStatus: Flow<AuthenticationStatus>
+
+    /** Provide the current status of face detection. */
+    val detectionStatus: Flow<DetectionStatus>
+
+    /** Current state of whether face authentication is locked out or not. */
+    val isLockedOut: Flow<Boolean>
+
+    /** Current state of whether face authentication is running. */
+    val isAuthRunning: Flow<Boolean>
+
+    /** Is face detection supported. */
+    val isDetectionSupported: Boolean
+}
+
+@SysUISingleton
+class KeyguardFaceAuthManagerImpl
+@Inject
+constructor(
+    context: Context,
+    private val faceManager: FaceManager? = null,
+    private val userRepository: UserRepository,
+    private val keyguardBypassController: KeyguardBypassController? = null,
+    @Application private val applicationScope: CoroutineScope,
+    @Main private val mainDispatcher: CoroutineDispatcher,
+    private val sessionTracker: SessionTracker,
+    private val uiEventsLogger: UiEventLogger,
+    private val faceAuthLogger: FaceAuthenticationLogger,
+    dumpManager: DumpManager,
+) : KeyguardFaceAuthManager, Dumpable {
+    private var cancellationSignal: CancellationSignal? = null
+    private val lockscreenBypassEnabled: Boolean
+        get() = keyguardBypassController?.bypassEnabled ?: false
+    private var faceAcquiredInfoIgnoreList: Set<Int>
+
+    private val faceLockoutResetCallback =
+        object : FaceManager.LockoutResetCallback() {
+            override fun onLockoutReset(sensorId: Int) {
+                _isLockedOut.value = false
+            }
+        }
+
+    init {
+        faceManager?.addLockoutResetCallback(faceLockoutResetCallback)
+        faceAcquiredInfoIgnoreList =
+            Arrays.stream(
+                    context.resources.getIntArray(
+                        R.array.config_face_acquire_device_entry_ignorelist
+                    )
+                )
+                .boxed()
+                .collect(Collectors.toSet())
+        dumpManager.registerCriticalDumpable("KeyguardFaceAuthManagerImpl", this)
+    }
+
+    private val faceAuthCallback =
+        object : FaceManager.AuthenticationCallback() {
+            override fun onAuthenticationFailed() {
+                _authenticationStatus.value = FailedAuthenticationStatus
+                faceAuthLogger.authenticationFailed()
+                onFaceAuthRequestCompleted()
+            }
+
+            override fun onAuthenticationAcquired(acquireInfo: Int) {
+                _authenticationStatus.value = AcquiredAuthenticationStatus(acquireInfo)
+                faceAuthLogger.authenticationAcquired(acquireInfo)
+            }
+
+            override fun onAuthenticationError(errorCode: Int, errString: CharSequence?) {
+                val errorStatus = ErrorAuthenticationStatus(errorCode, errString.toString())
+                if (errorStatus.isLockoutError()) {
+                    _isLockedOut.value = true
+                }
+                _authenticationStatus.value = errorStatus
+                if (errorStatus.isCancellationError()) {
+                    cancelNotReceivedHandlerJob?.cancel()
+                    applicationScope.launch {
+                        faceAuthLogger.launchingQueuedFaceAuthRequest(
+                            faceAuthRequestedWhileCancellation
+                        )
+                        faceAuthRequestedWhileCancellation?.let { authenticate(it) }
+                        faceAuthRequestedWhileCancellation = null
+                    }
+                }
+                faceAuthLogger.authenticationError(
+                    errorCode,
+                    errString,
+                    errorStatus.isLockoutError(),
+                    errorStatus.isCancellationError()
+                )
+                onFaceAuthRequestCompleted()
+            }
+
+            override fun onAuthenticationHelp(code: Int, helpStr: CharSequence?) {
+                if (faceAcquiredInfoIgnoreList.contains(code)) {
+                    return
+                }
+                _authenticationStatus.value = HelpAuthenticationStatus(code, helpStr.toString())
+            }
+
+            override fun onAuthenticationSucceeded(result: FaceManager.AuthenticationResult) {
+                _authenticationStatus.value = SuccessAuthenticationStatus(result)
+                faceAuthLogger.faceAuthSuccess(result)
+                onFaceAuthRequestCompleted()
+            }
+        }
+
+    private fun onFaceAuthRequestCompleted() {
+        cancellationInProgress = false
+        _isAuthRunning.value = false
+        cancellationSignal = null
+    }
+
+    private val detectionCallback =
+        FaceManager.FaceDetectionCallback { sensorId, userId, isStrong ->
+            faceAuthLogger.faceDetected()
+            _detectionStatus.value = DetectionStatus(sensorId, userId, isStrong)
+        }
+
+    private var cancellationInProgress = false
+    private var faceAuthRequestedWhileCancellation: FaceAuthUiEvent? = null
+
+    override suspend fun authenticate(uiEvent: FaceAuthUiEvent) {
+        if (_isAuthRunning.value) {
+            faceAuthLogger.ignoredFaceAuthTrigger(uiEvent)
+            return
+        }
+
+        if (cancellationInProgress) {
+            faceAuthLogger.queuingRequestWhileCancelling(
+                faceAuthRequestedWhileCancellation,
+                uiEvent
+            )
+            faceAuthRequestedWhileCancellation = uiEvent
+            return
+        } else {
+            faceAuthRequestedWhileCancellation = null
+        }
+
+        withContext(mainDispatcher) {
+            // We always want to invoke face auth in the main thread.
+            cancellationSignal = CancellationSignal()
+            _isAuthRunning.value = true
+            uiEventsLogger.logWithInstanceIdAndPosition(
+                uiEvent,
+                0,
+                null,
+                keyguardSessionId,
+                uiEvent.extraInfo
+            )
+            faceAuthLogger.authenticating(uiEvent)
+            faceManager?.authenticate(
+                null,
+                cancellationSignal,
+                faceAuthCallback,
+                null,
+                currentUserId,
+                lockscreenBypassEnabled
+            )
+        }
+    }
+
+    override suspend fun detect() {
+        if (!isDetectionSupported) {
+            faceAuthLogger.detectionNotSupported(faceManager, faceManager?.sensorPropertiesInternal)
+            return
+        }
+        if (_isAuthRunning.value) {
+            faceAuthLogger.skippingBecauseAlreadyRunning("detection")
+            return
+        }
+
+        cancellationSignal = CancellationSignal()
+        withContext(mainDispatcher) {
+            // We always want to invoke face detect in the main thread.
+            faceAuthLogger.faceDetectionStarted()
+            faceManager?.detectFace(cancellationSignal, detectionCallback, currentUserId)
+        }
+    }
+
+    private val currentUserId: Int
+        get() = userRepository.getSelectedUserInfo().id
+
+    override fun cancel() {
+        if (cancellationSignal == null) return
+
+        cancellationSignal?.cancel()
+        cancelNotReceivedHandlerJob =
+            applicationScope.launch {
+                delay(DEFAULT_CANCEL_SIGNAL_TIMEOUT)
+                faceAuthLogger.cancelSignalNotReceived(
+                    _isAuthRunning.value,
+                    _isLockedOut.value,
+                    cancellationInProgress,
+                    faceAuthRequestedWhileCancellation
+                )
+                onFaceAuthRequestCompleted()
+            }
+        cancellationInProgress = true
+        _isAuthRunning.value = false
+    }
+
+    private var cancelNotReceivedHandlerJob: Job? = null
+
+    private val _authenticationStatus: MutableStateFlow<AuthenticationStatus?> =
+        MutableStateFlow(null)
+    override val authenticationStatus: Flow<AuthenticationStatus>
+        get() = _authenticationStatus.filterNotNull()
+
+    private val _detectionStatus = MutableStateFlow<DetectionStatus?>(null)
+    override val detectionStatus: Flow<DetectionStatus>
+        get() = _detectionStatus.filterNotNull()
+
+    private val _isLockedOut = MutableStateFlow(false)
+    override val isLockedOut: Flow<Boolean> = _isLockedOut
+
+    override val isDetectionSupported =
+        faceManager?.sensorPropertiesInternal?.firstOrNull()?.supportsFaceDetection ?: false
+
+    private val _isAuthRunning = MutableStateFlow(false)
+    override val isAuthRunning: Flow<Boolean>
+        get() = _isAuthRunning
+
+    private val keyguardSessionId: InstanceId?
+        get() = sessionTracker.getSessionId(StatusBarManager.SESSION_KEYGUARD)
+
+    companion object {
+        const val TAG = "KeyguardFaceAuthManager"
+
+        /**
+         * If no cancel signal has been received after this amount of time, assume that it is
+         * cancelled.
+         */
+        const val DEFAULT_CANCEL_SIGNAL_TIMEOUT = 3000L
+    }
+
+    override fun dump(pw: PrintWriter, args: Array<out String>) {
+        pw.println("KeyguardFaceAuthManagerImpl state:")
+        pw.println("  cancellationInProgress: $cancellationInProgress")
+        pw.println("  _isLockedOut.value: ${_isLockedOut.value}")
+        pw.println("  _isAuthRunning.value: ${_isAuthRunning.value}")
+        pw.println("  isDetectionSupported: $isDetectionSupported")
+        pw.println("  FaceManager state:")
+        pw.println("    faceManager: $faceManager")
+        pw.println("    sensorPropertiesInternal: ${faceManager?.sensorPropertiesInternal}")
+        pw.println(
+            "    supportsFaceDetection: " +
+                "${faceManager?.sensorPropertiesInternal?.firstOrNull()?.supportsFaceDetection}"
+        )
+        pw.println(
+            "  faceAuthRequestedWhileCancellation: ${faceAuthRequestedWhileCancellation?.reason}"
+        )
+        pw.println("  cancellationSignal: $cancellationSignal")
+        pw.println("  faceAcquiredInfoIgnoreList: $faceAcquiredInfoIgnoreList")
+        pw.println("  _authenticationStatus: ${_authenticationStatus.value}")
+        pw.println("  _detectionStatus: ${_detectionStatus.value}")
+        pw.println("  currentUserId: $currentUserId")
+        pw.println("  keyguardSessionId: $keyguardSessionId")
+        pw.println("  lockscreenBypassEnabled: $lockscreenBypassEnabled")
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt
index 4a262f5..f27f899 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryModule.kt
@@ -31,6 +31,8 @@
     @Binds
     fun lightRevealScrimRepository(impl: LightRevealScrimRepositoryImpl): LightRevealScrimRepository
 
+    @Binds fun devicePostureRepository(impl: DevicePostureRepositoryImpl): DevicePostureRepository
+
     @Binds
     fun biometricSettingsRepository(
         impl: BiometricSettingsRepositoryImpl
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
index dfe1038..0140529 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager.LegacyAlternateBouncer
+import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.time.SystemClock
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
@@ -33,6 +34,7 @@
 class AlternateBouncerInteractor
 @Inject
 constructor(
+    private val keyguardStateController: KeyguardStateController,
     private val bouncerRepository: KeyguardBouncerRepository,
     private val biometricSettingsRepository: BiometricSettingsRepository,
     private val deviceEntryFingerprintAuthRepository: DeviceEntryFingerprintAuthRepository,
@@ -102,7 +104,8 @@
                 biometricSettingsRepository.isFingerprintEnrolled.value &&
                 biometricSettingsRepository.isStrongBiometricAllowed.value &&
                 biometricSettingsRepository.isFingerprintEnabledByDevicePolicy.value &&
-                !deviceEntryFingerprintAuthRepository.isLockedOut.value
+                !deviceEntryFingerprintAuthRepository.isLockedOut.value &&
+                !keyguardStateController.isUnlocked
         } else {
             legacyAlternateBouncer != null &&
                 keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(true)
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 b2da793..dfbe1c2 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
@@ -18,12 +18,14 @@
 package com.android.systemui.keyguard.domain.interactor
 
 import android.app.AlertDialog
+import android.app.admin.DevicePolicyManager
 import android.content.Intent
 import android.util.Log
 import com.android.internal.widget.LockPatternUtils
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.animation.Expandable
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
@@ -41,13 +43,17 @@
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import dagger.Lazy
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.withContext
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SysUISingleton
 class KeyguardQuickAffordanceInteractor
 @Inject
@@ -61,6 +67,8 @@
     private val featureFlags: FeatureFlags,
     private val repository: Lazy<KeyguardQuickAffordanceRepository>,
     private val launchAnimator: DialogLaunchAnimator,
+    private val devicePolicyManager: DevicePolicyManager,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
 ) {
     private val isUsingRepository: Boolean
         get() = featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES)
@@ -74,9 +82,13 @@
         get() = featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES)
 
     /** Returns an observable for the quick affordance at the given position. */
-    fun quickAffordance(
+    suspend fun quickAffordance(
         position: KeyguardQuickAffordancePosition
     ): Flow<KeyguardQuickAffordanceModel> {
+        if (isFeatureDisabledByDevicePolicy()) {
+            return flowOf(KeyguardQuickAffordanceModel.Hidden)
+        }
+
         return combine(
             quickAffordanceAlwaysVisible(position),
             keyguardInteractor.isDozing,
@@ -148,13 +160,20 @@
      *
      * @return `true` if the affordance was selected successfully; `false` otherwise.
      */
-    fun select(slotId: String, affordanceId: String): Boolean {
+    suspend fun select(slotId: String, affordanceId: String): Boolean {
         check(isUsingRepository)
+        if (isFeatureDisabledByDevicePolicy()) {
+            return false
+        }
 
         val slots = repository.get().getSlotPickerRepresentations()
         val slot = slots.find { it.id == slotId } ?: return false
         val selections =
-            repository.get().getCurrentSelections().getOrDefault(slotId, emptyList()).toMutableList()
+            repository
+                .get()
+                .getCurrentSelections()
+                .getOrDefault(slotId, emptyList())
+                .toMutableList()
         val alreadySelected = selections.remove(affordanceId)
         if (!alreadySelected) {
             while (selections.size > 0 && selections.size >= slot.maxSelectedAffordances) {
@@ -183,8 +202,11 @@
      * @return `true` if the affordance was successfully removed; `false` otherwise (for example, if
      * the affordance was not on the slot to begin with).
      */
-    fun unselect(slotId: String, affordanceId: String?): Boolean {
+    suspend fun unselect(slotId: String, affordanceId: String?): Boolean {
         check(isUsingRepository)
+        if (isFeatureDisabledByDevicePolicy()) {
+            return false
+        }
 
         val slots = repository.get().getSlotPickerRepresentations()
         if (slots.find { it.id == slotId } == null) {
@@ -203,7 +225,11 @@
         }
 
         val selections =
-            repository.get().getCurrentSelections().getOrDefault(slotId, emptyList()).toMutableList()
+            repository
+                .get()
+                .getCurrentSelections()
+                .getOrDefault(slotId, emptyList())
+                .toMutableList()
         return if (selections.remove(affordanceId)) {
             repository
                 .get()
@@ -219,6 +245,10 @@
 
     /** Returns affordance IDs indexed by slot ID, for all known slots. */
     suspend fun getSelections(): Map<String, List<KeyguardQuickAffordancePickerRepresentation>> {
+        if (isFeatureDisabledByDevicePolicy()) {
+            return emptyMap()
+        }
+
         val slots = repository.get().getSlotPickerRepresentations()
         val selections = repository.get().getCurrentSelections()
         val affordanceById =
@@ -343,13 +373,17 @@
         return repository.get().getAffordancePickerRepresentations()
     }
 
-    fun getSlotPickerRepresentations(): List<KeyguardSlotPickerRepresentation> {
+    suspend fun getSlotPickerRepresentations(): List<KeyguardSlotPickerRepresentation> {
         check(isUsingRepository)
 
+        if (isFeatureDisabledByDevicePolicy()) {
+            return emptyList()
+        }
+
         return repository.get().getSlotPickerRepresentations()
     }
 
-    fun getPickerFlags(): List<KeyguardPickerFlag> {
+    suspend fun getPickerFlags(): List<KeyguardPickerFlag> {
         return listOf(
             KeyguardPickerFlag(
                 name = Contract.FlagsTable.FLAG_NAME_REVAMPED_WALLPAPER_UI,
@@ -357,7 +391,9 @@
             ),
             KeyguardPickerFlag(
                 name = Contract.FlagsTable.FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED,
-                value = featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES),
+                value =
+                    !isFeatureDisabledByDevicePolicy() &&
+                        featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES),
             ),
             KeyguardPickerFlag(
                 name = Contract.FlagsTable.FLAG_NAME_CUSTOM_CLOCKS_ENABLED,
@@ -374,6 +410,17 @@
         )
     }
 
+    private suspend fun isFeatureDisabledByDevicePolicy(): Boolean {
+        val flags =
+            withContext(backgroundDispatcher) {
+                devicePolicyManager.getKeyguardDisabledFeatures(null, userTracker.userId)
+            }
+        val flagsToCheck =
+            DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL or
+                DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL
+        return flagsToCheck and flags != 0
+    }
+
     companion object {
         private const val TAG = "KeyguardQuickAffordanceInteractor"
         private const val DELIMITER = "::"
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
index 6610983..c709fd1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
+import android.content.Context
 import android.content.res.ColorStateList
 import android.hardware.biometrics.BiometricSourceType
 import android.os.Handler
@@ -23,9 +24,13 @@
 import android.os.UserHandle
 import android.os.UserManager
 import android.view.View
+import android.util.Log
+import com.android.keyguard.KeyguardConstants
 import com.android.keyguard.KeyguardSecurityModel
 import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.DejankUtils
+import com.android.systemui.R
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
@@ -62,8 +67,9 @@
     private val primaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor,
     private val falsingCollector: FalsingCollector,
     private val dismissCallbackRegistry: DismissCallbackRegistry,
+    private val context: Context,
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
     keyguardBypassController: KeyguardBypassController,
-    keyguardUpdateMonitor: KeyguardUpdateMonitor,
 ) {
     /** Whether we want to wait for face auth. */
     private val primaryBouncerFaceDelay =
@@ -90,7 +96,6 @@
     }
 
     val keyguardAuthenticated: Flow<Boolean> = repository.keyguardAuthenticated.filterNotNull()
-    val screenTurnedOff: Flow<Unit> = repository.onScreenTurnedOff.filter { it }.map {}
     val show: Flow<KeyguardBouncerModel> = repository.primaryBouncerShow.filterNotNull()
     val hide: Flow<Unit> = repository.primaryBouncerHide.filter { it }.map {}
     val startingToHide: Flow<Unit> = repository.primaryBouncerStartingToHide.filter { it }.map {}
@@ -115,6 +120,24 @@
         }
     /** Allow for interaction when just about fully visible */
     val isInteractable: Flow<Boolean> = bouncerExpansion.map { it > 0.9 }
+    val sideFpsShowing: Flow<Boolean> = repository.sideFpsShowing
+
+    init {
+        keyguardUpdateMonitor.registerCallback(
+            object : KeyguardUpdateMonitorCallback() {
+                override fun onBiometricRunningStateChanged(
+                    running: Boolean,
+                    biometricSourceType: BiometricSourceType?
+                ) {
+                    updateSideFpsVisibility()
+                }
+
+                override fun onStrongAuthStateChanged(userId: Int) {
+                    updateSideFpsVisibility()
+                }
+            }
+        )
+    }
 
     // TODO(b/243685699): Move isScrimmed logic to data layer.
     // TODO(b/243695312): Encapsulate all of the show logic for the bouncer.
@@ -122,7 +145,6 @@
     @JvmOverloads
     fun show(isScrimmed: Boolean) {
         // Reset some states as we show the bouncer.
-        repository.setOnScreenTurnedOff(false)
         repository.setKeyguardAuthenticated(null)
         repository.setPrimaryHide(false)
         repository.setPrimaryStartingToHide(false)
@@ -262,11 +284,6 @@
         repository.setKeyguardAuthenticated(strongAuth)
     }
 
-    /** Tell the bouncer the screen has turned off. */
-    fun onScreenTurnedOff() {
-        repository.setOnScreenTurnedOff(true)
-    }
-
     /** Update the position of the bouncer when showing. */
     fun setKeyguardPosition(position: Float) {
         repository.setKeyguardPosition(position)
@@ -301,6 +318,35 @@
         repository.setPrimaryStartDisappearAnimation(finishRunnable)
     }
 
+    /** Determine whether to show the side fps animation. */
+    fun updateSideFpsVisibility() {
+        val sfpsEnabled: Boolean =
+            context.resources.getBoolean(R.bool.config_show_sidefps_hint_on_bouncer)
+        val fpsDetectionRunning: Boolean = keyguardUpdateMonitor.isFingerprintDetectionRunning
+        val isUnlockingWithFpAllowed: Boolean =
+            keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed
+        val bouncerVisible = repository.primaryBouncerVisible.value
+        val toShow =
+            (repository.primaryBouncerVisible.value &&
+                sfpsEnabled &&
+                fpsDetectionRunning &&
+                isUnlockingWithFpAllowed &&
+                !isAnimatingAway())
+
+        if (KeyguardConstants.DEBUG) {
+            Log.d(
+                TAG,
+                ("sideFpsToShow=$toShow\n" +
+                    "bouncerVisible=$bouncerVisible\n" +
+                    "configEnabled=$sfpsEnabled\n" +
+                    "fpsDetectionRunning=$fpsDetectionRunning\n" +
+                    "isUnlockingWithFpAllowed=$isUnlockingWithFpAllowed\n" +
+                    "isAnimatingAway=${isAnimatingAway()}")
+            )
+        }
+        repository.setSideFpsShowing(toShow)
+    }
+
     /** Returns whether bouncer is fully showing. */
     fun isFullyShowing(): Boolean {
         return (repository.primaryBouncerShowingSoon.value ||
@@ -344,4 +390,8 @@
         DejankUtils.removeCallbacks(showRunnable)
         mainHandler.removeCallbacks(showRunnable)
     }
+
+    companion object {
+        private const val TAG = "PrimaryBouncerInteractor"
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/DevicePosture.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/DevicePosture.kt
new file mode 100644
index 0000000..fff7cfe
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/DevicePosture.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.shared.model
+
+import com.android.systemui.statusbar.policy.DevicePostureController
+
+/** Represents the possible posture states of the device. */
+enum class DevicePosture {
+    UNKNOWN,
+    CLOSED,
+    HALF_OPENED,
+    OPENED,
+    FLIPPED;
+
+    companion object {
+        fun toPosture(@DevicePostureController.DevicePostureInt posture: Int): DevicePosture {
+            return when (posture) {
+                DevicePostureController.DEVICE_POSTURE_CLOSED -> CLOSED
+                DevicePostureController.DEVICE_POSTURE_HALF_OPENED -> HALF_OPENED
+                DevicePostureController.DEVICE_POSTURE_OPENED -> OPENED
+                DevicePostureController.DEVICE_POSTURE_FLIPPED -> FLIPPED
+                DevicePostureController.DEVICE_POSTURE_UNKNOWN -> UNKNOWN
+                else -> UNKNOWN
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/FaceAuthenticationModels.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/FaceAuthenticationModels.kt
new file mode 100644
index 0000000..b1c5f8f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/FaceAuthenticationModels.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.shared.model
+
+import android.hardware.face.FaceManager
+
+/** Authentication status provided by [com.android.keyguard.faceauth.KeyguardFaceAuthManager] */
+sealed class AuthenticationStatus
+
+/** Success authentication status. */
+data class SuccessAuthenticationStatus(val successResult: FaceManager.AuthenticationResult) :
+    AuthenticationStatus()
+
+/** Face authentication help message. */
+data class HelpAuthenticationStatus(val msgId: Int, val msg: String?) : AuthenticationStatus()
+
+/** Face acquired message. */
+data class AcquiredAuthenticationStatus(val acquiredInfo: Int) : AuthenticationStatus()
+
+/** Face authentication failed message. */
+object FailedAuthenticationStatus : AuthenticationStatus()
+
+/** Face authentication error message */
+data class ErrorAuthenticationStatus(val msgId: Int, val msg: String?) : AuthenticationStatus() {
+    /**
+     * Method that checks if [msgId] is a lockout error. A lockout error means that face
+     * authentication is locked out.
+     */
+    fun isLockoutError() = msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT
+
+    /**
+     * Method that checks if [msgId] is a cancellation error. This means that face authentication
+     * was cancelled before it completed.
+     */
+    fun isCancellationError() = msgId == FaceManager.FACE_ERROR_CANCELED
+}
+
+/** Face detection success message. */
+data class DetectionStatus(val sensorId: Int, val userId: Int, val isStrongBiometric: Boolean)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt
index b0c0dd7..7db567b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt
@@ -22,16 +22,19 @@
 import android.window.OnBackAnimationCallback
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.keyguard.KeyguardHostViewController
+import com.android.keyguard.KeyguardSecurityContainerController
 import com.android.keyguard.KeyguardSecurityModel
+import com.android.keyguard.KeyguardSecurityView
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.dagger.KeyguardBouncerComponent
+import com.android.settingslib.Utils
 import com.android.systemui.keyguard.data.BouncerViewDelegate
 import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.ActivityStarter
 import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.launch
 
@@ -43,52 +46,54 @@
         viewModel: KeyguardBouncerViewModel,
         componentFactory: KeyguardBouncerComponent.Factory
     ) {
-        // Builds the KeyguardHostViewController from bouncer view group.
-        val hostViewController: KeyguardHostViewController =
-            componentFactory.create(view).keyguardHostViewController
-        hostViewController.init()
+        // Builds the KeyguardSecurityContainerController from bouncer view group.
+        val securityContainerController: KeyguardSecurityContainerController =
+            componentFactory.create(view).securityContainerController
+        securityContainerController.init()
         val delegate =
             object : BouncerViewDelegate {
                 override fun isFullScreenBouncer(): Boolean {
-                    val mode = hostViewController.currentSecurityMode
+                    val mode = securityContainerController.currentSecurityMode
                     return mode == KeyguardSecurityModel.SecurityMode.SimPin ||
                         mode == KeyguardSecurityModel.SecurityMode.SimPuk
                 }
 
                 override fun getBackCallback(): OnBackAnimationCallback {
-                    return hostViewController.backCallback
+                    return securityContainerController.backCallback
                 }
 
                 override fun shouldDismissOnMenuPressed(): Boolean {
-                    return hostViewController.shouldEnableMenuKey()
+                    return securityContainerController.shouldEnableMenuKey()
                 }
 
                 override fun interceptMediaKey(event: KeyEvent?): Boolean {
-                    return hostViewController.interceptMediaKey(event)
+                    return securityContainerController.interceptMediaKey(event)
                 }
 
                 override fun dispatchBackKeyEventPreIme(): Boolean {
-                    return hostViewController.dispatchBackKeyEventPreIme()
+                    return securityContainerController.dispatchBackKeyEventPreIme()
                 }
 
                 override fun showNextSecurityScreenOrFinish(): Boolean {
-                    return hostViewController.dismiss(KeyguardUpdateMonitor.getCurrentUser())
+                    return securityContainerController.dismiss(
+                        KeyguardUpdateMonitor.getCurrentUser()
+                    )
                 }
 
                 override fun resume() {
-                    hostViewController.showPrimarySecurityScreen()
-                    hostViewController.onResume()
+                    securityContainerController.showPrimarySecurityScreen(/* isTurningOff= */ false)
+                    securityContainerController.onResume(KeyguardSecurityView.SCREEN_ON)
                 }
 
                 override fun setDismissAction(
                     onDismissAction: ActivityStarter.OnDismissAction?,
                     cancelAction: Runnable?
                 ) {
-                    hostViewController.setOnDismissAction(onDismissAction, cancelAction)
+                    securityContainerController.setOnDismissAction(onDismissAction, cancelAction)
                 }
 
                 override fun willDismissWithActions(): Boolean {
-                    return hostViewController.hasDismissActions()
+                    return securityContainerController.hasDismissActions()
                 }
             }
         view.repeatWhenAttached {
@@ -98,38 +103,44 @@
                     launch {
                         viewModel.show.collect {
                             // Reset Security Container entirely.
-                            hostViewController.reinflateViewFlipper()
-                            hostViewController.showPromptReason(it.promptReason)
+                            securityContainerController.reinflateViewFlipper()
+                            securityContainerController.showPromptReason(it.promptReason)
                             it.errorMessage?.let { errorMessage ->
-                                hostViewController.showErrorMessage(errorMessage)
+                                securityContainerController.showMessage(
+                                    errorMessage,
+                                    Utils.getColorError(view.context)
+                                )
                             }
-                            hostViewController.showPrimarySecurityScreen()
-                            hostViewController.appear()
-                            hostViewController.onResume()
+                            securityContainerController.showPrimarySecurityScreen(
+                                /* turningOff= */ false
+                            )
+                            securityContainerController.appear()
+                            securityContainerController.onResume(KeyguardSecurityView.SCREEN_ON)
                         }
                     }
 
                     launch {
                         viewModel.hide.collect {
-                            hostViewController.cancelDismissAction()
-                            hostViewController.cleanUp()
-                            hostViewController.resetSecurityContainer()
+                            securityContainerController.cancelDismissAction()
+                            securityContainerController.reset()
                         }
                     }
 
                     launch {
-                        viewModel.startingToHide.collect { hostViewController.onStartingToHide() }
+                        viewModel.startingToHide.collect {
+                            securityContainerController.onStartingToHide()
+                        }
                     }
 
                     launch {
                         viewModel.startDisappearAnimation.collect {
-                            hostViewController.startDisappearAnimation(it)
+                            securityContainerController.startDisappearAnimation(it)
                         }
                     }
 
                     launch {
                         viewModel.bouncerExpansionAmount.collect { expansion ->
-                            hostViewController.setExpansion(expansion)
+                            securityContainerController.setExpansion(expansion)
                         }
                     }
 
@@ -137,50 +148,56 @@
                         viewModel.bouncerExpansionAmount
                             .filter { it == EXPANSION_VISIBLE }
                             .collect {
-                                hostViewController.onResume()
-                                view.announceForAccessibility(
-                                    hostViewController.accessibilityTitleForCurrentMode
-                                )
+                                securityContainerController.onResume(KeyguardSecurityView.SCREEN_ON)
+                                view.announceForAccessibility(securityContainerController.title)
                             }
                     }
 
                     launch {
                         viewModel.isBouncerVisible.collect { isVisible ->
-                            val visibility = if (isVisible) View.VISIBLE else View.INVISIBLE
-                            view.visibility = visibility
-                            hostViewController.onBouncerVisibilityChanged(visibility)
+                            view.visibility = if (isVisible) View.VISIBLE else View.INVISIBLE
+                            securityContainerController.onBouncerVisibilityChanged(isVisible)
                         }
                     }
 
                     launch {
+                        viewModel.isBouncerVisible
+                            .filter { !it }
+                            .collect { securityContainerController.onPause() }
+                    }
+
+                    launch {
                         viewModel.isInteractable.collect { isInteractable ->
-                            hostViewController.setInteractable(isInteractable)
+                            securityContainerController.setInteractable(isInteractable)
                         }
                     }
 
                     launch {
                         viewModel.keyguardPosition.collect { position ->
-                            hostViewController.updateKeyguardPosition(position)
+                            securityContainerController.updateKeyguardPosition(position)
                         }
                     }
 
                     launch {
                         viewModel.updateResources.collect {
-                            hostViewController.updateResources()
+                            securityContainerController.updateResources()
                             viewModel.notifyUpdateResources()
                         }
                     }
 
                     launch {
                         viewModel.bouncerShowMessage.collect {
-                            hostViewController.showMessage(it.message, it.colorStateList)
+                            securityContainerController.showMessage(it.message, it.colorStateList)
                             viewModel.onMessageShown()
                         }
                     }
 
                     launch {
                         viewModel.keyguardAuthenticated.collect {
-                            hostViewController.finish(it, KeyguardUpdateMonitor.getCurrentUser())
+                            securityContainerController.finish(
+                                it,
+                                KeyguardUpdateMonitor.getCurrentUser()
+                            )
                             viewModel.notifyKeyguardAuthenticated()
                         }
                     }
@@ -192,10 +209,14 @@
                     }
 
                     launch {
-                        viewModel.screenTurnedOff.collect {
-                            if (view.visibility == View.VISIBLE) {
-                                hostViewController.onPause()
-                            }
+                        viewModel.shouldUpdateSideFps.collect {
+                            viewModel.updateSideFpsVisibility()
+                        }
+                    }
+
+                    launch {
+                        viewModel.sideFpsShowing.collect {
+                            securityContainerController.updateSideFpsVisibility(it)
                         }
                     }
                     awaitCancellation()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
index 1e3b60c..e7184f7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
@@ -187,6 +187,7 @@
                             previewMode.isInPreviewMode &&
                                 previewMode.shouldHighlightSelectedAffordance &&
                                 !isSelected,
+                        forceInactive = previewMode.isInPreviewMode
                     )
                 }
                 .distinctUntilChanged()
@@ -198,6 +199,7 @@
         isClickable: Boolean,
         isSelected: Boolean,
         isDimmed: Boolean,
+        forceInactive: Boolean,
     ): KeyguardQuickAffordanceViewModel {
         return when (this) {
             is KeyguardQuickAffordanceModel.Visible ->
@@ -213,7 +215,7 @@
                         )
                     },
                     isClickable = isClickable,
-                    isActivated = activationState is ActivationState.Active,
+                    isActivated = !forceInactive && activationState is ActivationState.Active,
                     isSelected = isSelected,
                     useLongPress = quickAffordanceInteractor.useLongPress,
                     isDimmed = isDimmed,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt
index b8b3a8e..97e94d8f3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModel.kt
@@ -24,7 +24,9 @@
 import com.android.systemui.keyguard.shared.model.KeyguardBouncerModel
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
 
 /** Models UI state for the lock screen bouncer; handles user input. */
 class KeyguardBouncerViewModel
@@ -66,8 +68,16 @@
     /** Observe whether keyguard is authenticated already. */
     val keyguardAuthenticated: Flow<Boolean> = interactor.keyguardAuthenticated
 
-    /** Observe whether screen is turned off. */
-    val screenTurnedOff: Flow<Unit> = interactor.screenTurnedOff
+    /** Observe whether the side fps is showing. */
+    val sideFpsShowing: Flow<Boolean> = interactor.sideFpsShowing
+
+    /** Observe whether we should update fps is showing. */
+    val shouldUpdateSideFps: Flow<Unit> =
+        merge(
+            interactor.startingToHide,
+            interactor.isVisible.map {},
+            interactor.startingDisappearAnimation.filterNotNull().map {}
+        )
 
     /** Observe whether we want to update resources. */
     fun notifyUpdateResources() {
@@ -84,6 +94,10 @@
         interactor.onMessageShown()
     }
 
+    fun updateSideFpsVisibility() {
+        interactor.updateSideFpsVisibility()
+    }
+
     /** Observe whether back button is enabled. */
     fun observeOnIsBackButtonEnabled(systemUiVisibility: () -> Int): Flow<Int> {
         return interactor.isBackButtonEnabled.map { enabled ->
diff --git a/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
new file mode 100644
index 0000000..f7349a2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/FaceAuthenticationLogger.kt
@@ -0,0 +1,181 @@
+package com.android.systemui.log
+
+import android.hardware.face.FaceManager
+import android.hardware.face.FaceSensorPropertiesInternal
+import com.android.keyguard.FaceAuthUiEvent
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.dagger.FaceAuthLog
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel.DEBUG
+import com.google.errorprone.annotations.CompileTimeConstant
+import javax.inject.Inject
+
+private const val TAG = "KeyguardFaceAuthManagerLog"
+
+/**
+ * Helper class for logging for [com.android.keyguard.faceauth.KeyguardFaceAuthManager]
+ *
+ * To enable logcat echoing for an entire buffer:
+ *
+ * ```
+ *   adb shell settings put global systemui/buffer/KeyguardFaceAuthManagerLog <logLevel>
+ *
+ * ```
+ */
+@SysUISingleton
+class FaceAuthenticationLogger
+@Inject
+constructor(
+    @FaceAuthLog private val logBuffer: LogBuffer,
+) {
+    fun ignoredFaceAuthTrigger(uiEvent: FaceAuthUiEvent) {
+        logBuffer.log(
+            TAG,
+            DEBUG,
+            { str1 = uiEvent.reason },
+            {
+                "Ignoring trigger because face auth is currently running. " +
+                    "Trigger reason: $str1"
+            }
+        )
+    }
+
+    fun queuingRequestWhileCancelling(
+        alreadyQueuedRequest: FaceAuthUiEvent?,
+        newRequest: FaceAuthUiEvent
+    ) {
+        logBuffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = alreadyQueuedRequest?.reason
+                str2 = newRequest.reason
+            },
+            {
+                "Face auth requested while previous request is being cancelled, " +
+                    "already queued request: $str1 queueing the new request: $str2"
+            }
+        )
+    }
+
+    fun authenticating(uiEvent: FaceAuthUiEvent) {
+        logBuffer.log(TAG, DEBUG, { str1 = uiEvent.reason }, { "Running authenticate for $str1" })
+    }
+
+    fun detectionNotSupported(
+        faceManager: FaceManager?,
+        sensorPropertiesInternal: MutableList<FaceSensorPropertiesInternal>?
+    ) {
+        logBuffer.log(
+            TAG,
+            DEBUG,
+            {
+                bool1 = faceManager == null
+                bool2 = sensorPropertiesInternal.isNullOrEmpty()
+                bool2 = sensorPropertiesInternal?.firstOrNull()?.supportsFaceDetection ?: false
+            },
+            {
+                "skipping detection request because it is not supported, " +
+                    "faceManager isNull: $bool1, " +
+                    "sensorPropertiesInternal isNullOrEmpty: $bool2, " +
+                    "supportsFaceDetection: $bool3"
+            }
+        )
+    }
+
+    fun skippingBecauseAlreadyRunning(@CompileTimeConstant operation: String) {
+        logBuffer.log(TAG, DEBUG, "isAuthRunning is true, skipping $operation")
+    }
+
+    fun faceDetectionStarted() {
+        logBuffer.log(TAG, DEBUG, "Face detection started.")
+    }
+
+    fun faceDetected() {
+        logBuffer.log(TAG, DEBUG, "Face detected")
+    }
+
+    fun cancelSignalNotReceived(
+        isAuthRunning: Boolean,
+        isLockedOut: Boolean,
+        cancellationInProgress: Boolean,
+        faceAuthRequestedWhileCancellation: FaceAuthUiEvent?
+    ) {
+        logBuffer.log(
+            TAG,
+            DEBUG,
+            {
+                bool1 = isAuthRunning
+                bool2 = isLockedOut
+                bool3 = cancellationInProgress
+                str1 = "${faceAuthRequestedWhileCancellation?.reason}"
+            },
+            {
+                "Cancel signal was not received, running timeout handler to reset state. " +
+                    "State before reset: " +
+                    "isAuthRunning: $bool1, " +
+                    "isLockedOut: $bool2, " +
+                    "cancellationInProgress: $bool3, " +
+                    "faceAuthRequestedWhileCancellation: $str1"
+            }
+        )
+    }
+
+    fun authenticationFailed() {
+        logBuffer.log(TAG, DEBUG, "Face authentication failed")
+    }
+
+    fun authenticationAcquired(acquireInfo: Int) {
+        logBuffer.log(
+            TAG,
+            DEBUG,
+            { int1 = acquireInfo },
+            { "Face acquired during face authentication: acquireInfo: $int1 " }
+        )
+    }
+
+    fun authenticationError(
+        errorCode: Int,
+        errString: CharSequence?,
+        lockoutError: Boolean,
+        cancellationError: Boolean
+    ) {
+        logBuffer.log(
+            TAG,
+            DEBUG,
+            {
+                int1 = errorCode
+                str1 = "$errString"
+                bool1 = lockoutError
+                bool2 = cancellationError
+            },
+            {
+                "Received authentication error: errorCode: $int1, " +
+                    "errString: $str1, " +
+                    "isLockoutError: $bool1, " +
+                    "isCancellationError: $bool2"
+            }
+        )
+    }
+
+    fun launchingQueuedFaceAuthRequest(faceAuthRequestedWhileCancellation: FaceAuthUiEvent?) {
+        logBuffer.log(
+            TAG,
+            DEBUG,
+            { str1 = "${faceAuthRequestedWhileCancellation?.reason}" },
+            { "Received cancellation error and starting queued face auth request: $str1" }
+        )
+    }
+
+    fun faceAuthSuccess(result: FaceManager.AuthenticationResult) {
+        logBuffer.log(
+            TAG,
+            DEBUG,
+            {
+                int1 = result.userId
+                bool1 = result.isStrongBiometric
+            },
+            { "Face authenticated successfully: userId: $int1, isStrongBiometric: $bool1" }
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/FaceAuthLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/FaceAuthLog.kt
new file mode 100644
index 0000000..b97e3a7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/FaceAuthLog.kt
@@ -0,0 +1,6 @@
+package com.android.systemui.log.dagger
+
+import javax.inject.Qualifier
+
+/** A [com.android.systemui.log.LogBuffer] for Face authentication triggered by SysUI. */
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class FaceAuthLog()
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index 5341cd5..642c9f7 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -62,6 +62,15 @@
         return factory.create("NotifLog", maxSize, false /* systrace */);
     }
 
+    /** Provides a logging buffer for all logs related to notifications on the lockscreen. */
+    @Provides
+    @SysUISingleton
+    @NotificationLockscreenLog
+    public static LogBuffer provideNotificationLockScreenLogBuffer(
+            LogBufferFactory factory) {
+        return factory.create("NotifLockscreenLog", 50, false /* systrace */);
+    }
+
     /** Provides a logging buffer for logs related to heads up presentation of notifications. */
     @Provides
     @SysUISingleton
@@ -350,6 +359,17 @@
     }
 
     /**
+     * Provides a {@link LogBuffer} for use by
+     *  {@link com.android.keyguard.faceauth.KeyguardFaceAuthManagerImpl}.
+     */
+    @Provides
+    @SysUISingleton
+    @FaceAuthLog
+    public static LogBuffer provideFaceAuthLog(LogBufferFactory factory) {
+        return factory.create("KeyguardFaceAuthManagerLog", 300);
+    }
+
+    /**
      * Provides a {@link LogBuffer} for bluetooth-related logs.
      */
     @Provides
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/NotificationLockscreenLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/NotificationLockscreenLog.java
new file mode 100644
index 0000000..a2d381e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/NotificationLockscreenLog.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.android.systemui.plugins.log.LogBuffer;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+/** A {@link LogBuffer} for notification & lockscreen related messages. */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface NotificationLockscreenLog {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaData.kt b/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaData.kt
index dc7a4f1..0b57175 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/models/recommendation/SmartspaceMediaData.kt
@@ -88,6 +88,8 @@
     }
 }
 
+/** Key to indicate whether this card should be used to re-show recent media */
+const val EXTRA_KEY_TRIGGER_RESUME = "SHOULD_TRIGGER_RESUME"
 /** Key for extras [SmartspaceMediaData.cardAction] indicating why the card was sent */
 const val EXTRA_KEY_TRIGGER_SOURCE = "MEDIA_RECOMMENDATION_TRIGGER_SOURCE"
 /** Value for [EXTRA_KEY_TRIGGER_SOURCE] when the card is sent on headphone connection */
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataFilter.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataFilter.kt
index 27f7b97..97717a6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataFilter.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataFilter.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.broadcast.BroadcastSender
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.media.controls.models.player.MediaData
+import com.android.systemui.media.controls.models.recommendation.EXTRA_KEY_TRIGGER_RESUME
 import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData
 import com.android.systemui.media.controls.util.MediaFlags
 import com.android.systemui.media.controls.util.MediaUiEventLogger
@@ -138,14 +139,23 @@
         val sorted = userEntries.toSortedMap(compareBy { userEntries.get(it)?.lastActive ?: -1 })
         val timeSinceActive = timeSinceActiveForMostRecentMedia(sorted)
         var smartspaceMaxAgeMillis = SMARTSPACE_MAX_AGE
-        data.cardAction?.let {
-            val smartspaceMaxAgeSeconds = it.extras.getLong(RESUMABLE_MEDIA_MAX_AGE_SECONDS_KEY, 0)
+        data.cardAction?.extras?.let {
+            val smartspaceMaxAgeSeconds = it.getLong(RESUMABLE_MEDIA_MAX_AGE_SECONDS_KEY, 0)
             if (smartspaceMaxAgeSeconds > 0) {
                 smartspaceMaxAgeMillis = TimeUnit.SECONDS.toMillis(smartspaceMaxAgeSeconds)
             }
         }
 
-        val shouldReactivate = !hasActiveMedia() && hasAnyMedia() && data.isActive
+        // Check if smartspace has explicitly specified whether to re-activate resumable media.
+        // The default behavior is to trigger if the smartspace data is active.
+        val shouldTriggerResume =
+            if (data.cardAction?.extras?.containsKey(EXTRA_KEY_TRIGGER_RESUME) == true) {
+                data.cardAction.extras.getBoolean(EXTRA_KEY_TRIGGER_RESUME, true)
+            } else {
+                true
+            }
+        val shouldReactivate =
+            shouldTriggerResume && !hasActiveMedia() && hasAnyMedia() && data.isActive
 
         if (timeSinceActive < smartspaceMaxAgeMillis) {
             // It could happen there are existing active media resume cards, then we don't need to
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
index f5558a2..e70a2f3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
@@ -665,7 +665,7 @@
         appIntent: PendingIntent,
         packageName: String
     ) {
-        if (TextUtils.isEmpty(desc.title)) {
+        if (desc.title.isNullOrBlank()) {
             Log.e(TAG, "Description incomplete")
             // Delete the placeholder entry
             mediaEntries.remove(packageName)
@@ -1339,10 +1339,13 @@
     fun onNotificationRemoved(key: String) {
         Assert.isMainThread()
         val removed = mediaEntries.remove(key) ?: return
-
+        val isEligibleForResume =
+            removed.isLocalSession() ||
+                (mediaFlags.isRemoteResumeAllowed() &&
+                    removed.playbackLocation != MediaData.PLAYBACK_CAST_REMOTE)
         if (keyguardUpdateMonitor.isUserInLockdown(removed.userId)) {
             logger.logMediaRemoved(removed.appUid, removed.packageName, removed.instanceId)
-        } else if (useMediaResumption && removed.resumeAction != null && removed.isLocalSession()) {
+        } else if (useMediaResumption && removed.resumeAction != null && isEligibleForResume) {
             convertToResumePlayer(key, removed)
         } else if (mediaFlags.isRetainingPlayersEnabled()) {
             handlePossibleRemoval(key, removed, notificationRemoved = true)
@@ -1405,6 +1408,13 @@
     /** Set the given [MediaData] as a resume state player and notify listeners */
     private fun convertToResumePlayer(key: String, data: MediaData) {
         if (DEBUG) Log.d(TAG, "Converting $key to resume")
+        // Resumption controls must have a title.
+        if (data.song.isNullOrBlank()) {
+            Log.e(TAG, "Description incomplete")
+            notifyMediaDataRemoved(key)
+            logger.logMediaRemoved(data.appUid, data.packageName, data.instanceId)
+            return
+        }
         // Move to resume key (aka package name) if that key doesn't already exist.
         val resumeAction = data.resumeAction?.let { getResumeMediaAction(it) }
         val actions = resumeAction?.let { listOf(resumeAction) } ?: emptyList()
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/resume/MediaResumeListener.kt b/packages/SystemUI/src/com/android/systemui/media/controls/resume/MediaResumeListener.kt
index 2d10b82..2af21c4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/resume/MediaResumeListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/resume/MediaResumeListener.kt
@@ -37,6 +37,7 @@
 import com.android.systemui.media.controls.models.player.MediaData
 import com.android.systemui.media.controls.pipeline.MediaDataManager
 import com.android.systemui.media.controls.pipeline.RESUME_MEDIA_TIMEOUT
+import com.android.systemui.media.controls.util.MediaFlags
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.tuner.TunerService
 import com.android.systemui.util.Utils
@@ -63,7 +64,8 @@
     private val tunerService: TunerService,
     private val mediaBrowserFactory: ResumeMediaBrowserFactory,
     dumpManager: DumpManager,
-    private val systemClock: SystemClock
+    private val systemClock: SystemClock,
+    private val mediaFlags: MediaFlags,
 ) : MediaDataManager.Listener, Dumpable {
 
     private var useMediaResumption: Boolean = Utils.useMediaResumption(context)
@@ -231,7 +233,11 @@
                 mediaBrowser = null
             }
             // If we don't have a resume action, check if we haven't already
-            if (data.resumeAction == null && !data.hasCheckedForResume && data.isLocalSession()) {
+            val isEligibleForResume =
+                data.isLocalSession() ||
+                    (mediaFlags.isRemoteResumeAllowed() &&
+                        data.playbackLocation != MediaData.PLAYBACK_CAST_REMOTE)
+            if (data.resumeAction == null && !data.hasCheckedForResume && isEligibleForResume) {
                 // TODO also check for a media button receiver intended for restarting (b/154127084)
                 Log.d(TAG, "Checking for service component for " + data.packageName)
                 val pm = context.packageManager
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
index 68d2c5c..6cf051a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
@@ -39,6 +39,7 @@
 import com.android.systemui.R
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -68,6 +69,7 @@
 import com.android.systemui.util.traceSection
 import java.io.PrintWriter
 import java.util.TreeMap
+import java.util.concurrent.Executor
 import javax.inject.Inject
 import javax.inject.Provider
 import kotlinx.coroutines.CoroutineScope
@@ -93,7 +95,8 @@
     private val mediaHostStatesManager: MediaHostStatesManager,
     private val activityStarter: ActivityStarter,
     private val systemClock: SystemClock,
-    @Main executor: DelayableExecutor,
+    @Main private val mainExecutor: DelayableExecutor,
+    @Background private val backgroundExecutor: Executor,
     private val mediaManager: MediaDataManager,
     configurationController: ConfigurationController,
     falsingCollector: FalsingCollector,
@@ -256,7 +259,7 @@
             MediaCarouselScrollHandler(
                 mediaCarousel,
                 pageIndicator,
-                executor,
+                mainExecutor,
                 this::onSwipeToDismiss,
                 this::updatePageIndicatorLocation,
                 this::updateSeekbarListening,
@@ -618,10 +621,50 @@
                 MediaPlayerData.visiblePlayerKeys()
                     .elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex)
             if (existingPlayer == null) {
-                val newPlayer = mediaControlPanelFactory.get()
-                newPlayer.attachPlayer(
-                    MediaViewHolder.create(LayoutInflater.from(context), mediaContent)
+                setupNewPlayer(key, data, isSsReactivated, curVisibleMediaKey)
+            } else {
+                existingPlayer.bindPlayer(data, key)
+                MediaPlayerData.addMediaPlayer(
+                    key,
+                    data,
+                    existingPlayer,
+                    systemClock,
+                    isSsReactivated,
+                    debugLogger
                 )
+                val packageName = MediaPlayerData.smartspaceMediaData?.packageName ?: String()
+                // In case of recommendations hits.
+                // Check the playing status of media player and the package name.
+                // To make sure we scroll to the right app's media player.
+                if (
+                    isReorderingAllowed ||
+                        shouldScrollToKey &&
+                            data.isPlaying == true &&
+                            packageName == data.packageName
+                ) {
+                    reorderAllPlayers(curVisibleMediaKey, key)
+                } else {
+                    needsReordering = true
+                }
+                updatePageIndicator()
+                mediaCarouselScrollHandler.onPlayersChanged()
+                mediaFrame.requiresRemeasuring = true
+            }
+            return existingPlayer == null
+        }
+
+    private fun setupNewPlayer(
+        key: String,
+        data: MediaData,
+        isSsReactivated: Boolean,
+        curVisibleMediaKey: MediaPlayerData.MediaSortKey?,
+    ) {
+        backgroundExecutor.execute {
+            val mediaViewHolder = createMediaViewHolderInBg()
+            // Add the new player in the main thread.
+            mainExecutor.execute {
+                val newPlayer = mediaControlPanelFactory.get()
+                newPlayer.attachPlayer(mediaViewHolder)
                 newPlayer.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
                 val lp =
                     LinearLayout.LayoutParams(
@@ -651,36 +694,16 @@
                 } else {
                     needsReordering = true
                 }
-            } else {
-                existingPlayer.bindPlayer(data, key)
-                MediaPlayerData.addMediaPlayer(
-                    key,
-                    data,
-                    existingPlayer,
-                    systemClock,
-                    isSsReactivated,
-                    debugLogger
-                )
-                val packageName = MediaPlayerData.smartspaceMediaData?.packageName ?: String()
-                // In case of recommendations hits.
-                // Check the playing status of media player and the package name.
-                // To make sure we scroll to the right app's media player.
-                if (
-                    isReorderingAllowed ||
-                        shouldScrollToKey &&
-                            data.isPlaying == true &&
-                            packageName == data.packageName
-                ) {
-                    reorderAllPlayers(curVisibleMediaKey, key)
-                } else {
-                    needsReordering = true
-                }
+                updatePageIndicator()
+                mediaCarouselScrollHandler.onPlayersChanged()
+                mediaFrame.requiresRemeasuring = true
             }
-            updatePageIndicator()
-            mediaCarouselScrollHandler.onPlayersChanged()
-            mediaFrame.requiresRemeasuring = true
-            return existingPlayer == null
         }
+    }
+
+    private fun createMediaViewHolderInBg(): MediaViewHolder {
+        return MediaViewHolder.create(LayoutInflater.from(context), mediaContent)
+    }
 
     private fun addSmartspaceMediaRecommendations(
         key: String,
@@ -714,15 +737,14 @@
                     debugLogger.logPotentialMemoryLeak(existingSmartspaceMediaKey)
                 }
             }
-
             val newRecs = mediaControlPanelFactory.get()
-            newRecs.attachRecommendation(
+            val recommendationViewHolder =
                 RecommendationViewHolder.create(
                     LayoutInflater.from(context),
                     mediaContent,
                     mediaFlags.isRecommendationCardUpdateEnabled()
                 )
-            )
+            newRecs.attachRecommendation(recommendationViewHolder)
             newRecs.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
             val lp =
                 LinearLayout.LayoutParams(
@@ -746,17 +768,6 @@
             reorderAllPlayers(curVisibleMediaKey)
             updatePageIndicator()
             mediaFrame.requiresRemeasuring = true
-            // Check postcondition: mediaContent should have the same number of children as there
-            // are
-            // elements in mediaPlayers.
-            if (MediaPlayerData.players().size != mediaContent.childCount) {
-                Log.e(
-                    TAG,
-                    "Size of players list and number of views in carousel are out of sync. " +
-                        "Players size is ${MediaPlayerData.players().size}. " +
-                        "View count is ${mediaContent.childCount}."
-                )
-            }
         }
 
     fun removePlayer(
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
index 7677062..4ab93da 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
@@ -226,7 +226,7 @@
     private final BroadcastDialogController mBroadcastDialogController;
     private boolean mIsCurrentBroadcastedApp = false;
     private boolean mShowBroadcastDialogButton = false;
-    private String mSwitchBroadcastApp;
+    private String mCurrentBroadcastApp;
     private MultiRippleController mMultiRippleController;
     private TurbulenceNoiseController mTurbulenceNoiseController;
     private final FeatureFlags mFeatureFlags;
@@ -572,9 +572,8 @@
             // TODO(b/233698402): Use the package name instead of app label to avoid the
             // unexpected result.
             mIsCurrentBroadcastedApp = device != null
-                    && TextUtils.equals(device.getName(),
-                    MediaDataUtils.getAppLabel(mContext, mPackageName, mContext.getString(
-                            R.string.bt_le_audio_broadcast_dialog_unknown_name)));
+                && TextUtils.equals(device.getName(),
+                    mContext.getString(R.string.broadcasting_description_is_broadcasting));
             useDisabledAlpha = !mIsCurrentBroadcastedApp;
             // Always be enabled if the broadcast button is shown
             isTapEnabled = true;
@@ -629,8 +628,8 @@
                         // media output dialog.
                         if (!mIsCurrentBroadcastedApp) {
                             mLogger.logOpenBroadcastDialog(mUid, mPackageName, mInstanceId);
-                            mSwitchBroadcastApp = device.getName().toString();
-                            mBroadcastDialogController.createBroadcastDialog(mSwitchBroadcastApp,
+                            mCurrentBroadcastApp = device.getName().toString();
+                            mBroadcastDialogController.createBroadcastDialog(mCurrentBroadcastApp,
                                     mPackageName, true, mMediaViewHolder.getSeamlessButton());
                         } else {
                             mLogger.logOpenOutputSwitcher(mUid, mPackageName, mInstanceId);
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
index c3fa76e..9bc66f6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt
@@ -61,4 +61,7 @@
 
     /** If true, do not automatically dismiss the recommendation card */
     fun isPersistentSsCardEnabled() = featureFlags.isEnabled(Flags.MEDIA_RETAIN_RECOMMENDATIONS)
+
+    /** Check whether we allow remote media to generate resume controls */
+    fun isRemoteResumeAllowed() = featureFlags.isEnabled(Flags.MEDIA_REMOTE_RESUME)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt
index 4ff082a..0b0535d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt
@@ -98,7 +98,7 @@
     // Calculates the actual starting percentage according to ripple shader progress set method.
     // Check calculations in [RippleShader.progress]
     fun calculateStartingPercentage(newHeight: Float): Float {
-        val ratio = rippleShader.currentHeight / newHeight
+        val ratio = rippleShader.rippleSize.currentHeight / newHeight
         val remainingPercentage = (1 - ratio).toDouble().pow(1 / 3.toDouble()).toFloat()
         return 1 - remainingPercentage
     }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index 6ee86aa..5b02aaf 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -41,7 +41,6 @@
 
 import android.app.StatusBarManager;
 import android.app.StatusBarManager.WindowVisibleState;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Rect;
@@ -68,7 +67,6 @@
 import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
@@ -78,6 +76,7 @@
 import com.android.systemui.statusbar.phone.BarTransitions;
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.wm.shell.back.BackAnimation;
 import com.android.wm.shell.pip.Pip;
 
@@ -169,16 +168,20 @@
 
     private BackAnimation mBackAnimation;
 
+    private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     @Inject
     public TaskbarDelegate(Context context,
             EdgeBackGestureHandler.Factory edgeBackGestureHandlerFactory,
-            LightBarTransitionsController.Factory lightBarTransitionsControllerFactory) {
+            LightBarTransitionsController.Factory lightBarTransitionsControllerFactory,
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
         mLightBarTransitionsControllerFactory = lightBarTransitionsControllerFactory;
         mEdgeBackGestureHandler = edgeBackGestureHandlerFactory.create(context);
 
         mContext = context;
         mDisplayManager = mContext.getSystemService(DisplayManager.class);
         mPipListener = mEdgeBackGestureHandler::setPipStashExclusionBounds;
+        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+        mStatusBarKeyguardViewManager.setTaskbarDelegate(this);
     }
 
     public void setDependencies(CommandQueue commandQueue,
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
index 8ad2f86..79167f2 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
@@ -16,7 +16,11 @@
 
 import android.content.Context
 import android.util.AttributeSet
+import android.view.Gravity.CENTER_VERTICAL
+import android.view.Gravity.END
 import android.view.ViewGroup
+import android.view.ViewGroup.LayoutParams.MATCH_PARENT
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
 import android.widget.ImageView
 import android.widget.LinearLayout
 import com.android.settingslib.Utils
@@ -35,7 +39,7 @@
     private var iconSize = 0
     private var iconColor = 0
 
-    private lateinit var iconsContainer: LinearLayout
+    private val iconsContainer: LinearLayout
 
     var privacyList = emptyList<PrivacyItem>()
         set(value) {
@@ -43,11 +47,13 @@
             updateView(PrivacyChipBuilder(context, field))
         }
 
-    override fun onFinishInflate() {
-        super.onFinishInflate()
-
+    init {
+        inflate(context, R.layout.ongoing_privacy_chip, this)
+        id = R.id.privacy_chip
+        layoutParams = LayoutParams(WRAP_CONTENT, MATCH_PARENT, CENTER_VERTICAL or END)
+        clipChildren = true
+        clipToPadding = true
         iconsContainer = requireViewById(R.id.icons_container)
-
         updateResources()
     }
 
@@ -107,6 +113,6 @@
         val padding = context.resources
                 .getDimensionPixelSize(R.dimen.ongoing_appops_chip_side_padding)
         iconsContainer.setPaddingRelative(padding, 0, padding, 0)
-        iconsContainer.background = context.getDrawable(R.drawable.privacy_chip_bg)
+        iconsContainer.background = context.getDrawable(R.drawable.statusbar_privacy_chip_bg)
     }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java b/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java
index 245cf89..2751072 100644
--- a/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java
@@ -26,7 +26,10 @@
     @Inject
     public ProcessWrapper() {}
 
-    public int getUserHandleIdentifier() {
-        return android.os.Process.myUserHandle().getIdentifier();
+    /**
+     * Returns {@code true} if System User is running the current process.
+     */
+    public boolean isSystemUser() {
+        return android.os.Process.myUserHandle().isSystem();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/process/condition/UserProcessCondition.java b/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.java
similarity index 67%
rename from packages/SystemUI/src/com/android/systemui/process/condition/UserProcessCondition.java
rename to packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.java
index 5a21ea0..80fbf911 100644
--- a/packages/SystemUI/src/com/android/systemui/process/condition/UserProcessCondition.java
+++ b/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.java
@@ -17,29 +17,26 @@
 package com.android.systemui.process.condition;
 
 import com.android.systemui.process.ProcessWrapper;
-import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.condition.Condition;
 
 import javax.inject.Inject;
 
 /**
- * {@link UserProcessCondition} provides a signal when the process handle belongs to the current
- * user.
+ * {@link SystemProcessCondition} checks to make sure the current process is being ran by the
+ * System User.
  */
-public class UserProcessCondition extends Condition {
+public class SystemProcessCondition extends Condition {
     private final ProcessWrapper mProcessWrapper;
-    private final UserTracker mUserTracker;
 
     @Inject
-    public UserProcessCondition(ProcessWrapper processWrapper, UserTracker userTracker) {
+    public SystemProcessCondition(ProcessWrapper processWrapper) {
+        super();
         mProcessWrapper = processWrapper;
-        mUserTracker = userTracker;
     }
 
     @Override
     protected void start() {
-        updateCondition(mUserTracker.getUserId()
-                == mProcessWrapper.getUserHandleIdentifier());
+        updateCondition(mProcessWrapper.isSystemUser());
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.kt b/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.kt
index be93550..c70cce9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.kt
@@ -183,7 +183,7 @@
     }
 
     fun getRestoredTilePosition(tile: String): Int =
-        restoredTiles?.get(tile)?.index ?: QSTileHost.POSITION_AT_END
+        restoredTiles?.get(tile)?.index ?: QSHost.POSITION_AT_END
 
     /**
      * Returns `true` if the tile has been auto-added before
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index e1289a6..a7aac5a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -135,7 +135,7 @@
     private int mNumQuickTiles;
     private int mLastQQSTileHeight;
     private float mLastPosition;
-    private final QSTileHost mHost;
+    private final QSHost mHost;
     private final Executor mExecutor;
     private boolean mShowCollapsedOnKeyguard;
     private int mQQSTop;
@@ -146,7 +146,7 @@
     @Inject
     public QSAnimator(QS qs, QuickQSPanel quickPanel, QuickStatusBarHeader quickStatusBarHeader,
             QSPanelController qsPanelController,
-            QuickQSPanelController quickQSPanelController, QSTileHost qsTileHost,
+            QuickQSPanelController quickQSPanelController, QSHost qsTileHost,
             @Main Executor executor, TunerService tunerService,
             QSExpansionPathInterpolator qsExpansionPathInterpolator) {
         mQs = qs;
@@ -330,12 +330,8 @@
 
                     // Offset the translation animation on the views
                     // (that goes from 0 to getOffsetTranslation)
-                    int offsetWithQSBHTranslation =
-                            yOffset - mQuickStatusBarHeader.getOffsetTranslation();
-                    qqsTranslationYBuilder.addFloat(quickTileView, "translationY", 0,
-                            offsetWithQSBHTranslation);
-                    translationYBuilder.addFloat(tileView, "translationY",
-                            -offsetWithQSBHTranslation, 0);
+                    qqsTranslationYBuilder.addFloat(quickTileView, "translationY", 0, yOffset);
+                    translationYBuilder.addFloat(tileView, "translationY", -yOffset, 0);
 
                     translationXBuilder.addFloat(quickTileView, "translationX", 0, xOffset);
                     translationXBuilder.addFloat(tileView, "translationX", -xOffset, 0);
@@ -489,7 +485,7 @@
         if (specs.isEmpty()) {
             // specs should not be empty in a valid secondary page, as we scrolled to it.
             // We may crash later on because there's a null animator.
-            specs = mQsPanelController.getHost().mTileSpecs;
+            specs = mHost.getSpecs();
             Log.e(TAG, "Trying to create animators for empty page " + page + ". Tiles: " + specs);
             // return null;
         }
@@ -614,7 +610,7 @@
         View commonView = mQs.getView();
         getRelativePositionInt(qsPosition, view1, commonView);
         getRelativePositionInt(qqsPosition, view2, commonView);
-        return (qsPosition[1] - qqsPosition[1]) - mQuickStatusBarHeader.getOffsetTranslation();
+        return qsPosition[1] - qqsPosition[1];
     }
 
     private boolean isIconInAnimatedRow(int count) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 0c242d9..b7f9f6b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -53,7 +53,6 @@
     private boolean mQsDisabled;
     private int mContentHorizontalPadding = -1;
     private boolean mClippingEnabled;
-    private boolean mUseCombinedHeaders;
 
     public QSContainerImpl(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -68,10 +67,6 @@
         setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
     }
 
-    void setUseCombinedHeaders(boolean useCombinedHeaders) {
-        mUseCombinedHeaders = useCombinedHeaders;
-    }
-
     @Override
     public boolean hasOverlappingRendering() {
         return false;
@@ -150,8 +145,7 @@
     void updateResources(QSPanelController qsPanelController,
             QuickStatusBarHeaderController quickStatusBarHeaderController) {
         int topPadding = QSUtils.getQsHeaderSystemIconsAreaHeight(mContext);
-        if (mUseCombinedHeaders
-                && !LargeScreenUtils.shouldUseLargeScreenShadeHeader(mContext.getResources())) {
+        if (!LargeScreenUtils.shouldUseLargeScreenShadeHeader(mContext.getResources())) {
             topPadding = mContext.getResources()
                     .getDimensionPixelSize(R.dimen.large_screen_shade_header_height);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
index 28b4c822..73a5faa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java
@@ -22,8 +22,6 @@
 import android.view.MotionEvent;
 import android.view.View;
 
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.qs.dagger.QSScope;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -66,15 +64,13 @@
             QSPanelController qsPanelController,
             QuickStatusBarHeaderController quickStatusBarHeaderController,
             ConfigurationController configurationController,
-            FalsingManager falsingManager,
-            FeatureFlags featureFlags) {
+            FalsingManager falsingManager) {
         super(view);
         mQsPanelController = qsPanelController;
         mQuickStatusBarHeaderController = quickStatusBarHeaderController;
         mConfigurationController = configurationController;
         mFalsingManager = falsingManager;
         mQSPanelContainer = mView.getQSPanelContainer();
-        view.setUseCombinedHeaders(featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS));
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 8ad102e..9d34df8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -51,9 +51,7 @@
 import com.android.systemui.animation.ShadeInterpolation;
 import com.android.systemui.compose.ComposeFacade;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.media.controls.ui.MediaHost;
-import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.qs.QSContainerController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -61,6 +59,7 @@
 import com.android.systemui.qs.dagger.QSFragmentComponent;
 import com.android.systemui.qs.footer.ui.binder.FooterActionsViewBinder;
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel;
+import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
@@ -88,14 +87,11 @@
 
     private final Rect mQsBounds = new Rect();
     private final SysuiStatusBarStateController mStatusBarStateController;
-    private final FalsingManager mFalsingManager;
     private final KeyguardBypassController mBypassController;
     private boolean mQsExpanded;
     private boolean mHeaderAnimating;
     private boolean mStackScrollerOverscrolling;
 
-    private long mDelay;
-
     private QSAnimator mQSAnimator;
     private HeightListener mPanelView;
     private QSSquishinessController mQSSquishinessController;
@@ -116,8 +112,7 @@
     private final MediaHost mQqsMediaHost;
     private final QSFragmentComponent.Factory mQsComponentFactory;
     private final QSFragmentDisableFlagsLogger mQsFragmentDisableFlagsLogger;
-    private final QSTileHost mHost;
-    private final FeatureFlags mFeatureFlags;
+    private final QSLogger mLogger;
     private final FooterActionsController mFooterActionsController;
     private final FooterActionsViewModel.Factory mFooterActionsViewModelFactory;
     private final ListeningAndVisibilityLifecycleOwner mListeningAndVisibilityLifecycleOwner;
@@ -150,11 +145,6 @@
      */
     private boolean mTransitioningToFullShade;
 
-    /**
-     * Whether the next Quick settings
-     */
-    private boolean mAnimateNextQsUpdate;
-
     private final DumpManager mDumpManager;
 
     /**
@@ -178,14 +168,13 @@
 
     @Inject
     public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
-            QSTileHost qsTileHost,
             SysuiStatusBarStateController statusBarStateController, CommandQueue commandQueue,
             @Named(QS_PANEL) MediaHost qsMediaHost,
             @Named(QUICK_QS_PANEL) MediaHost qqsMediaHost,
             KeyguardBypassController keyguardBypassController,
             QSFragmentComponent.Factory qsComponentFactory,
             QSFragmentDisableFlagsLogger qsFragmentDisableFlagsLogger,
-            FalsingManager falsingManager, DumpManager dumpManager, FeatureFlags featureFlags,
+            DumpManager dumpManager, QSLogger qsLogger,
             FooterActionsController footerActionsController,
             FooterActionsViewModel.Factory footerActionsViewModelFactory) {
         mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
@@ -193,13 +182,11 @@
         mQqsMediaHost = qqsMediaHost;
         mQsComponentFactory = qsComponentFactory;
         mQsFragmentDisableFlagsLogger = qsFragmentDisableFlagsLogger;
+        mLogger = qsLogger;
         commandQueue.observe(getLifecycle(), this);
-        mHost = qsTileHost;
-        mFalsingManager = falsingManager;
         mBypassController = keyguardBypassController;
         mStatusBarStateController = statusBarStateController;
         mDumpManager = dumpManager;
-        mFeatureFlags = featureFlags;
         mFooterActionsController = footerActionsController;
         mFooterActionsViewModelFactory = footerActionsViewModelFactory;
         mListeningAndVisibilityLifecycleOwner = new ListeningAndVisibilityLifecycleOwner();
@@ -241,7 +228,6 @@
                 (v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
                     // Lazily update animators whenever the scrolling changes
                     mQSAnimator.requestAnimatorUpdate();
-                    mHeader.setExpandedScrollAmount(scrollY);
                     if (mScrollListener != null) {
                         mScrollListener.onQsPanelScrollChanged(scrollY);
                     }
@@ -661,8 +647,6 @@
         int heightDiff = getHeightDiff();
         float panelTranslationY = translationScaleY * heightDiff;
 
-        // Let the views animate their contents correctly by giving them the necessary context.
-        mHeader.setExpansion(onKeyguardAndExpanded, expansion, panelTranslationY);
         if (expansion < 1 && expansion > 0.99) {
             if (mQuickQSPanelController.switchTileLayout(false)) {
                 mHeader.updateResources();
@@ -716,8 +700,10 @@
     private void setAlphaAnimationProgress(float progress) {
         final View view = getView();
         if (progress == 0 && view.getVisibility() != View.INVISIBLE) {
+            mLogger.logVisibility("QS fragment", View.INVISIBLE);
             view.setVisibility(View.INVISIBLE);
         } else if (progress > 0 && view.getVisibility() != View.VISIBLE) {
+            mLogger.logVisibility("QS fragment", View.VISIBLE);
             view.setVisibility((View.VISIBLE));
         }
         view.setAlpha(interpolateAlphaAnimationProgress(progress));
@@ -914,7 +900,6 @@
             getView().getViewTreeObserver().removeOnPreDrawListener(this);
             getView().animate()
                     .translationY(0f)
-                    .setStartDelay(mDelay)
                     .setDuration(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE)
                     .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                     .setListener(mAnimateHeaderSlidingInListener)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
index 1da30ad..a71e6dd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
@@ -14,15 +14,48 @@
 
 package com.android.systemui.qs;
 
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.res.Resources;
+import android.os.Build;
+import android.provider.Settings;
 
 import com.android.internal.logging.InstanceId;
 import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.R;
+import com.android.systemui.plugins.qs.QSFactory;
 import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.plugins.qs.QSTileView;
+import com.android.systemui.util.leak.GarbageMonitor;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
 
 public interface QSHost {
+    String TILES_SETTING = Settings.Secure.QS_TILES;
+    int POSITION_AT_END = -1;
+
+    /**
+     * Returns the default QS tiles for the context.
+     * @param context the context to obtain the resources from
+     * @return a list of specs of the default tiles
+     */
+    static List<String> getDefaultSpecs(Context context) {
+        final ArrayList<String> tiles = new ArrayList();
+
+        final Resources res = context.getResources();
+        final String defaultTileList = res.getString(R.string.quick_settings_tiles_default);
+
+        tiles.addAll(Arrays.asList(defaultTileList.split(",")));
+        if (Build.IS_DEBUGGABLE
+                && GarbageMonitor.ADD_MEMORY_TILE_TO_DEFAULT_ON_DEBUGGABLE_BUILDS) {
+            tiles.add(GarbageMonitor.MemoryTile.TILE_SPEC);
+        }
+        return tiles;
+    }
+
     void warn(String message, Throwable t);
     void collapsePanels();
     void forceCollapsePanels();
@@ -37,6 +70,44 @@
     void removeTile(String tileSpec);
     void removeTiles(Collection<String> specs);
 
+    List<String> getSpecs();
+    /**
+     * Create a view for a tile, iterating over all possible {@link QSFactory}.
+     *
+     * @see QSFactory#createTileView
+     */
+    QSTileView createTileView(Context themedContext, QSTile tile, boolean collapsedView);
+    /** Create a {@link QSTile} of a {@code tileSpec} type. */
+    QSTile createTile(String tileSpec);
+
+    /**
+     * Add a tile to the end
+     *
+     * @param spec string matching a pre-defined tilespec
+     */
+    void addTile(String spec);
+
+    /**
+     * Add a tile into the requested spot, or at the end if the position is greater than the number
+     * of tiles.
+     * @param spec string matching a pre-defined tilespec
+     * @param requestPosition -1 for end, 0 for beginning, or X for insertion at position X
+     */
+    void addTile(String spec, int requestPosition);
+    void addTile(ComponentName tile);
+
+    /**
+     * Adds a custom tile to the set of current tiles.
+     * @param tile the component name of the {@link android.service.quicksettings.TileService}
+     * @param end if true, the tile will be added at the end. If false, at the beginning.
+     */
+    void addTile(ComponentName tile, boolean end);
+    void removeTileByUser(ComponentName tile);
+    void changeTilesByUser(List<String> previousTiles, List<String> newTiles);
+
+    boolean isTileAdded(ComponentName componentName, int userId);
+    void setTileAdded(ComponentName componentName, int userId, boolean added);
+
     int indexOf(String tileSpec);
 
     InstanceId getNewInstanceId();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 7067c220..b476521 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -25,8 +25,6 @@
 import android.content.res.Resources;
 import android.graphics.Rect;
 import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
 import android.util.ArrayMap;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -81,7 +79,6 @@
     protected boolean mExpanded;
     protected boolean mListening;
 
-    @Nullable protected QSTileHost mHost;
     private final List<OnConfigurationChangedListener> mOnConfigurationChangedListeners =
             new ArrayList<>();
 
@@ -106,8 +103,12 @@
     private final Rect mClippingRect = new Rect();
     private ViewGroup mMediaHostView;
     private boolean mShouldMoveMediaOnExpansion = true;
-    private boolean mUsingCombinedHeaders = false;
     private QSLogger mQsLogger;
+    /**
+     * Specifies if we can collapse to QQS in current state. In split shade that should be always
+     * false. It influences available accessibility actions.
+     */
+    private boolean mCanCollapse = true;
 
     public QSPanel(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -152,10 +153,6 @@
         }
     }
 
-    void setUsingCombinedHeaders(boolean usingCombinedHeaders) {
-        mUsingCombinedHeaders = usingCombinedHeaders;
-    }
-
     protected void setHorizontalContentContainerClipping() {
         mHorizontalContentContainer.setClipChildren(true);
         mHorizontalContentContainer.setClipToPadding(false);
@@ -361,11 +358,6 @@
         }
     }
 
-    @Nullable
-    public QSTileHost getHost() {
-        return mHost;
-    }
-
     public void updateResources() {
         updatePadding();
 
@@ -380,9 +372,7 @@
 
     protected void updatePadding() {
         final Resources res = mContext.getResources();
-        int paddingTop = res.getDimensionPixelSize(
-                mUsingCombinedHeaders ? R.dimen.qs_panel_padding_top_combined_headers
-                        : R.dimen.qs_panel_padding_top);
+        int paddingTop = res.getDimensionPixelSize(R.dimen.qs_panel_padding_top);
         int paddingBottom = res.getDimensionPixelSize(R.dimen.qs_panel_padding_bottom);
         setPaddingRelative(getPaddingStart(),
                 paddingTop,
@@ -650,7 +640,9 @@
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
-        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE);
+        if (mCanCollapse) {
+            info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE);
+        }
     }
 
     @Override
@@ -669,15 +661,11 @@
         mCollapseExpandAction = action;
     }
 
-    private class H extends Handler {
-        private static final int ANNOUNCE_FOR_ACCESSIBILITY = 1;
-
-        @Override
-        public void handleMessage(Message msg) {
-            if (msg.what == ANNOUNCE_FOR_ACCESSIBILITY) {
-                announceForAccessibility((CharSequence) msg.obj);
-            }
-        }
+    /**
+     * Specifies if these expanded QS can collapse to QQS.
+     */
+    public void setCanCollapse(boolean canCollapse) {
+        mCanCollapse = canCollapse;
     }
 
     public interface QSTileLayout {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index cabe1da..83b373d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -17,7 +17,6 @@
 package com.android.systemui.qs;
 
 import static com.android.systemui.classifier.Classifier.QS_SWIPE_SIDE;
-import static com.android.systemui.flags.Flags.COMBINED_QS_HEADERS;
 import static com.android.systemui.media.dagger.MediaModule.QS_PANEL;
 import static com.android.systemui.qs.QSPanel.QS_SHOW_BRIGHTNESS;
 import static com.android.systemui.qs.dagger.QSFragmentModule.QS_USING_MEDIA_PLAYER;
@@ -28,7 +27,6 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.media.controls.ui.MediaHierarchyManager;
 import com.android.systemui.media.controls.ui.MediaHost;
 import com.android.systemui.media.controls.ui.MediaHostState;
@@ -73,7 +71,7 @@
 
     @Inject
     QSPanelController(QSPanel view, TunerService tunerService,
-            QSTileHost qstileHost, QSCustomizerController qsCustomizerController,
+            QSHost qsHost, QSCustomizerController qsCustomizerController,
             @Named(QS_USING_MEDIA_PLAYER) boolean usingMediaPlayer,
             @Named(QS_PANEL) MediaHost mediaHost,
             QSTileRevealController.Factory qsTileRevealControllerFactory,
@@ -81,9 +79,8 @@
             QSLogger qsLogger, BrightnessController.Factory brightnessControllerFactory,
             BrightnessSliderController.Factory brightnessSliderFactory,
             FalsingManager falsingManager,
-            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
-            FeatureFlags featureFlags) {
-        super(view, qstileHost, qsCustomizerController, usingMediaPlayer, mediaHost,
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
+        super(view, qsHost, qsCustomizerController, usingMediaPlayer, mediaHost,
                 metricsLogger, uiEventLogger, qsLogger, dumpManager);
         mTunerService = tunerService;
         mQsCustomizerController = qsCustomizerController;
@@ -96,7 +93,6 @@
         mBrightnessController = brightnessControllerFactory.create(mBrightnessSliderController);
         mBrightnessMirrorHandler = new BrightnessMirrorHandler(mBrightnessController);
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
-        mView.setUsingCombinedHeaders(featureFlags.isEnabled(COMBINED_QS_HEADERS));
     }
 
     @Override
@@ -148,9 +144,10 @@
     }
 
     @Override
-    protected void onSplitShadeChanged() {
+    protected void onSplitShadeChanged(boolean shouldUseSplitNotificationShade) {
         ((PagedTileLayout) mView.getOrCreateTileLayout())
                 .forceTilesRedistribution("Split shade state changed");
+        mView.setCanCollapse(!shouldUseSplitNotificationShade);
     }
 
     /** */
@@ -175,12 +172,6 @@
         mBrightnessMirrorHandler.setController(brightnessMirrorController);
     }
 
-    /** Get the QSTileHost this panel uses. */
-    public QSTileHost getHost() {
-        return mHost;
-    }
-
-
     /** Update appearance of QSPanel. */
     public void updateResources() {
         mView.updateResources();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index e85d0a3..2668d2e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -64,7 +64,7 @@
 public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewController<T>
         implements Dumpable{
     private static final String TAG = "QSPanelControllerBase";
-    protected final QSTileHost mHost;
+    protected final QSHost mHost;
     private final QSCustomizerController mQsCustomizerController;
     private final boolean mUsingMediaPlayer;
     protected final MediaHost mMediaHost;
@@ -104,14 +104,14 @@
                     switchTileLayoutIfNeeded();
                     onConfigurationChanged();
                     if (previousSplitShadeState != mShouldUseSplitNotificationShade) {
-                        onSplitShadeChanged();
+                        onSplitShadeChanged(mShouldUseSplitNotificationShade);
                     }
                 }
             };
 
     protected void onConfigurationChanged() { }
 
-    protected void onSplitShadeChanged() { }
+    protected void onSplitShadeChanged(boolean shouldUseSplitNotificationShade) { }
 
     private final Function1<Boolean, Unit> mMediaHostVisibilityListener = (visible) -> {
         if (mMediaVisibilityChangedListener != null) {
@@ -128,7 +128,7 @@
 
     protected QSPanelControllerBase(
             T view,
-            QSTileHost host,
+            QSHost host,
             QSCustomizerController qsCustomizerController,
             @Named(QS_USING_MEDIA_PLAYER) boolean usingMediaPlayer,
             MediaHost mediaHost,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index 98af9df..0ead979 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -18,7 +18,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
-import android.os.Build;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings.Secure;
@@ -56,17 +55,14 @@
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.phone.AutoTileManager;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
-import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
-import com.android.systemui.util.leak.GarbageMonitor;
 import com.android.systemui.util.settings.SecureSettings;
 
 import org.jetbrains.annotations.NotNull;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -94,16 +90,13 @@
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     private static final int MAX_QS_INSTANCE_ID = 1 << 20;
 
-    public static final int POSITION_AT_END = -1;
-    public static final String TILES_SETTING = Secure.QS_TILES;
-
     // Shared prefs that hold tile lifecycle info.
     @VisibleForTesting
     static final String TILES = "tiles_prefs";
 
     private final Context mContext;
     private final LinkedHashMap<String, QSTile> mTiles = new LinkedHashMap<>();
-    protected final ArrayList<String> mTileSpecs = new ArrayList<>();
+    private final ArrayList<String> mTileSpecs = new ArrayList<>();
     private final TunerService mTunerService;
     private final PluginManager mPluginManager;
     private final DumpManager mDumpManager;
@@ -117,7 +110,6 @@
     private final List<Callback> mCallbacks = new ArrayList<>();
     @Nullable
     private AutoTileManager mAutoTiles;
-    private final StatusBarIconController mIconController;
     private final ArrayList<QSFactory> mQsFactories = new ArrayList<>();
     private int mCurrentUser;
     private final Optional<CentralSurfaces> mCentralSurfacesOptional;
@@ -135,7 +127,6 @@
 
     @Inject
     public QSTileHost(Context context,
-            StatusBarIconController iconController,
             QSFactory defaultFactory,
             @Main Executor mainExecutor,
             PluginManager pluginManager,
@@ -152,7 +143,6 @@
             TileLifecycleManager.Factory tileLifecycleManagerFactory,
             UserFileManager userFileManager
     ) {
-        mIconController = iconController;
         mContext = context;
         mUserContext = context;
         mTunerService = tunerService;
@@ -186,10 +176,6 @@
         });
     }
 
-    public StatusBarIconController getIconController() {
-        return mIconController;
-    }
-
     @Override
     public InstanceId getNewInstanceId() {
         return mInstanceIdSequence.newInstanceId();
@@ -438,12 +424,7 @@
         addTile(spec, POSITION_AT_END);
     }
 
-    /**
-     * Add a tile into the requested spot, or at the end if the position is greater than the number
-     * of tiles.
-     * @param spec string matching a pre-defined tilespec
-     * @param requestPosition -1 for end, 0 for beginning, or X for insertion at position X
-     */
+    @Override
     public void addTile(String spec, int requestPosition) {
         mMainExecutor.execute(() ->
                 changeTileSpecs(tileSpecs -> {
@@ -483,15 +464,12 @@
         }
     }
 
+    @Override
     public void addTile(ComponentName tile) {
         addTile(tile, /* end */ false);
     }
 
-    /**
-     * Adds a custom tile to the set of current tiles.
-     * @param tile the component name of the {@link android.service.quicksettings.TileService}
-     * @param end if true, the tile will be added at the end. If false, at the beginning.
-     */
+    @Override
     public void addTile(ComponentName tile, boolean end) {
         String spec = CustomTile.toSpec(tile);
         addTile(spec, end ? POSITION_AT_END : 0);
@@ -501,6 +479,7 @@
      * This will call through {@link #changeTilesByUser}. It should only be used when a tile is
      * removed by a <b>user action</b> like {@code adb}.
      */
+    @Override
     public void removeTileByUser(ComponentName tile) {
         mMainExecutor.execute(() -> {
             List<String> newSpecs = new ArrayList<>(mTileSpecs);
@@ -519,6 +498,7 @@
      * that are removed.
      */
     @MainThread
+    @Override
     public void changeTilesByUser(List<String> previousTiles, List<String> newTiles) {
         final List<String> copy = new ArrayList<>(previousTiles);
         final int NP = copy.size();
@@ -542,8 +522,8 @@
         saveTilesToSettings(newTiles);
     }
 
-    /** Create a {@link QSTile} of a {@code tileSpec} type. */
     @Nullable
+    @Override
     public QSTile createTile(String tileSpec) {
         for (int i = 0; i < mQsFactories.size(); i++) {
             QSTile t = mQsFactories.get(i).createTile(tileSpec);
@@ -554,11 +534,7 @@
         return null;
     }
 
-    /**
-     * Create a view for a tile, iterating over all possible {@link QSFactory}.
-     *
-     * @see QSFactory#createTileView
-     */
+    @Override
     public QSTileView createTileView(Context themedContext, QSTile tile, boolean collapsedView) {
         for (int i = 0; i < mQsFactories.size(); i++) {
             QSTileView view = mQsFactories.get(i)
@@ -578,6 +554,7 @@
      *                      tile.
      * @param userId the user to check
      */
+    @Override
     public boolean isTileAdded(ComponentName componentName, int userId) {
         return mUserFileManager
                 .getSharedPreferences(TILES, 0, userId)
@@ -593,6 +570,7 @@
      * @param userId the user for this tile
      * @param added {@code true} if the tile is being added, {@code false} otherwise
      */
+    @Override
     public void setTileAdded(ComponentName componentName, int userId, boolean added) {
         mUserFileManager.getSharedPreferences(TILES, 0, userId)
                 .edit()
@@ -600,6 +578,11 @@
                 .apply();
     }
 
+    @Override
+    public List<String> getSpecs() {
+        return mTileSpecs;
+    }
+
     protected static List<String> loadTileSpecs(Context context, String tileList) {
         final Resources res = context.getResources();
 
@@ -617,7 +600,7 @@
             if (tile.isEmpty()) continue;
             if (tile.equals("default")) {
                 if (!addedDefault) {
-                    List<String> defaultSpecs = getDefaultSpecs(context);
+                    List<String> defaultSpecs = QSHost.getDefaultSpecs(context);
                     for (String spec : defaultSpecs) {
                         if (!addedSpecs.contains(spec)) {
                             tiles.add(spec);
@@ -650,25 +633,6 @@
         return tiles;
     }
 
-    /**
-     * Returns the default QS tiles for the context.
-     * @param context the context to obtain the resources from
-     * @return a list of specs of the default tiles
-     */
-    public static List<String> getDefaultSpecs(Context context) {
-        final ArrayList<String> tiles = new ArrayList<String>();
-
-        final Resources res = context.getResources();
-        final String defaultTileList = res.getString(R.string.quick_settings_tiles_default);
-
-        tiles.addAll(Arrays.asList(defaultTileList.split(",")));
-        if (Build.IS_DEBUGGABLE
-                && GarbageMonitor.ADD_MEMORY_TILE_TO_DEFAULT_ON_DEBUGGABLE_BUILDS) {
-            tiles.add(GarbageMonitor.MemoryTile.TILE_SPEC);
-        }
-        return tiles;
-    }
-
     @Override
     public void dump(PrintWriter pw, String[] args) {
         pw.println("QSTileHost:");
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
index 6aabe3b..2d54313 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
@@ -48,7 +48,7 @@
     private final Provider<Boolean> mUsingCollapsedLandscapeMediaProvider;
 
     @Inject
-    QuickQSPanelController(QuickQSPanel view, QSTileHost qsTileHost,
+    QuickQSPanelController(QuickQSPanel view, QSHost qsHost,
             QSCustomizerController qsCustomizerController,
             @Named(QS_USING_MEDIA_PLAYER) boolean usingMediaPlayer,
             @Named(QUICK_QS_PANEL) MediaHost mediaHost,
@@ -57,7 +57,7 @@
             MetricsLogger metricsLogger, UiEventLogger uiEventLogger, QSLogger qsLogger,
             DumpManager dumpManager
     ) {
-        super(view, qsTileHost, qsCustomizerController, usingMediaPlayer, mediaHost, metricsLogger,
+        super(view, qsHost, qsCustomizerController, usingMediaPlayer, mediaHost, metricsLogger,
                 uiEventLogger, qsLogger, dumpManager);
         mUsingCollapsedLandscapeMediaProvider = usingCollapsedLandscapeMediaProvider;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 946fe54..691a1a1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -20,35 +20,15 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.graphics.Color;
-import android.graphics.Rect;
 import android.util.AttributeSet;
-import android.util.Pair;
-import android.view.DisplayCutout;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.WindowInsets;
 import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.Space;
 
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.internal.policy.SystemBarUtils;
-import com.android.settingslib.Utils;
 import com.android.systemui.R;
-import com.android.systemui.battery.BatteryMeterView;
-import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider;
-import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
-import com.android.systemui.statusbar.phone.StatusIconContainer;
-import com.android.systemui.statusbar.policy.Clock;
-import com.android.systemui.statusbar.policy.VariableDateView;
 import com.android.systemui.util.LargeScreenUtils;
 
-import java.util.List;
-
 /**
  * View that contains the top-most bits of the QS panel (primarily the status bar with date, time,
  * battery, carrier info and privacy icons) and also contains the {@link QuickQSPanel}.
@@ -58,184 +38,30 @@
     private boolean mExpanded;
     private boolean mQsDisabled;
 
-    @Nullable
-    private TouchAnimator mAlphaAnimator;
-    @Nullable
-    private TouchAnimator mTranslationAnimator;
-    @Nullable
-    private TouchAnimator mIconsAlphaAnimator;
-    private TouchAnimator mIconsAlphaAnimatorFixed;
-
     protected QuickQSPanel mHeaderQsPanel;
-    private View mDatePrivacyView;
-    private View mDateView;
-    // DateView next to clock. Visible on QQS
-    private VariableDateView mClockDateView;
-    private View mStatusIconsView;
-    private View mContainer;
-
-    private View mQSCarriers;
-    private ViewGroup mClockContainer;
-    private Clock mClockView;
-    private Space mDatePrivacySeparator;
-    private View mClockIconsSeparator;
-    private boolean mShowClockIconsSeparator;
-    private View mRightLayout;
-    private View mDateContainer;
-    private View mPrivacyContainer;
-
-    private BatteryMeterView mBatteryRemainingIcon;
-    private StatusIconContainer mIconContainer;
-    private View mPrivacyChip;
-
-    @Nullable
-    private TintedIconManager mTintedIconManager;
-    @Nullable
-    private QSExpansionPathInterpolator mQSExpansionPathInterpolator;
-    private StatusBarContentInsetsProvider mInsetsProvider;
-
-    private int mRoundedCornerPadding = 0;
-    private int mWaterfallTopInset;
-    private int mCutOutPaddingLeft;
-    private int mCutOutPaddingRight;
-    private float mKeyguardExpansionFraction;
-    private int mTextColorPrimary = Color.TRANSPARENT;
-    private int mTopViewMeasureHeight;
-
-    @NonNull
-    private List<String> mRssiIgnoredSlots = List.of();
-    private boolean mIsSingleCarrier;
-
-    private boolean mHasCenterCutout;
-    private boolean mConfigShowBatteryEstimate;
-
-    private boolean mUseCombinedQSHeader;
 
     public QuickStatusBarHeader(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
-    /**
-     * How much the view containing the clock and QQS will translate down when QS is fully expanded.
-     *
-     * This matches the measured height of the view containing the date and privacy icons.
-     */
-    public int getOffsetTranslation() {
-        return mTopViewMeasureHeight;
-    }
-
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-
         mHeaderQsPanel = findViewById(R.id.quick_qs_panel);
-        mDatePrivacyView = findViewById(R.id.quick_status_bar_date_privacy);
-        mStatusIconsView = findViewById(R.id.quick_qs_status_icons);
-        mQSCarriers = findViewById(R.id.carrier_group);
-        mContainer = findViewById(R.id.qs_container);
-        mIconContainer = findViewById(R.id.statusIcons);
-        mPrivacyChip = findViewById(R.id.privacy_chip);
-        mDateView = findViewById(R.id.date);
-        mClockDateView = findViewById(R.id.date_clock);
-        mClockIconsSeparator = findViewById(R.id.separator);
-        mRightLayout = findViewById(R.id.rightLayout);
-        mDateContainer = findViewById(R.id.date_container);
-        mPrivacyContainer = findViewById(R.id.privacy_container);
-
-        mClockContainer = findViewById(R.id.clock_container);
-        mClockView = findViewById(R.id.clock);
-        mDatePrivacySeparator = findViewById(R.id.space);
-        // Tint for the battery icons are handled in setupHost()
-        mBatteryRemainingIcon = findViewById(R.id.batteryRemainingIcon);
 
         updateResources();
-        Configuration config = mContext.getResources().getConfiguration();
-        setDatePrivacyContainersWidth(config.orientation == Configuration.ORIENTATION_LANDSCAPE);
-
-        // QS will always show the estimate, and BatteryMeterView handles the case where
-        // it's unavailable or charging
-        mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
-
-        mIconsAlphaAnimatorFixed = new TouchAnimator.Builder()
-                .addFloat(mIconContainer, "alpha", 0, 1)
-                .addFloat(mBatteryRemainingIcon, "alpha", 0, 1)
-                .build();
-    }
-
-    void onAttach(TintedIconManager iconManager,
-            QSExpansionPathInterpolator qsExpansionPathInterpolator,
-            List<String> rssiIgnoredSlots,
-            StatusBarContentInsetsProvider insetsProvider,
-            boolean useCombinedQSHeader) {
-        mUseCombinedQSHeader = useCombinedQSHeader;
-        mTintedIconManager = iconManager;
-        mRssiIgnoredSlots = rssiIgnoredSlots;
-        mInsetsProvider = insetsProvider;
-        int fillColor = Utils.getColorAttrDefaultColor(getContext(),
-                android.R.attr.textColorPrimary);
-
-        // Set the correct tint for the status icons so they contrast
-        iconManager.setTint(fillColor);
-
-        mQSExpansionPathInterpolator = qsExpansionPathInterpolator;
-        updateAnimators();
-    }
-
-    void setIsSingleCarrier(boolean isSingleCarrier) {
-        mIsSingleCarrier = isSingleCarrier;
-        updateAlphaAnimator();
-    }
-
-    public QuickQSPanel getHeaderQsPanel() {
-        return mHeaderQsPanel;
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        if (mDatePrivacyView.getMeasuredHeight() != mTopViewMeasureHeight) {
-            mTopViewMeasureHeight = mDatePrivacyView.getMeasuredHeight();
-            post(this::updateAnimators);
-        }
     }
 
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
         updateResources();
-        setDatePrivacyContainersWidth(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE);
-    }
-
-    @Override
-    public void onRtlPropertiesChanged(int layoutDirection) {
-        super.onRtlPropertiesChanged(layoutDirection);
-        updateResources();
-    }
-
-    private void setDatePrivacyContainersWidth(boolean landscape) {
-        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mDateContainer.getLayoutParams();
-        lp.width = landscape ? WRAP_CONTENT : 0;
-        lp.weight = landscape ? 0f : 1f;
-        mDateContainer.setLayoutParams(lp);
-
-        lp = (LinearLayout.LayoutParams) mPrivacyContainer.getLayoutParams();
-        lp.width = landscape ? WRAP_CONTENT : 0;
-        lp.weight = landscape ? 0f : 1f;
-        mPrivacyContainer.setLayoutParams(lp);
-    }
-
-    private void updateBatteryMode() {
-        if (mConfigShowBatteryEstimate && !mHasCenterCutout) {
-            mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
-        } else {
-            mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ON);
-        }
     }
 
     @Override
     public boolean onTouchEvent(MotionEvent event) {
-        // If using combined headers, only react to touches inside QuickQSPanel
-        if (!mUseCombinedQSHeader || event.getY() > mHeaderQsPanel.getTop()) {
+        // Only react to touches inside QuickQSPanel
+        if (event.getY() > mHeaderQsPanel.getTop()) {
             return super.onTouchEvent(event);
         } else {
             return false;
@@ -247,193 +73,29 @@
         boolean largeScreenHeaderActive =
                 LargeScreenUtils.shouldUseLargeScreenShadeHeader(resources);
 
-        boolean gone = largeScreenHeaderActive || mUseCombinedQSHeader || mQsDisabled;
-        mStatusIconsView.setVisibility(gone ? View.GONE : View.VISIBLE);
-        mDatePrivacyView.setVisibility(gone ? View.GONE : View.VISIBLE);
-
-        mConfigShowBatteryEstimate = resources.getBoolean(R.bool.config_showBatteryEstimateQSBH);
-
-        mRoundedCornerPadding = resources.getDimensionPixelSize(
-                R.dimen.rounded_corner_content_padding);
-
-        int qsOffsetHeight = SystemBarUtils.getQuickQsOffsetHeight(mContext);
-
-        mDatePrivacyView.getLayoutParams().height =
-                Math.max(qsOffsetHeight, mDatePrivacyView.getMinimumHeight());
-        mDatePrivacyView.setLayoutParams(mDatePrivacyView.getLayoutParams());
-
-        mStatusIconsView.getLayoutParams().height =
-                Math.max(qsOffsetHeight, mStatusIconsView.getMinimumHeight());
-        mStatusIconsView.setLayoutParams(mStatusIconsView.getLayoutParams());
-
         ViewGroup.LayoutParams lp = getLayoutParams();
         if (mQsDisabled) {
-            lp.height = mStatusIconsView.getLayoutParams().height;
+            lp.height = 0;
         } else {
             lp.height = WRAP_CONTENT;
         }
         setLayoutParams(lp);
 
-        int textColor = Utils.getColorAttrDefaultColor(mContext, android.R.attr.textColorPrimary);
-        if (textColor != mTextColorPrimary) {
-            int textColorSecondary = Utils.getColorAttrDefaultColor(mContext,
-                    android.R.attr.textColorSecondary);
-            mTextColorPrimary = textColor;
-            mClockView.setTextColor(textColor);
-            if (mTintedIconManager != null) {
-                mTintedIconManager.setTint(textColor);
-            }
-            mBatteryRemainingIcon.updateColors(mTextColorPrimary, textColorSecondary,
-                    mTextColorPrimary);
-        }
-
         MarginLayoutParams qqsLP = (MarginLayoutParams) mHeaderQsPanel.getLayoutParams();
         if (largeScreenHeaderActive) {
             qqsLP.topMargin = mContext.getResources()
                     .getDimensionPixelSize(R.dimen.qqs_layout_margin_top);
-        } else if (!mUseCombinedQSHeader) {
-            qqsLP.topMargin = qsOffsetHeight;
         } else {
             qqsLP.topMargin = mContext.getResources()
                     .getDimensionPixelSize(R.dimen.large_screen_shade_header_min_height);
         }
         mHeaderQsPanel.setLayoutParams(qqsLP);
-
-        updateBatteryMode();
-        updateHeadersPadding();
-        updateAnimators();
-
-        updateClockDatePadding();
     }
 
-    private void updateClockDatePadding() {
-        int startPadding = mContext.getResources()
-                .getDimensionPixelSize(R.dimen.status_bar_left_clock_starting_padding);
-        int endPadding = mContext.getResources()
-                .getDimensionPixelSize(R.dimen.status_bar_left_clock_end_padding);
-        mClockView.setPaddingRelative(
-                startPadding,
-                mClockView.getPaddingTop(),
-                endPadding,
-                mClockView.getPaddingBottom()
-        );
-
-        MarginLayoutParams lp = (MarginLayoutParams) mClockDateView.getLayoutParams();
-        lp.setMarginStart(endPadding);
-        mClockDateView.setLayoutParams(lp);
-    }
-
-    private void updateAnimators() {
-        if (mUseCombinedQSHeader) {
-            mTranslationAnimator = null;
-            return;
-        }
-        updateAlphaAnimator();
-        int offset = mTopViewMeasureHeight;
-
-        mTranslationAnimator = new TouchAnimator.Builder()
-                .addFloat(mContainer, "translationY", 0, offset)
-                .setInterpolator(mQSExpansionPathInterpolator != null
-                        ? mQSExpansionPathInterpolator.getYInterpolator()
-                        : null)
-                .build();
-    }
-
-    private void updateAlphaAnimator() {
-        if (mUseCombinedQSHeader) {
-            mAlphaAnimator = null;
-            return;
-        }
-        TouchAnimator.Builder builder = new TouchAnimator.Builder()
-                // These views appear on expanding down
-                .addFloat(mDateView, "alpha", 0, 0, 1)
-                .addFloat(mClockDateView, "alpha", 1, 0, 0)
-                .addFloat(mQSCarriers, "alpha", 0, 1)
-                .setListener(new TouchAnimator.ListenerAdapter() {
-                    @Override
-                    public void onAnimationAtEnd() {
-                        super.onAnimationAtEnd();
-                        if (!mIsSingleCarrier) {
-                            mIconContainer.addIgnoredSlots(mRssiIgnoredSlots);
-                        }
-                        // Make it gone so there's enough room for carrier names
-                        mClockDateView.setVisibility(View.GONE);
-                    }
-
-                    @Override
-                    public void onAnimationStarted() {
-                        mClockDateView.setVisibility(View.VISIBLE);
-                        mClockDateView.setFreezeSwitching(true);
-                        setSeparatorVisibility(false);
-                        if (!mIsSingleCarrier) {
-                            mIconContainer.addIgnoredSlots(mRssiIgnoredSlots);
-                        }
-                    }
-
-                    @Override
-                    public void onAnimationAtStart() {
-                        super.onAnimationAtStart();
-                        mClockDateView.setFreezeSwitching(false);
-                        mClockDateView.setVisibility(View.VISIBLE);
-                        setSeparatorVisibility(mShowClockIconsSeparator);
-                        // In QQS we never ignore RSSI.
-                        mIconContainer.removeIgnoredSlots(mRssiIgnoredSlots);
-                    }
-                });
-        mAlphaAnimator = builder.build();
-    }
-
-    void setChipVisibility(boolean visibility) {
-        if (visibility) {
-            // Animates the icons and battery indicator from alpha 0 to 1, when the chip is visible
-            mIconsAlphaAnimator = mIconsAlphaAnimatorFixed;
-            mIconsAlphaAnimator.setPosition(mKeyguardExpansionFraction);
-        } else {
-            mIconsAlphaAnimator = null;
-            mIconContainer.setAlpha(1);
-            mBatteryRemainingIcon.setAlpha(1);
-        }
-
-    }
-
-    /** */
     public void setExpanded(boolean expanded, QuickQSPanelController quickQSPanelController) {
         if (mExpanded == expanded) return;
         mExpanded = expanded;
         quickQSPanelController.setExpanded(expanded);
-        updateEverything();
-    }
-
-    /**
-     * Animates the inner contents based on the given expansion details.
-     *
-     * @param forceExpanded whether we should show the state expanded forcibly
-     * @param expansionFraction how much the QS panel is expanded/pulled out (up to 1f)
-     * @param panelTranslationY how much the panel has physically moved down vertically (required
-     *                          for keyguard animations only)
-     */
-    public void setExpansion(boolean forceExpanded, float expansionFraction,
-                             float panelTranslationY) {
-        final float keyguardExpansionFraction = forceExpanded ? 1f : expansionFraction;
-
-        if (mAlphaAnimator != null) {
-            mAlphaAnimator.setPosition(keyguardExpansionFraction);
-        }
-        if (mTranslationAnimator != null) {
-            mTranslationAnimator.setPosition(keyguardExpansionFraction);
-        }
-        if (mIconsAlphaAnimator != null) {
-            mIconsAlphaAnimator.setPosition(keyguardExpansionFraction);
-        }
-        // If forceExpanded (we are opening QS from lockscreen), the animators have been set to
-        // position = 1f.
-        if (forceExpanded) {
-            setAlpha(expansionFraction);
-        } else {
-            setAlpha(1);
-        }
-
-        mKeyguardExpansionFraction = keyguardExpansionFraction;
     }
 
     public void disable(int state1, int state2, boolean animate) {
@@ -441,133 +103,13 @@
         if (disabled == mQsDisabled) return;
         mQsDisabled = disabled;
         mHeaderQsPanel.setDisabledByPolicy(disabled);
-        mStatusIconsView.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
         updateResources();
     }
 
-    @Override
-    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        // Handle padding of the views
-        DisplayCutout cutout = insets.getDisplayCutout();
-
-        Pair<Integer, Integer> sbInsets = mInsetsProvider
-                .getStatusBarContentInsetsForCurrentRotation();
-        boolean hasCornerCutout = mInsetsProvider.currentRotationHasCornerCutout();
-
-        mDatePrivacyView.setPadding(sbInsets.first, 0, sbInsets.second, 0);
-        mStatusIconsView.setPadding(sbInsets.first, 0, sbInsets.second, 0);
-        LinearLayout.LayoutParams datePrivacySeparatorLayoutParams =
-                (LinearLayout.LayoutParams) mDatePrivacySeparator.getLayoutParams();
-        LinearLayout.LayoutParams mClockIconsSeparatorLayoutParams =
-                (LinearLayout.LayoutParams) mClockIconsSeparator.getLayoutParams();
-        if (cutout != null) {
-            Rect topCutout = cutout.getBoundingRectTop();
-            if (topCutout.isEmpty() || hasCornerCutout) {
-                datePrivacySeparatorLayoutParams.width = 0;
-                mDatePrivacySeparator.setVisibility(View.GONE);
-                mClockIconsSeparatorLayoutParams.width = 0;
-                setSeparatorVisibility(false);
-                mShowClockIconsSeparator = false;
-                mHasCenterCutout = false;
-            } else {
-                datePrivacySeparatorLayoutParams.width = topCutout.width();
-                mDatePrivacySeparator.setVisibility(View.VISIBLE);
-                mClockIconsSeparatorLayoutParams.width = topCutout.width();
-                mShowClockIconsSeparator = true;
-                setSeparatorVisibility(mKeyguardExpansionFraction == 0f);
-                mHasCenterCutout = true;
-            }
-        }
-        mDatePrivacySeparator.setLayoutParams(datePrivacySeparatorLayoutParams);
-        mClockIconsSeparator.setLayoutParams(mClockIconsSeparatorLayoutParams);
-        mCutOutPaddingLeft = sbInsets.first;
-        mCutOutPaddingRight = sbInsets.second;
-        mWaterfallTopInset = cutout == null ? 0 : cutout.getWaterfallInsets().top;
-
-        updateBatteryMode();
-        updateHeadersPadding();
-        return super.onApplyWindowInsets(insets);
-    }
-
-    /**
-     * Sets the visibility of the separator between clock and icons.
-     *
-     * This separator is "visible" when there is a center cutout, to block that space. In that
-     * case, the clock and the layout on the right (containing the icons and the battery meter) are
-     * set to weight 1 to take the available space.
-     * @param visible whether the separator between clock and icons should be visible.
-     */
-    private void setSeparatorVisibility(boolean visible) {
-        int newVisibility = visible ? View.VISIBLE : View.GONE;
-        if (mClockIconsSeparator.getVisibility() == newVisibility) return;
-
-        mClockIconsSeparator.setVisibility(visible ? View.VISIBLE : View.GONE);
-        mQSCarriers.setVisibility(visible ? View.GONE : View.VISIBLE);
-
-        LinearLayout.LayoutParams lp =
-                (LinearLayout.LayoutParams) mClockContainer.getLayoutParams();
-        lp.width = visible ? 0 : WRAP_CONTENT;
-        lp.weight = visible ? 1f : 0f;
-        mClockContainer.setLayoutParams(lp);
-
-        lp = (LinearLayout.LayoutParams) mRightLayout.getLayoutParams();
-        lp.width = visible ? 0 : WRAP_CONTENT;
-        lp.weight = visible ? 1f : 0f;
-        mRightLayout.setLayoutParams(lp);
-    }
-
-    private void updateHeadersPadding() {
-        setContentMargins(mDatePrivacyView, 0, 0);
-        setContentMargins(mStatusIconsView, 0, 0);
-        int paddingLeft = 0;
-        int paddingRight = 0;
-
-        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
-        int leftMargin = lp.leftMargin;
-        int rightMargin = lp.rightMargin;
-
-        // The clock might collide with cutouts, let's shift it out of the way.
-        // We only do that if the inset is bigger than our own padding, since it's nicer to
-        // align with
-        if (mCutOutPaddingLeft > 0) {
-            // if there's a cutout, let's use at least the rounded corner inset
-            int cutoutPadding = Math.max(mCutOutPaddingLeft, mRoundedCornerPadding);
-            paddingLeft = Math.max(cutoutPadding - leftMargin, 0);
-        }
-        if (mCutOutPaddingRight > 0) {
-            // if there's a cutout, let's use at least the rounded corner inset
-            int cutoutPadding = Math.max(mCutOutPaddingRight, mRoundedCornerPadding);
-            paddingRight = Math.max(cutoutPadding - rightMargin, 0);
-        }
-
-        mDatePrivacyView.setPadding(paddingLeft,
-                mWaterfallTopInset,
-                paddingRight,
-                0);
-        mStatusIconsView.setPadding(paddingLeft,
-                mWaterfallTopInset,
-                paddingRight,
-                0);
-    }
-
-    public void updateEverything() {
-        post(() -> setClickable(!mExpanded));
-    }
-
     private void setContentMargins(View view, int marginStart, int marginEnd) {
         MarginLayoutParams lp = (MarginLayoutParams) view.getLayoutParams();
         lp.setMarginStart(marginStart);
         lp.setMarginEnd(marginEnd);
         view.setLayoutParams(lp);
     }
-
-    /**
-     * Scroll the headers away.
-     *
-     * @param scrollY the scroll of the QSPanel container
-     */
-    public void setExpandedScrollAmount(int scrollY) {
-        mStatusIconsView.setScrollY(scrollY);
-        mDatePrivacyView.setScrollY(scrollY);
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
index ccaab1a..64960e6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
@@ -16,154 +16,38 @@
 
 package com.android.systemui.qs;
 
-import android.os.Bundle;
-
-import com.android.internal.colorextraction.ColorExtractor;
-import com.android.systemui.R;
-import com.android.systemui.battery.BatteryMeterViewController;
-import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.demomode.DemoMode;
-import com.android.systemui.demomode.DemoModeController;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
-import com.android.systemui.qs.carrier.QSCarrierGroupController;
 import com.android.systemui.qs.dagger.QSScope;
-import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider;
-import com.android.systemui.statusbar.phone.StatusBarIconController;
-import com.android.systemui.statusbar.phone.StatusBarLocation;
-import com.android.systemui.statusbar.phone.StatusIconContainer;
-import com.android.systemui.statusbar.policy.Clock;
-import com.android.systemui.statusbar.policy.VariableDateViewController;
 import com.android.systemui.util.ViewController;
 
-import java.util.List;
-
 import javax.inject.Inject;
 
 /**
  * Controller for {@link QuickStatusBarHeader}.
  */
 @QSScope
-class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader> implements
-        ChipVisibilityListener {
+class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader> {
 
-    private final QSCarrierGroupController mQSCarrierGroupController;
     private final QuickQSPanelController mQuickQSPanelController;
-    private final Clock mClockView;
-    private final StatusBarIconController mStatusBarIconController;
-    private final DemoModeController mDemoModeController;
-    private final StatusIconContainer mIconContainer;
-    private final StatusBarIconController.TintedIconManager mIconManager;
-    private final DemoMode mDemoModeReceiver;
-    private final QSExpansionPathInterpolator mQSExpansionPathInterpolator;
-    private final FeatureFlags mFeatureFlags;
-    private final BatteryMeterViewController mBatteryMeterViewController;
-    private final StatusBarContentInsetsProvider mInsetsProvider;
-
-    private final VariableDateViewController mVariableDateViewControllerDateView;
-    private final VariableDateViewController mVariableDateViewControllerClockDateView;
-    private final HeaderPrivacyIconsController mPrivacyIconsController;
-
     private boolean mListening;
 
-    private SysuiColorExtractor mColorExtractor;
-    private ColorExtractor.OnColorsChangedListener mOnColorsChangedListener;
-
     @Inject
     QuickStatusBarHeaderController(QuickStatusBarHeader view,
-            HeaderPrivacyIconsController headerPrivacyIconsController,
-            StatusBarIconController statusBarIconController,
-            DemoModeController demoModeController,
-            QuickQSPanelController quickQSPanelController,
-            QSCarrierGroupController.Builder qsCarrierGroupControllerBuilder,
-            SysuiColorExtractor colorExtractor,
-            QSExpansionPathInterpolator qsExpansionPathInterpolator,
-            FeatureFlags featureFlags,
-            VariableDateViewController.Factory variableDateViewControllerFactory,
-            BatteryMeterViewController batteryMeterViewController,
-            StatusBarContentInsetsProvider statusBarContentInsetsProvider,
-            StatusBarIconController.TintedIconManager.Factory tintedIconManagerFactory) {
+            QuickQSPanelController quickQSPanelController
+    ) {
         super(view);
-        mPrivacyIconsController = headerPrivacyIconsController;
-        mStatusBarIconController = statusBarIconController;
-        mDemoModeController = demoModeController;
         mQuickQSPanelController = quickQSPanelController;
-        mQSExpansionPathInterpolator = qsExpansionPathInterpolator;
-        mFeatureFlags = featureFlags;
-        mBatteryMeterViewController = batteryMeterViewController;
-        mInsetsProvider = statusBarContentInsetsProvider;
-
-        mQSCarrierGroupController = qsCarrierGroupControllerBuilder
-                .setQSCarrierGroup(mView.findViewById(R.id.carrier_group))
-                .build();
-        mClockView = mView.findViewById(R.id.clock);
-        mIconContainer = mView.findViewById(R.id.statusIcons);
-        mVariableDateViewControllerDateView = variableDateViewControllerFactory.create(
-                mView.requireViewById(R.id.date)
-        );
-        mVariableDateViewControllerClockDateView = variableDateViewControllerFactory.create(
-                mView.requireViewById(R.id.date_clock)
-        );
-
-        mIconManager = tintedIconManagerFactory.create(mIconContainer, StatusBarLocation.QS);
-        mDemoModeReceiver = new ClockDemoModeReceiver(mClockView);
-        mColorExtractor = colorExtractor;
-        mOnColorsChangedListener = (extractor, which) -> {
-            final boolean lightTheme = mColorExtractor.getNeutralColors().supportsDarkText();
-            mClockView.onColorsChanged(lightTheme);
-        };
-        mColorExtractor.addOnColorsChangedListener(mOnColorsChangedListener);
-
-        // Don't need to worry about tuner settings for this icon
-        mBatteryMeterViewController.ignoreTunerUpdates();
-    }
-
-    @Override
-    protected void onInit() {
-        mBatteryMeterViewController.init();
     }
 
     @Override
     protected void onViewAttached() {
-        mPrivacyIconsController.onParentVisible();
-        mPrivacyIconsController.setChipVisibilityListener(this);
-        mIconContainer.addIgnoredSlot(
-                getResources().getString(com.android.internal.R.string.status_bar_managed_profile));
-        mIconContainer.addIgnoredSlot(
-                getResources().getString(com.android.internal.R.string.status_bar_alarm_clock));
-        mIconContainer.setShouldRestrictIcons(false);
-        mStatusBarIconController.addIconGroup(mIconManager);
-
-        mView.setIsSingleCarrier(mQSCarrierGroupController.isSingleCarrier());
-        mQSCarrierGroupController
-                .setOnSingleCarrierChangedListener(mView::setIsSingleCarrier);
-
-        List<String> rssiIgnoredSlots = List.of(
-                getResources().getString(com.android.internal.R.string.status_bar_mobile)
-        );
-
-        mView.onAttach(mIconManager, mQSExpansionPathInterpolator, rssiIgnoredSlots,
-                mInsetsProvider, mFeatureFlags.isEnabled(Flags.COMBINED_QS_HEADERS));
-
-        mDemoModeController.addCallback(mDemoModeReceiver);
-
-        mVariableDateViewControllerDateView.init();
-        mVariableDateViewControllerClockDateView.init();
     }
 
     @Override
     protected void onViewDetached() {
-        mColorExtractor.removeOnColorsChangedListener(mOnColorsChangedListener);
-        mPrivacyIconsController.onParentInvisible();
-        mStatusBarIconController.removeIconGroup(mIconManager);
-        mQSCarrierGroupController.setOnSingleCarrierChangedListener(null);
-        mDemoModeController.removeCallback(mDemoModeReceiver);
         setListening(false);
     }
 
     public void setListening(boolean listening) {
-        mQSCarrierGroupController.setListening(listening);
-
         if (listening == mListening) {
             return;
         }
@@ -174,48 +58,9 @@
         if (mQuickQSPanelController.switchTileLayout(false)) {
             mView.updateResources();
         }
-
-        if (listening) {
-            mPrivacyIconsController.startListening();
-        } else {
-            mPrivacyIconsController.stopListening();
-        }
-    }
-
-    @Override
-    public void onChipVisibilityRefreshed(boolean visible) {
-        mView.setChipVisibility(visible);
     }
 
     public void setContentMargins(int marginStart, int marginEnd) {
         mQuickQSPanelController.setContentMargins(marginStart, marginEnd);
     }
-
-    private static class ClockDemoModeReceiver implements DemoMode {
-        private Clock mClockView;
-
-        @Override
-        public List<String> demoCommands() {
-            return List.of(COMMAND_CLOCK);
-        }
-
-        ClockDemoModeReceiver(Clock clockView) {
-            mClockView = clockView;
-        }
-
-        @Override
-        public void dispatchDemoCommand(String command, Bundle args) {
-            mClockView.dispatchDemoCommand(command, args);
-        }
-
-        @Override
-        public void onDemoModeStarted() {
-            mClockView.onDemoModeStarted();
-        }
-
-        @Override
-        public void onDemoModeFinished() {
-            mClockView.onDemoModeFinished();
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java
index 9739011..a319fb8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java
@@ -40,7 +40,7 @@
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.qs.QSEditEvent;
 import com.android.systemui.qs.QSFragment;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.dagger.QSScope;
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -57,7 +57,7 @@
 @QSScope
 public class QSCustomizerController extends ViewController<QSCustomizer> {
     private final TileQueryHelper mTileQueryHelper;
-    private final QSTileHost mQsTileHost;
+    private final QSHost mQsHost;
     private final TileAdapter mTileAdapter;
     private final ScreenLifecycle mScreenLifecycle;
     private final KeyguardStateController mKeyguardStateController;
@@ -104,12 +104,12 @@
 
     @Inject
     protected QSCustomizerController(QSCustomizer view, TileQueryHelper tileQueryHelper,
-            QSTileHost qsTileHost, TileAdapter tileAdapter, ScreenLifecycle screenLifecycle,
+            QSHost qsHost, TileAdapter tileAdapter, ScreenLifecycle screenLifecycle,
             KeyguardStateController keyguardStateController, LightBarController lightBarController,
             ConfigurationController configurationController, UiEventLogger uiEventLogger) {
         super(view);
         mTileQueryHelper = tileQueryHelper;
-        mQsTileHost = qsTileHost;
+        mQsHost = qsHost;
         mTileAdapter = tileAdapter;
         mScreenLifecycle = screenLifecycle;
         mKeyguardStateController = keyguardStateController;
@@ -175,7 +175,7 @@
 
 
     private void reset() {
-        mTileAdapter.resetTileSpecs(QSTileHost.getDefaultSpecs(getContext()));
+        mTileAdapter.resetTileSpecs(QSHost.getDefaultSpecs(getContext()));
     }
 
     public boolean isCustomizing() {
@@ -192,7 +192,7 @@
                 mView.show(x, y, mTileAdapter);
                 mUiEventLogger.log(QSEditEvent.QS_EDIT_OPEN);
             }
-            mTileQueryHelper.queryTiles(mQsTileHost);
+            mTileQueryHelper.queryTiles(mQsHost);
             mKeyguardStateController.addCallback(mKeyguardCallback);
             mView.updateNavColors(mLightBarController);
         }
@@ -258,13 +258,13 @@
 
     private void save() {
         if (mTileQueryHelper.isFinished()) {
-            mTileAdapter.saveSpecs(mQsTileHost);
+            mTileAdapter.saveSpecs(mQsHost);
         }
     }
 
     private void setTileSpecs() {
         List<String> specs = new ArrayList<>();
-        for (QSTile tile : mQsTileHost.getTiles()) {
+        for (QSTile tile : mQsHost.getTiles()) {
             specs.add(tile.getTileSpec());
         }
         mTileAdapter.setTileSpecs(specs);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index d84b12c..6a05684 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -45,7 +45,7 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSEditEvent;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.customize.TileAdapter.Holder;
 import com.android.systemui.qs.customize.TileQueryHelper.TileInfo;
 import com.android.systemui.qs.customize.TileQueryHelper.TileStateListener;
@@ -91,7 +91,7 @@
     private ItemDecoration mDecoration;
     private final MarginTileDecoration mMarginDecoration;
     private final int mMinNumTiles;
-    private final QSTileHost mHost;
+    private final QSHost mHost;
     private int mEditIndex;
     private int mTileDividerIndex;
     private int mFocusIndex;
@@ -117,7 +117,7 @@
     @Inject
     public TileAdapter(
             @QSThemedContext Context context,
-            QSTileHost qsHost,
+            QSHost qsHost,
             UiEventLogger uiEventLogger) {
         mContext = context;
         mHost = qsHost;
@@ -176,7 +176,7 @@
         mMarginDecoration.setHalfMargin(halfMargin);
     }
 
-    public void saveSpecs(QSTileHost host) {
+    public void saveSpecs(QSHost host) {
         List<String> newSpecs = new ArrayList<>();
         clearAccessibilityState();
         for (int i = 1; i < mTiles.size() && mTiles.get(i) != null; i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index 32a7916..d9f4484 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -38,7 +38,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.qs.QSTile.State;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.dagger.QSScope;
 import com.android.systemui.qs.external.CustomTile;
 import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIcon;
@@ -85,7 +85,7 @@
         mListener = listener;
     }
 
-    public void queryTiles(QSTileHost host) {
+    public void queryTiles(QSHost host) {
         mTiles.clear();
         mSpecs.clear();
         mFinished = false;
@@ -97,7 +97,7 @@
         return mFinished;
     }
 
-    private void addCurrentAndStockTiles(QSTileHost host) {
+    private void addCurrentAndStockTiles(QSHost host) {
         String stock = mContext.getString(R.string.quick_settings_tiles_stock);
         String current = Settings.Secure.getString(mContext.getContentResolver(),
                 Settings.Secure.QS_TILES);
@@ -153,14 +153,14 @@
     private class TileCollector implements QSTile.Callback {
 
         private final List<TilePair> mQSTileList = new ArrayList<>();
-        private final QSTileHost mQSTileHost;
+        private final QSHost mQSHost;
 
-        TileCollector(List<QSTile> tilesToAdd, QSTileHost host) {
+        TileCollector(List<QSTile> tilesToAdd, QSHost host) {
             for (QSTile tile: tilesToAdd) {
                 TilePair pair = new TilePair(tile);
                 mQSTileList.add(pair);
             }
-            mQSTileHost = host;
+            mQSHost = host;
             if (tilesToAdd.isEmpty()) {
                 mBgExecutor.execute(this::finished);
             }
@@ -168,7 +168,7 @@
 
         private void finished() {
             notifyTilesChanged(false);
-            addPackageTiles(mQSTileHost);
+            addPackageTiles(mQSHost);
         }
 
         private void startListening() {
@@ -207,7 +207,7 @@
         }
     }
 
-    private void addPackageTiles(final QSTileHost host) {
+    private void addPackageTiles(final QSHost host) {
         mBgExecutor.execute(() -> {
             Collection<QSTile> params = host.getTiles();
             PackageManager pm = mContext.getPackageManager();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
index 01eb636..ce6b8d4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
@@ -24,10 +24,8 @@
 import android.view.View;
 
 import com.android.systemui.R;
-import com.android.systemui.battery.BatteryMeterView;
 import com.android.systemui.dagger.qualifiers.RootView;
 import com.android.systemui.plugins.qs.QS;
-import com.android.systemui.privacy.OngoingPrivacyChip;
 import com.android.systemui.qs.QSContainerImpl;
 import com.android.systemui.qs.QSFooter;
 import com.android.systemui.qs.QSFooterView;
@@ -37,7 +35,6 @@
 import com.android.systemui.qs.QuickQSPanel;
 import com.android.systemui.qs.QuickStatusBarHeader;
 import com.android.systemui.qs.customize.QSCustomizer;
-import com.android.systemui.statusbar.phone.StatusIconContainer;
 
 import javax.inject.Named;
 
@@ -106,12 +103,6 @@
 
     /** */
     @Provides
-    static BatteryMeterView providesBatteryMeterView(QuickStatusBarHeader quickStatusBarHeader) {
-        return quickStatusBarHeader.findViewById(R.id.batteryRemainingIcon);
-    }
-
-    /** */
-    @Provides
     static QSFooterView providesQSFooterView(@RootView View view) {
         return view.findViewById(R.id.qs_footer);
     }
@@ -144,18 +135,4 @@
     static boolean providesQSUsingCollapsedLandscapeMedia(Context context) {
         return useCollapsedMediaInLandscape(context.getResources());
     }
-
-    /** */
-    @Provides
-    @QSScope
-    static OngoingPrivacyChip providesPrivacyChip(QuickStatusBarHeader qsHeader) {
-        return qsHeader.findViewById(R.id.privacy_chip);
-    }
-
-    /** */
-    @Provides
-    @QSScope
-    static StatusIconContainer providesStatusIconContainer(QuickStatusBarHeader qsHeader) {
-        return qsHeader.findViewById(R.id.statusIcons);
-    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
index 27ae171..431d6e8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
@@ -67,7 +67,7 @@
     static AutoTileManager provideAutoTileManager(
             Context context,
             AutoAddTracker.Builder autoAddTrackerBuilder,
-            QSTileHost host,
+            QSHost host,
             @Background Handler handler,
             SecureSettings secureSettings,
             HotspotController hotspotController,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt
index 237b66e..d9e5580 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt
@@ -25,13 +25,13 @@
 import android.util.Log
 import androidx.annotation.VisibleForTesting
 import com.android.internal.statusbar.IAddTileResultCallback
+import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.qs.QSTileHost
+import com.android.systemui.qs.QSHost
+import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.commandline.Command
 import com.android.systemui.statusbar.commandline.CommandRegistry
 import com.android.systemui.statusbar.phone.SystemUIDialog
-import com.android.systemui.R
-import com.android.systemui.statusbar.CommandQueue
 import java.io.PrintWriter
 import java.util.concurrent.atomic.AtomicBoolean
 import java.util.function.Consumer
@@ -40,14 +40,14 @@
 private const val TAG = "TileServiceRequestController"
 
 /**
- * Controller to interface between [TileRequestDialog] and [QSTileHost].
+ * Controller to interface between [TileRequestDialog] and [QSHost].
  */
 class TileServiceRequestController constructor(
-    private val qsTileHost: QSTileHost,
+    private val qsHost: QSHost,
     private val commandQueue: CommandQueue,
     private val commandRegistry: CommandRegistry,
     private val eventLogger: TileRequestDialogEventLogger,
-    private val dialogCreator: () -> TileRequestDialog = { TileRequestDialog(qsTileHost.context) }
+    private val dialogCreator: () -> TileRequestDialog = { TileRequestDialog(qsHost.context) }
 ) {
 
     companion object {
@@ -93,7 +93,7 @@
     }
 
     private fun addTile(componentName: ComponentName) {
-        qsTileHost.addTile(componentName, true)
+        qsHost.addTile(componentName, true)
     }
 
     @VisibleForTesting
@@ -158,7 +158,7 @@
 
     private fun isTileAlreadyAdded(componentName: ComponentName): Boolean {
         val spec = CustomTile.toSpec(componentName)
-        return qsTileHost.indexOf(spec) != -1
+        return qsHost.indexOf(spec) != -1
     }
 
     inner class TileServiceRequestCommand : Command {
@@ -194,13 +194,13 @@
         private val commandQueue: CommandQueue,
         private val commandRegistry: CommandRegistry
     ) {
-        fun create(qsTileHost: QSTileHost): TileServiceRequestController {
+        fun create(qsHost: QSHost): TileServiceRequestController {
             return TileServiceRequestController(
-                    qsTileHost,
+                    qsHost,
                     commandQueue,
                     commandRegistry,
                     TileRequestDialogEventLogger()
             )
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
index 84a18d8..adc7165 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
@@ -39,7 +39,7 @@
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -68,22 +68,24 @@
     private final Context mContext;
     private final Handler mMainHandler;
     private final Provider<Handler> mHandlerProvider;
-    private final QSTileHost mHost;
+    private final QSHost mHost;
     private final KeyguardStateController mKeyguardStateController;
     private final BroadcastDispatcher mBroadcastDispatcher;
     private final CommandQueue mCommandQueue;
     private final UserTracker mUserTracker;
+    private final StatusBarIconController mStatusBarIconController;
 
     private int mMaxBound = DEFAULT_MAX_BOUND;
 
     @Inject
     public TileServices(
-            QSTileHost host,
+            QSHost host,
             @Main Provider<Handler> handlerProvider,
             BroadcastDispatcher broadcastDispatcher,
             UserTracker userTracker,
             KeyguardStateController keyguardStateController,
-            CommandQueue commandQueue) {
+            CommandQueue commandQueue,
+            StatusBarIconController statusBarIconController) {
         mHost = host;
         mKeyguardStateController = keyguardStateController;
         mContext = mHost.getContext();
@@ -92,6 +94,7 @@
         mMainHandler = mHandlerProvider.get();
         mUserTracker = userTracker;
         mCommandQueue = commandQueue;
+        mStatusBarIconController = statusBarIconController;
         mCommandQueue.addCallback(mRequestListeningCallback);
     }
 
@@ -99,7 +102,7 @@
         return mContext;
     }
 
-    public QSTileHost getHost() {
+    public QSHost getHost() {
         return mHost;
     }
 
@@ -131,8 +134,7 @@
             mTiles.remove(tile.getComponent());
             final String slot = tile.getComponent().getClassName();
             // TileServices doesn't know how to add more than 1 icon per slot, so remove all
-            mMainHandler.post(() -> mHost.getIconController()
-                    .removeAllIconsForExternalSlot(slot));
+            mMainHandler.post(() -> mStatusBarIconController.removeAllIconsForSlot(slot));
         }
     }
 
@@ -309,7 +311,7 @@
                     mMainHandler.post(new Runnable() {
                         @Override
                         public void run() {
-                            StatusBarIconController iconController = mHost.getIconController();
+                            StatusBarIconController iconController = mStatusBarIconController;
                             iconController.setIcon(componentName.getClassName(), statusIcon);
                             iconController.setExternalIcon(componentName.getClassName());
                         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
index d32ef32..23c41db 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
@@ -17,15 +17,14 @@
 package com.android.systemui.qs.logging
 
 import android.service.quicksettings.Tile
+import android.view.View
 import com.android.systemui.log.dagger.QSLog
 import com.android.systemui.plugins.log.ConstantStringsLogger
 import com.android.systemui.plugins.log.ConstantStringsLoggerImpl
 import com.android.systemui.plugins.log.LogBuffer
-import com.android.systemui.plugins.log.LogLevel
 import com.android.systemui.plugins.log.LogLevel.DEBUG
 import com.android.systemui.plugins.log.LogLevel.ERROR
 import com.android.systemui.plugins.log.LogLevel.VERBOSE
-import com.android.systemui.plugins.log.LogMessage
 import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.statusbar.StatusBarState
 import com.google.errorprone.annotations.CompileTimeConstant
@@ -332,4 +331,25 @@
             else -> "wrong state"
         }
     }
+
+    fun logVisibility(viewName: String, @View.Visibility visibility: Int) {
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = viewName
+                str2 = toVisibilityString(visibility)
+            },
+            { "$str1 visibility: $str2" }
+        )
+    }
+
+    private fun toVisibilityString(visibility: Int): String {
+        return when (visibility) {
+            View.VISIBLE -> "VISIBLE"
+            View.INVISIBLE -> "INVISIBLE"
+            View.GONE -> "GONE"
+            else -> "undefined"
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt
index 721046d..9b4ac1b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt
@@ -27,6 +27,8 @@
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.plugins.qs.QSTile
@@ -50,7 +52,8 @@
     activityStarter: ActivityStarter,
     qsLogger: QSLogger,
     private val dialogLaunchAnimator: DialogLaunchAnimator,
-    private val systemSettings: SystemSettings
+    private val systemSettings: SystemSettings,
+    private val featureFlags: FeatureFlags
 ) :
     QSTileImpl<QSTile.State?>(
         host,
@@ -65,7 +68,7 @@
     private val icon = ResourceIcon.get(R.drawable.ic_qs_font_scaling)
 
     override fun isAvailable(): Boolean {
-        return false
+        return featureFlags.isEnabled(Flags.ENABLE_FONT_SCALING_TILE)
     }
 
     override fun newTileState(): QSTile.State {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManager.kt b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManager.kt
index e360ec2..a78b0aa 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManager.kt
@@ -31,7 +31,7 @@
 
 /**
  * Contains all changes that need to be performed to the different [ConstraintSet] in
- * [LargeScreenShadeHeaderController].
+ * [ShadeHeaderController].
  */
 data class ConstraintsChanges(
     val qqsConstraintsChanges: ConstraintChange? = null,
@@ -46,7 +46,7 @@
 }
 
 /**
- * Determines [ConstraintChanges] for [LargeScreenShadeHeaderController] based on configurations.
+ * Determines [ConstraintChanges] for [ShadeHeaderController] based on configurations.
  *
  * Given that the number of different scenarios is not that large, having specific methods instead
  * of a full map between state and [ConstraintSet] was preferred.
diff --git a/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java b/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java
index ae303eb..fb2ddc1 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java
@@ -39,6 +39,7 @@
     private final NotificationPanelView mView;
     private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
     private final LockIconViewController mLockIconViewController;
+    private final QuickSettingsController mQsController;
     private final Set<Integer> mDebugTextUsedYPositions;
     private final Paint mDebugPaint;
 
@@ -46,12 +47,14 @@
             NotificationPanelViewController notificationPanelViewController,
             NotificationPanelView notificationPanelView,
             NotificationStackScrollLayoutController notificationStackScrollLayoutController,
-            LockIconViewController lockIconViewController
+            LockIconViewController lockIconViewController,
+            QuickSettingsController quickSettingsController
     ) {
         mNotificationPanelViewController = notificationPanelViewController;
         mView = notificationPanelView;
         mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
         mLockIconViewController = lockIconViewController;
+        mQsController = quickSettingsController;
         mDebugTextUsedYPositions = new HashSet<>();
         mDebugPaint = new Paint();
     }
@@ -71,12 +74,19 @@
                 Color.RED, "getMaxPanelHeight()");
         drawDebugInfo(canvas, (int) mNotificationPanelViewController.getExpandedHeight(),
                 Color.BLUE, "getExpandedHeight()");
-        drawDebugInfo(canvas, mNotificationPanelViewController.calculatePanelHeightQsExpanded(),
+        drawDebugInfo(canvas, mQsController.calculatePanelHeightExpanded(
+                        mNotificationPanelViewController.getClockPositionResult()
+                                .stackScrollerPadding),
                 Color.GREEN, "calculatePanelHeightQsExpanded()");
-        drawDebugInfo(canvas, mNotificationPanelViewController.calculatePanelHeightQsExpanded(),
+        drawDebugInfo(canvas, mQsController.calculatePanelHeightExpanded(
+                        mNotificationPanelViewController.getClockPositionResult()
+                                .stackScrollerPadding),
                 Color.YELLOW, "calculatePanelHeightShade()");
         drawDebugInfo(canvas,
-                (int) mNotificationPanelViewController.calculateNotificationsTopPadding(),
+                (int) mQsController.calculateNotificationsTopPadding(
+                        mNotificationPanelViewController.isExpanding(),
+                        mNotificationPanelViewController.getKeyguardNotificationStaticPadding(),
+                        mNotificationPanelViewController.getExpandedFraction()),
                 Color.MAGENTA, "calculateNotificationsTopPadding()");
         drawDebugInfo(canvas, mNotificationPanelViewController.getClockPositionResult().clockY,
                 Color.GRAY, "mClockPositionResult.clockY");
diff --git a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
deleted file mode 100644
index 197232e..0000000
--- a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
+++ /dev/null
@@ -1,569 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.shade
-
-import android.animation.Animator
-import android.annotation.IdRes
-import android.app.StatusBarManager
-import android.content.res.Configuration
-import android.os.Bundle
-import android.os.Trace
-import android.os.Trace.TRACE_TAG_APP
-import android.util.Pair
-import android.view.View
-import android.view.WindowInsets
-import android.widget.TextView
-import androidx.annotation.VisibleForTesting
-import androidx.constraintlayout.motion.widget.MotionLayout
-import com.android.settingslib.Utils
-import com.android.systemui.Dumpable
-import com.android.systemui.R
-import com.android.systemui.animation.Interpolators
-import com.android.systemui.animation.ShadeInterpolation
-import com.android.systemui.battery.BatteryMeterView
-import com.android.systemui.battery.BatteryMeterViewController
-import com.android.systemui.demomode.DemoMode
-import com.android.systemui.demomode.DemoModeController
-import com.android.systemui.dump.DumpManager
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
-import com.android.systemui.qs.ChipVisibilityListener
-import com.android.systemui.qs.HeaderPrivacyIconsController
-import com.android.systemui.qs.carrier.QSCarrierGroup
-import com.android.systemui.qs.carrier.QSCarrierGroupController
-import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.HEADER_TRANSITION_ID
-import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QQS_HEADER_CONSTRAINT
-import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QS_HEADER_CONSTRAINT
-import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
-import com.android.systemui.statusbar.phone.StatusBarIconController
-import com.android.systemui.statusbar.phone.StatusBarLocation
-import com.android.systemui.statusbar.phone.StatusIconContainer
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
-import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_BATTERY_CONTROLLER
-import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_SHADE_HEADER
-import com.android.systemui.statusbar.policy.Clock
-import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.statusbar.policy.VariableDateView
-import com.android.systemui.statusbar.policy.VariableDateViewController
-import com.android.systemui.util.ViewController
-import java.io.PrintWriter
-import javax.inject.Inject
-import javax.inject.Named
-
-/**
- * Controller for QS header on Large Screen width (large screen + landscape).
- *
- * Additionally, this serves as the staging ground for the combined QS headers. A single
- * [MotionLayout] that changes constraints depending on the configuration and can animate the
- * expansion of the headers in small screen portrait.
- *
- * [header] will be a [MotionLayout] if [Flags.COMBINED_QS_HEADERS] is enabled. In this case, the
- * [MotionLayout] has one transitions:
- * * [HEADER_TRANSITION_ID]: [QQS_HEADER_CONSTRAINT] <-> [QS_HEADER_CONSTRAINT] for portrait
- *   handheld device configuration.
- */
-@CentralSurfacesScope
-class LargeScreenShadeHeaderController @Inject constructor(
-    @Named(LARGE_SCREEN_SHADE_HEADER) private val header: View,
-    private val statusBarIconController: StatusBarIconController,
-    private val tintedIconManagerFactory: StatusBarIconController.TintedIconManager.Factory,
-    private val privacyIconsController: HeaderPrivacyIconsController,
-    private val insetsProvider: StatusBarContentInsetsProvider,
-    private val configurationController: ConfigurationController,
-    private val variableDateViewControllerFactory: VariableDateViewController.Factory,
-    @Named(LARGE_SCREEN_BATTERY_CONTROLLER)
-    private val batteryMeterViewController: BatteryMeterViewController,
-    private val dumpManager: DumpManager,
-    private val featureFlags: FeatureFlags,
-    private val qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder,
-    private val combinedShadeHeadersConstraintManager: CombinedShadeHeadersConstraintManager,
-    private val demoModeController: DemoModeController
-) : ViewController<View>(header), Dumpable {
-
-    companion object {
-        /** IDs for transitions and constraints for the [MotionLayout]. These are only used when
-         * [Flags.COMBINED_QS_HEADERS] is enabled.
-         */
-        @VisibleForTesting
-        internal val HEADER_TRANSITION_ID = R.id.header_transition
-        @VisibleForTesting
-        internal val LARGE_SCREEN_HEADER_TRANSITION_ID = R.id.large_screen_header_transition
-        @VisibleForTesting
-        internal val QQS_HEADER_CONSTRAINT = R.id.qqs_header_constraint
-        @VisibleForTesting
-        internal val QS_HEADER_CONSTRAINT = R.id.qs_header_constraint
-        @VisibleForTesting
-        internal val LARGE_SCREEN_HEADER_CONSTRAINT = R.id.large_screen_header_constraint
-
-        private fun Int.stateToString() = when (this) {
-            QQS_HEADER_CONSTRAINT -> "QQS Header"
-            QS_HEADER_CONSTRAINT -> "QS Header"
-            LARGE_SCREEN_HEADER_CONSTRAINT -> "Large Screen Header"
-            else -> "Unknown state $this"
-        }
-    }
-
-    private val combinedHeaders = featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)
-
-    private lateinit var iconManager: StatusBarIconController.TintedIconManager
-    private lateinit var carrierIconSlots: List<String>
-    private lateinit var qsCarrierGroupController: QSCarrierGroupController
-
-    private val batteryIcon: BatteryMeterView = header.findViewById(R.id.batteryRemainingIcon)
-    private val clock: Clock = header.findViewById(R.id.clock)
-    private val date: TextView = header.findViewById(R.id.date)
-    private val iconContainer: StatusIconContainer = header.findViewById(R.id.statusIcons)
-    private val qsCarrierGroup: QSCarrierGroup = header.findViewById(R.id.carrier_group)
-
-    private var cutoutLeft = 0
-    private var cutoutRight = 0
-    private var roundedCorners = 0
-    private var lastInsets: WindowInsets? = null
-
-    private var qsDisabled = false
-    private var visible = false
-        set(value) {
-            if (field == value) {
-                return
-            }
-            field = value
-            updateListeners()
-        }
-
-    /**
-     * Whether the QQS/QS part of the shade is visible. This is particularly important in
-     * Lockscreen, as the shade is visible but QS is not.
-     */
-    var qsVisible = false
-        set(value) {
-            if (field == value) {
-                return
-            }
-            field = value
-            onShadeExpandedChanged()
-        }
-
-    /**
-     * Whether we are in a configuration with large screen width. In this case, the header is a
-     * single line.
-     */
-    var largeScreenActive = false
-        set(value) {
-            if (field == value) {
-                return
-            }
-            field = value
-            onHeaderStateChanged()
-        }
-
-    /**
-     * Expansion fraction of the QQS/QS shade. This is not the expansion between QQS <-> QS.
-     */
-    var shadeExpandedFraction = -1f
-        set(value) {
-            if (field != value) {
-                val oldAlpha = header.alpha
-                header.alpha = ShadeInterpolation.getContentAlpha(value)
-                field = value
-                if ((oldAlpha == 0f && header.alpha > 0f) ||
-                        (oldAlpha > 0f && header.alpha == 0f)) {
-                    updateVisibility()
-                }
-            }
-        }
-
-    /**
-     * Expansion fraction of the QQS <-> QS animation.
-     */
-    var qsExpandedFraction = -1f
-        set(value) {
-            if (visible && field != value) {
-                field = value
-                updatePosition()
-            }
-        }
-
-    /**
-     * Current scroll of QS.
-     */
-    var qsScrollY = 0
-        set(value) {
-            if (field != value) {
-                field = value
-                updateScrollY()
-            }
-        }
-
-    private val insetListener = View.OnApplyWindowInsetsListener { view, insets ->
-        updateConstraintsForInsets(view as MotionLayout, insets)
-        lastInsets = WindowInsets(insets)
-
-        view.onApplyWindowInsets(insets)
-    }
-
-    private val demoModeReceiver = object : DemoMode {
-        override fun demoCommands() = listOf(DemoMode.COMMAND_CLOCK)
-        override fun dispatchDemoCommand(command: String, args: Bundle) =
-            clock.dispatchDemoCommand(command, args)
-        override fun onDemoModeStarted() = clock.onDemoModeStarted()
-        override fun onDemoModeFinished() = clock.onDemoModeFinished()
-    }
-
-    private val chipVisibilityListener: ChipVisibilityListener = object : ChipVisibilityListener {
-        override fun onChipVisibilityRefreshed(visible: Boolean) {
-            if (header is MotionLayout) {
-                // If the privacy chip is visible, we hide the status icons and battery remaining
-                // icon, only in QQS.
-                val update = combinedShadeHeadersConstraintManager
-                    .privacyChipVisibilityConstraints(visible)
-                header.updateAllConstraints(update)
-            }
-        }
-    }
-
-    private val configurationControllerListener =
-        object : ConfigurationController.ConfigurationListener {
-        override fun onConfigChanged(newConfig: Configuration?) {
-            if (header !is MotionLayout) {
-                val left = header.resources.getDimensionPixelSize(
-                    R.dimen.large_screen_shade_header_left_padding
-                )
-                header.setPadding(
-                    left,
-                    header.paddingTop,
-                    header.paddingRight,
-                    header.paddingBottom
-                )
-            }
-        }
-
-        override fun onDensityOrFontScaleChanged() {
-            clock.setTextAppearance(R.style.TextAppearance_QS_Status)
-            date.setTextAppearance(R.style.TextAppearance_QS_Status)
-            qsCarrierGroup.updateTextAppearance(R.style.TextAppearance_QS_Status_Carriers)
-            if (header is MotionLayout) {
-                loadConstraints()
-                header.minHeight = resources
-                        .getDimensionPixelSize(R.dimen.large_screen_shade_header_min_height)
-                lastInsets?.let { updateConstraintsForInsets(header, it) }
-            }
-            updateResources()
-        }
-    }
-
-    override fun onInit() {
-        if (header is MotionLayout) {
-            variableDateViewControllerFactory.create(date as VariableDateView).init()
-        }
-        batteryMeterViewController.init()
-
-        // battery settings same as in QS icons
-        batteryMeterViewController.ignoreTunerUpdates()
-        batteryIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE)
-
-        iconManager = tintedIconManagerFactory.create(iconContainer, StatusBarLocation.QS)
-        iconManager.setTint(
-            Utils.getColorAttrDefaultColor(header.context, android.R.attr.textColorPrimary)
-        )
-
-        carrierIconSlots =
-            listOf(header.context.getString(com.android.internal.R.string.status_bar_mobile))
-        qsCarrierGroupController = qsCarrierGroupControllerBuilder
-            .setQSCarrierGroup(qsCarrierGroup)
-            .build()
-
-        if (!combinedHeaders) {
-            // In the new header, we display alarm icon but we ignore it when not using the new
-            // headers.
-            iconContainer.addIgnoredSlot(
-                    context.getString(com.android.internal.R.string.status_bar_alarm_clock)
-            )
-        }
-        if (combinedHeaders) {
-            privacyIconsController.onParentVisible()
-        }
-    }
-
-    override fun onViewAttached() {
-        privacyIconsController.chipVisibilityListener = chipVisibilityListener
-        updateVisibility()
-        updateTransition()
-
-        if (header is MotionLayout) {
-            header.setOnApplyWindowInsetsListener(insetListener)
-            clock.addOnLayoutChangeListener { v, _, _, _, _, _, _, _, _ ->
-                val newPivot = if (v.isLayoutRtl) v.width.toFloat() else 0f
-                v.pivotX = newPivot
-                v.pivotY = v.height.toFloat() / 2
-
-                qsCarrierGroup.setPaddingRelative((v.width * v.scaleX).toInt(), 0, 0, 0)
-            }
-        }
-
-        dumpManager.registerDumpable(this)
-        configurationController.addCallback(configurationControllerListener)
-        demoModeController.addCallback(demoModeReceiver)
-    }
-
-    override fun onViewDetached() {
-        privacyIconsController.chipVisibilityListener = null
-        dumpManager.unregisterDumpable(this::class.java.simpleName)
-        configurationController.removeCallback(configurationControllerListener)
-        demoModeController.removeCallback(demoModeReceiver)
-    }
-
-    fun disable(state1: Int, state2: Int, animate: Boolean) {
-        val disabled = state2 and StatusBarManager.DISABLE2_QUICK_SETTINGS != 0
-        if (disabled == qsDisabled) return
-        qsDisabled = disabled
-        updateVisibility()
-    }
-
-    fun startCustomizingAnimation(show: Boolean, duration: Long) {
-        header.animate()
-                .setDuration(duration)
-                .alpha(if (show) 0f else 1f)
-                .setInterpolator(if (show) Interpolators.ALPHA_OUT else Interpolators.ALPHA_IN)
-                .setUpdateListener {
-                    updateVisibility()
-                }
-                .setListener(endAnimationListener)
-                .start()
-    }
-
-    private val endAnimationListener = object : Animator.AnimatorListener {
-        override fun onAnimationCancel(animation: Animator?) {
-            clearListeners()
-        }
-
-        override fun onAnimationEnd(animation: Animator?) {
-            clearListeners()
-        }
-
-        override fun onAnimationRepeat(animation: Animator?) {}
-
-        override fun onAnimationStart(animation: Animator?) {}
-
-        private fun clearListeners() {
-            header.animate().setListener(null).setUpdateListener(null)
-        }
-    }
-
-    private fun loadConstraints() {
-        if (header is MotionLayout) {
-            // Use resources.getXml instead of passing the resource id due to bug b/205018300
-            header.getConstraintSet(QQS_HEADER_CONSTRAINT)
-                    .load(context, resources.getXml(R.xml.qqs_header))
-            header.getConstraintSet(QS_HEADER_CONSTRAINT)
-                    .load(context, resources.getXml(R.xml.qs_header))
-            header.getConstraintSet(LARGE_SCREEN_HEADER_CONSTRAINT)
-                    .load(context, resources.getXml(R.xml.large_screen_shade_header))
-        }
-    }
-
-    private fun updateConstraintsForInsets(view: MotionLayout, insets: WindowInsets) {
-        val cutout = insets.displayCutout
-
-        val sbInsets: Pair<Int, Int> = insetsProvider.getStatusBarContentInsetsForCurrentRotation()
-        cutoutLeft = sbInsets.first
-        cutoutRight = sbInsets.second
-        val hasCornerCutout: Boolean = insetsProvider.currentRotationHasCornerCutout()
-        updateQQSPaddings()
-        // Set these guides as the left/right limits for content that lives in the top row, using
-        // cutoutLeft and cutoutRight
-        var changes = combinedShadeHeadersConstraintManager
-            .edgesGuidelinesConstraints(
-                if (view.isLayoutRtl) cutoutRight else cutoutLeft,
-                header.paddingStart,
-                if (view.isLayoutRtl) cutoutLeft else cutoutRight,
-                header.paddingEnd
-            )
-
-        if (cutout != null) {
-            val topCutout = cutout.boundingRectTop
-            if (topCutout.isEmpty || hasCornerCutout) {
-                changes += combinedShadeHeadersConstraintManager.emptyCutoutConstraints()
-            } else {
-                changes += combinedShadeHeadersConstraintManager.centerCutoutConstraints(
-                    view.isLayoutRtl,
-                    (view.width - view.paddingLeft - view.paddingRight - topCutout.width()) / 2
-                )
-            }
-        } else {
-           changes += combinedShadeHeadersConstraintManager.emptyCutoutConstraints()
-        }
-
-        view.updateAllConstraints(changes)
-    }
-
-    private fun updateScrollY() {
-        if (!largeScreenActive && combinedHeaders) {
-            header.scrollY = qsScrollY
-        }
-    }
-
-    private fun onShadeExpandedChanged() {
-        if (qsVisible) {
-            privacyIconsController.startListening()
-        } else {
-            privacyIconsController.stopListening()
-        }
-        updateVisibility()
-        updatePosition()
-    }
-
-    private fun onHeaderStateChanged() {
-        if (largeScreenActive || combinedHeaders) {
-            privacyIconsController.onParentVisible()
-        } else {
-            privacyIconsController.onParentInvisible()
-        }
-        updateVisibility()
-        updateTransition()
-    }
-
-    /**
-     * If not using [combinedHeaders] this should only be visible on large screen. Else, it should
-     * be visible any time the QQS/QS shade is open.
-     */
-    private fun updateVisibility() {
-        val visibility = if (!largeScreenActive && !combinedHeaders || qsDisabled) {
-            View.GONE
-        } else if (qsVisible && header.alpha > 0f) {
-            View.VISIBLE
-        } else {
-            View.INVISIBLE
-        }
-        if (header.visibility != visibility) {
-            header.visibility = visibility
-            visible = visibility == View.VISIBLE
-        }
-    }
-
-    private fun updateTransition() {
-        if (!combinedHeaders) {
-            return
-        }
-        header as MotionLayout
-        if (largeScreenActive) {
-            logInstantEvent("Large screen constraints set")
-            header.setTransition(LARGE_SCREEN_HEADER_TRANSITION_ID)
-        } else {
-            logInstantEvent("Small screen constraints set")
-            header.setTransition(HEADER_TRANSITION_ID)
-        }
-        header.jumpToState(header.startState)
-        updatePosition()
-        updateScrollY()
-    }
-
-    private fun updatePosition() {
-        if (header is MotionLayout && !largeScreenActive && visible) {
-            logInstantEvent("updatePosition: $qsExpandedFraction")
-            header.progress = qsExpandedFraction
-        }
-    }
-
-    private fun logInstantEvent(message: String) {
-        Trace.instantForTrack(
-                TRACE_TAG_APP,
-                "LargeScreenHeaderController",
-                message
-        )
-    }
-
-    private fun updateListeners() {
-        qsCarrierGroupController.setListening(visible)
-        if (visible) {
-            updateSingleCarrier(qsCarrierGroupController.isSingleCarrier)
-            qsCarrierGroupController.setOnSingleCarrierChangedListener { updateSingleCarrier(it) }
-            statusBarIconController.addIconGroup(iconManager)
-        } else {
-            qsCarrierGroupController.setOnSingleCarrierChangedListener(null)
-            statusBarIconController.removeIconGroup(iconManager)
-        }
-    }
-
-    private fun updateSingleCarrier(singleCarrier: Boolean) {
-        if (singleCarrier) {
-            iconContainer.removeIgnoredSlots(carrierIconSlots)
-        } else {
-            iconContainer.addIgnoredSlots(carrierIconSlots)
-        }
-    }
-
-    private fun updateResources() {
-        roundedCorners = resources.getDimensionPixelSize(R.dimen.rounded_corner_content_padding)
-        val padding = resources.getDimensionPixelSize(R.dimen.qs_panel_padding)
-        header.setPadding(padding, header.paddingTop, padding, header.paddingBottom)
-        updateQQSPaddings()
-    }
-
-    private fun updateQQSPaddings() {
-        if (header is MotionLayout) {
-            val clockPaddingStart = resources
-                .getDimensionPixelSize(R.dimen.status_bar_left_clock_starting_padding)
-            val clockPaddingEnd = resources
-                .getDimensionPixelSize(R.dimen.status_bar_left_clock_end_padding)
-            clock.setPaddingRelative(
-                clockPaddingStart,
-                clock.paddingTop,
-                clockPaddingEnd,
-                clock.paddingBottom
-            )
-        }
-    }
-
-    override fun dump(pw: PrintWriter, args: Array<out String>) {
-        pw.println("visible: $visible")
-        pw.println("shadeExpanded: $qsVisible")
-        pw.println("shadeExpandedFraction: $shadeExpandedFraction")
-        pw.println("active: $largeScreenActive")
-        pw.println("qsExpandedFraction: $qsExpandedFraction")
-        pw.println("qsScrollY: $qsScrollY")
-        if (combinedHeaders) {
-            header as MotionLayout
-            pw.println("currentState: ${header.currentState.stateToString()}")
-        }
-    }
-
-    private fun MotionLayout.updateConstraints(@IdRes state: Int, update: ConstraintChange) {
-        val constraints = getConstraintSet(state)
-        constraints.update()
-        updateState(state, constraints)
-    }
-
-    /**
-     * Updates the [ConstraintSet] for the case of combined headers.
-     *
-     * Only non-`null` changes are applied to reduce the number of rebuilding in the [MotionLayout].
-     */
-    private fun MotionLayout.updateAllConstraints(updates: ConstraintsChanges) {
-        if (updates.qqsConstraintsChanges != null) {
-            updateConstraints(QQS_HEADER_CONSTRAINT, updates.qqsConstraintsChanges)
-        }
-        if (updates.qsConstraintsChanges != null) {
-            updateConstraints(QS_HEADER_CONSTRAINT, updates.qsConstraintsChanges)
-        }
-        if (updates.largeScreenConstraintsChanges != null) {
-            updateConstraints(LARGE_SCREEN_HEADER_CONSTRAINT, updates.largeScreenConstraintsChanges)
-        }
-    }
-
-    @VisibleForTesting
-    internal fun simulateViewDetached() = this.onViewDetached()
-}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
index 639172f..b445000 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
@@ -48,7 +48,10 @@
                 setOf(
                     ViewIdToTranslate(R.id.quick_settings_panel, START, filterShade),
                     ViewIdToTranslate(R.id.notification_stack_scroller, END, filterShade),
-                    ViewIdToTranslate(R.id.rightLayout, END, filterShade),
+                    ViewIdToTranslate(R.id.statusIcons, END, filterShade),
+                    ViewIdToTranslate(R.id.privacy_container, END, filterShade),
+                    ViewIdToTranslate(R.id.batteryRemainingIcon, END, filterShade),
+                    ViewIdToTranslate(R.id.carrier_group, END, filterShade),
                     ViewIdToTranslate(R.id.clock, START, filterShade),
                     ViewIdToTranslate(R.id.date, START, filterShade)),
             progressProvider = progressProvider)
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index cd45b32..e53eea9 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -23,14 +23,12 @@
 import static androidx.constraintlayout.widget.ConstraintSet.END;
 import static androidx.constraintlayout.widget.ConstraintSet.PARENT_ID;
 
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE;
 import static com.android.keyguard.KeyguardClockSwitch.LARGE;
 import static com.android.keyguard.KeyguardClockSwitch.SMALL;
 import static com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE;
 import static com.android.systemui.animation.Interpolators.EMPHASIZED_DECELERATE;
 import static com.android.systemui.classifier.Classifier.BOUNCER_UNLOCK;
 import static com.android.systemui.classifier.Classifier.GENERIC;
-import static com.android.systemui.classifier.Classifier.QS_COLLAPSE;
 import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
 import static com.android.systemui.classifier.Classifier.UNLOCK;
 import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_CLOSED;
@@ -53,7 +51,6 @@
 import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.Fragment;
 import android.app.StatusBarManager;
 import android.content.ContentResolver;
 import android.content.res.Resources;
@@ -101,10 +98,8 @@
 import androidx.constraintlayout.widget.ConstraintSet;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.policy.ScreenDecorationsUtils;
 import com.android.internal.policy.SystemBarUtils;
 import com.android.internal.util.LatencyTracker;
 import com.android.keyguard.ActiveUnlockConfig;
@@ -135,7 +130,6 @@
 import com.android.systemui.dump.DumpsysTableLogger;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
-import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
 import com.android.systemui.fragments.FragmentService;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
@@ -177,7 +171,6 @@
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.NotificationShelfController;
 import com.android.systemui.statusbar.PulseExpansionHandler;
-import com.android.systemui.statusbar.QsFrameTranslateController;
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
@@ -263,13 +256,13 @@
     private static final VibrationEffect ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT =
             VibrationEffect.get(VibrationEffect.EFFECT_STRENGTH_MEDIUM, false);
     /** The parallax amount of the quick settings translation when dragging down the panel. */
-    private static final float QS_PARALLAX_AMOUNT = 0.175f;
+    public static final float QS_PARALLAX_AMOUNT = 0.175f;
     /** Fling expanding QS. */
     public static final int FLING_EXPAND = 0;
     /** Fling collapsing QS, potentially stopping when QS becomes QQS. */
-    private static final int FLING_COLLAPSE = 1;
+    public static final int FLING_COLLAPSE = 1;
     /** Fling until QS is completely hidden. */
-    private static final int FLING_HIDE = 2;
+    public static final int FLING_HIDE = 2;
     /** The delay to reset the hint text when the hint animation is finished running. */
     private static final int HINT_RESET_DELAY_MS = 1200;
     private static final long ANIMATION_DELAY_ICON_FADE_IN =
@@ -291,7 +284,7 @@
     private static final int MAX_TIME_TO_OPEN_WHEN_FLINGING_FROM_LAUNCHER = 300;
     private static final int MAX_DOWN_EVENT_BUFFER_SIZE = 50;
     private static final String COUNTER_PANEL_OPEN = "panel_open";
-    private static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs";
+    public static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs";
     private static final String COUNTER_PANEL_OPEN_PEEK = "panel_open_peek";
     private static final Rect M_DUMMY_DIRTY_RECT = new Rect(0, 0, 1, 1);
     private static final Rect EMPTY_RECT = new Rect();
@@ -310,14 +303,10 @@
     private final SystemClock mSystemClock;
     private final ShadeLogger mShadeLog;
     private final DozeParameters mDozeParameters;
-    private final Runnable mCollapseExpandAction = this::collapseOrExpand;
-    private final NsslOverscrollTopChangedListener mOnOverscrollTopChangedListener =
-            new NsslOverscrollTopChangedListener();
     private final NotificationStackScrollLayout.OnEmptySpaceClickListener
             mOnEmptySpaceClickListener = (x, y) -> onEmptySpaceClick();
     private final ShadeHeadsUpChangedListener mOnHeadsUpChangedListener =
             new ShadeHeadsUpChangedListener();
-    private final QS.HeightListener mHeightListener = this::onQsHeightChanged;
     private final ConfigurationListener mConfigurationListener = new ConfigurationListener();
     private final SettingsChangeObserver mSettingsChangeObserver;
     private final StatusBarStateListener mStatusBarStateListener = new StatusBarStateListener();
@@ -327,7 +316,6 @@
     private final ConfigurationController mConfigurationController;
     private final Provider<FlingAnimationUtils.Builder> mFlingAnimationUtilsBuilder;
     private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
-    private final InteractionJankMonitor mInteractionJankMonitor;
     private final LayoutInflater mLayoutInflater;
     private final FeatureFlags mFeatureFlags;
     private final PowerManager mPowerManager;
@@ -346,12 +334,9 @@
     private final KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory;
     private final FragmentService mFragmentService;
     private final ScrimController mScrimController;
-    private final NotificationRemoteInputManager mRemoteInputManager;
     private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
-    private final ShadeTransitionController mShadeTransitionController;
     private final TapAgainViewController mTapAgainViewController;
-    private final LargeScreenShadeHeaderController mLargeScreenShadeHeaderController;
-    private final RecordingController mRecordingController;
+    private final ShadeHeaderController mShadeHeaderController;
     private final boolean mVibrateOnOpening;
     private final VelocityTracker mVelocityTracker = VelocityTracker.obtain();
     private final FlingAnimationUtils mFlingAnimationUtilsClosing;
@@ -363,12 +348,11 @@
     private final Interpolator mBounceInterpolator;
     private final NotificationShadeWindowController mNotificationShadeWindowController;
     private final ShadeExpansionStateManager mShadeExpansionStateManager;
-    private final QS.ScrollListener mQsScrollListener = this::onQsPanelScrollChanged;
     private final FalsingTapListener mFalsingTapListener = this::falsingAdditionalTapRequired;
-    private final FragmentListener mQsFragmentListener = new QsFragmentListener();
     private final AccessibilityDelegate mAccessibilityDelegate = new ShadeAccessibilityDelegate();
     private final NotificationGutsManager mGutsManager;
     private final AlternateBouncerInteractor mAlternateBouncerInteractor;
+    private final QuickSettingsController mQsController;
 
     private long mDownTime;
     private boolean mTouchSlopExceededBeforeDown;
@@ -395,9 +379,6 @@
     private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
     private KeyguardStatusBarView mKeyguardStatusBar;
     private KeyguardStatusBarViewController mKeyguardStatusBarViewController;
-    private QS mQs;
-    private FrameLayout mQsFrame;
-    private final QsFrameTranslateController mQsFrameTranslateController;
     private KeyguardStatusViewController mKeyguardStatusViewController;
     private final LockIconViewController mLockIconViewController;
     private NotificationsQuickSettingsContainer mNotificationContainerParent;
@@ -405,47 +386,19 @@
     private final Provider<KeyguardBottomAreaViewController>
             mKeyguardBottomAreaViewControllerProvider;
     private boolean mAnimateNextPositionUpdate;
-    private float mQuickQsHeaderHeight;
     private final ScreenOffAnimationController mScreenOffAnimationController;
     private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
-    private int mQsTrackingPointer;
-    private VelocityTracker mQsVelocityTracker;
     private TrackingStartedListener mTrackingStartedListener;
     private OpenCloseListener mOpenCloseListener;
     private GestureRecorder mGestureRecorder;
-    private boolean mQsTracking;
-    /** Whether the ongoing gesture might both trigger the expansion in both the view and QS. */
-    private boolean mConflictingQsExpansionGesture;
     private boolean mPanelExpanded;
 
-    /**
-     * Indicates that QS is in expanded state which can happen by:
-     * - single pane shade: expanding shade and then expanding QS
-     * - split shade: just expanding shade (QS are expanded automatically)
-     */
-    private boolean mQsExpanded;
-    private boolean mQsExpandedWhenExpandingStarted;
-    private boolean mQsFullyExpanded;
-    private boolean mKeyguardShowing;
     private boolean mKeyguardQsUserSwitchEnabled;
     private boolean mKeyguardUserSwitcherEnabled;
     private boolean mDozing;
     private boolean mDozingOnDown;
     private boolean mBouncerShowing;
     private int mBarState;
-    private float mInitialHeightOnTouch;
-    private float mInitialTouchX;
-    private float mInitialTouchY;
-    private float mQsExpansionHeight;
-    private int mQsMinExpansionHeight;
-    private int mQsMaxExpansionHeight;
-    private int mQsPeekHeight;
-    private boolean mStackScrollerOverscrolling;
-    private boolean mQsExpansionFromOverscroll;
-    private float mLastOverscroll;
-    private boolean mQsExpansionEnabledPolicy = true;
-    private boolean mQsExpansionEnabledAmbient = true;
-    private ValueAnimator mQsExpansionAnimator;
     private FlingAnimationUtils mFlingAnimationUtils;
     private int mStatusBarMinHeight;
     private int mStatusBarHeaderHeightKeyguard;
@@ -455,8 +408,6 @@
     private int mDisplayTopInset = 0; // in pixels
     private int mDisplayRightInset = 0; // in pixels
     private int mDisplayLeftInset = 0; // in pixels
-    private int mLargeScreenShadeHeaderHeight;
-    private int mSplitShadeNotificationsScrimMarginBottom;
 
     private final KeyguardClockPositionAlgorithm
             mClockPositionAlgorithm =
@@ -466,23 +417,7 @@
             new KeyguardClockPositionAlgorithm.Result();
     private boolean mIsExpanding;
 
-    /**
-     * Determines if QS should be already expanded when expanding shade.
-     * Used for split shade, two finger gesture as well as accessibility shortcut to QS.
-     * It needs to be set when movement starts as it resets at the end of expansion/collapse.
-     */
-    private boolean mQsExpandImmediate;
-    private boolean mTwoFingerQsExpandPossible;
     private String mHeaderDebugInfo;
-    /**
-     * If we are in a panel collapsing motion, we reset scrollY of our scroll view but still
-     * need to take this into account in our panel height calculation.
-     */
-    private boolean mQsAnimatorExpand;
-    private ValueAnimator mQsSizeChangeAnimator;
-    private boolean mQsScrimEnabled = true;
-    private boolean mQsTouchAboveFalsingThreshold;
-    private int mQsFalsingThreshold;
 
     /**
      * Indicates drag starting height when swiping down or up on heads-up notifications.
@@ -530,7 +465,7 @@
     private int mPanelAlpha;
     private Runnable mPanelAlphaEndAction;
     private float mBottomAreaShadeAlpha;
-    private final ValueAnimator mBottomAreaShadeAlphaAnimator;
+    final ValueAnimator mBottomAreaShadeAlphaAnimator;
     private final AnimatableProperty mPanelAlphaAnimator = AnimatableProperty.from("panelAlpha",
             NotificationPanelView::setPanelAlphaInternal,
             NotificationPanelView::getCurrentPanelAlpha,
@@ -564,51 +499,12 @@
     private Runnable mExpandAfterLayoutRunnable;
     private Runnable mHideExpandedRunnable;
 
-    /**
-     * The padding between the start of notifications and the qs boundary on the lockscreen.
-     * On lockscreen, notifications aren't inset this extra amount, but we still want the
-     * qs boundary to be padded.
-     */
-    private int mLockscreenNotificationQSPadding;
-    /**
-     * The amount of progress we are currently in if we're transitioning to the full shade.
-     * 0.0f means we're not transitioning yet, while 1 means we're all the way in the full
-     * shade. This value can also go beyond 1.1 when we're overshooting!
-     */
-    private float mTransitioningToFullShadeProgress;
-    /**
-     * Position of the qs bottom during the full shade transition. This is needed as the toppadding
-     * can change during state changes, which makes it much harder to do animations
-     */
-    private int mTransitionToFullShadeQSPosition;
-    /** Distance a full shade transition takes in order for qs to fully transition to the shade. */
-    private int mDistanceForQSFullShadeTransition;
-    /** The translation amount for QS for the full shade transition. */
-    private float mQsTranslationForFullShadeTransition;
-
     /** The maximum overshoot allowed for the top padding for the full shade transition. */
     private int mMaxOverscrollAmountForPulse;
-    /** Should we animate the next bounds update. */
-    private boolean mAnimateNextNotificationBounds;
-    /** The delay for the next bounds animation. */
-    private long mNotificationBoundsAnimationDelay;
-    /** The duration of the notification bounds animation. */
-    private long mNotificationBoundsAnimationDuration;
 
     /** Whether a collapse that started on the panel should allow the panel to intercept. */
     private boolean mIsPanelCollapseOnQQS;
-    private boolean mAnimatingQS;
-    /** The end bounds of a clipping animation. */
-    private final Rect mQsClippingAnimationEndBounds = new Rect();
-    /** The animator for the qs clipping bounds. */
-    private ValueAnimator mQsClippingAnimation = null;
-    /** Whether the current animator is resetting the qs translation. */
-    private boolean mIsQsTranslationResetAnimator;
 
-    /** Whether the current animator is resetting the pulse expansion after a drag down. */
-    private boolean mIsPulseExpansionResetAnimator;
-    private final Rect mLastQsClipBounds = new Rect();
-    private final Region mQsInterceptRegion = new Region();
     /** Alpha of the views which only show on the keyguard but not in shade / shade locked. */
     private float mKeyguardOnlyContentAlpha = 1.0f;
     /** Y translation of the views that only show on the keyguard but in shade / shade locked. */
@@ -618,15 +514,6 @@
     private boolean mIsGestureNavigation;
     private int mOldLayoutDirection;
     private NotificationShelfController mNotificationShelfController;
-    private int mScrimCornerRadius;
-    private int mScreenCornerRadius;
-    private boolean mQSAnimatingHiddenFromCollapsed;
-    private boolean mUseLargeScreenShadeHeader;
-    private boolean mEnableQsClipping;
-
-    private int mQsClipTop;
-    private int mQsClipBottom;
-    private boolean mQsVisible;
 
     private final ContentResolver mContentResolver;
     private float mMinFraction;
@@ -685,7 +572,6 @@
     private boolean mInstantExpanding;
     private boolean mAnimateAfterExpanding;
     private boolean mIsFlinging;
-    private boolean mLastFlingWasExpanding;
     private String mViewName;
     private float mInitialExpandY;
     private float mInitialExpandX;
@@ -711,7 +597,6 @@
     private int mLockscreenToDreamingTransitionTranslationY;
     private int mGoneToDreamingTransitionTranslationY;
     private int mLockscreenToOccludedTransitionTranslationY;
-    private boolean mUnocclusionTransitionFlagEnabled = false;
 
     private final Runnable mFlingCollapseRunnable = () -> fling(0, false /* expand */,
             mNextCollapseSpeedUpFactor, false /* expandBecauseOfFalsing */);
@@ -803,17 +688,16 @@
             TapAgainViewController tapAgainViewController,
             NavigationModeController navigationModeController,
             NavigationBarController navigationBarController,
+            QuickSettingsController quickSettingsController,
             FragmentService fragmentService,
             ContentResolver contentResolver,
             RecordingController recordingController,
-            LargeScreenShadeHeaderController largeScreenShadeHeaderController,
+            ShadeHeaderController shadeHeaderController,
             ScreenOffAnimationController screenOffAnimationController,
             LockscreenGestureLogger lockscreenGestureLogger,
             ShadeExpansionStateManager shadeExpansionStateManager,
             NotificationRemoteInputManager remoteInputManager,
             Optional<SysUIUnfoldComponent> unfoldComponent,
-            InteractionJankMonitor interactionJankMonitor,
-            QsFrameTranslateController qsFrameTranslateController,
             SysUiState sysUiState,
             Provider<KeyguardBottomAreaViewController> keyguardBottomAreaViewControllerProvider,
             KeyguardUnlockAnimationController keyguardUnlockAnimationController,
@@ -873,6 +757,7 @@
 
         mResources = mView.getResources();
         mKeyguardStateController = keyguardStateController;
+        mQsController = quickSettingsController;
         mKeyguardIndicationController = keyguardIndicationController;
         mStatusBarStateController = (SysuiStatusBarStateController) statusBarStateController;
         mNotificationShadeWindowController = notificationShadeWindowController;
@@ -903,7 +788,6 @@
         mVibratorHelper = vibratorHelper;
         mVibrateOnOpening = mResources.getBoolean(R.bool.config_vibrateOnIconAnimation);
         mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
-        mInteractionJankMonitor = interactionJankMonitor;
         mSystemClock = systemClock;
         mKeyguardMediaController = keyguardMediaController;
         mMetricsLogger = metricsLogger;
@@ -928,7 +812,7 @@
         mSplitShadeEnabled =
                 LargeScreenUtils.shouldUseSplitNotificationShade(mResources);
         mView.setWillNotDraw(!DEBUG_DRAWABLE);
-        mLargeScreenShadeHeaderController = largeScreenShadeHeaderController;
+        mShadeHeaderController = shadeHeaderController;
         mLayoutInflater = layoutInflater;
         mFeatureFlags = featureFlags;
         mFalsingCollector = falsingCollector;
@@ -939,7 +823,6 @@
         mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
         setPanelAlpha(255, false /* animate */);
         mCommandQueue = commandQueue;
-        mRecordingController = recordingController;
         mDisplayId = displayId;
         mPulseExpansionHandler = pulseExpansionHandler;
         mDozeParameters = dozeParameters;
@@ -948,20 +831,19 @@
         mMediaDataManager = mediaDataManager;
         mTapAgainViewController = tapAgainViewController;
         mSysUiState = sysUiState;
-        pulseExpansionHandler.setPulseExpandAbortListener(() -> {
-            if (mQs != null) {
-                mQs.animateHeaderSlidingOut();
-            }
-        });
         statusBarWindowStateController.addListener(this::onStatusBarWindowStateChanged);
         mKeyguardBypassController = bypassController;
         mUpdateMonitor = keyguardUpdateMonitor;
         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
-        mShadeTransitionController = shadeTransitionController;
         lockscreenShadeTransitionController.setNotificationPanelController(this);
         shadeTransitionController.setNotificationPanelViewController(this);
         dynamicPrivacyController.addListener(this::onDynamicPrivacyChanged);
-
+        quickSettingsController.setExpansionHeightListener(this::onQsSetExpansionHeightCalled);
+        quickSettingsController.setQsStateUpdateListener(this::onQsStateUpdated);
+        quickSettingsController.setApplyClippingImmediatelyListener(
+                this::onQsClippingImmediatelyApplied);
+        quickSettingsController.setFlingQsWithoutClickListener(this::onFlingQsWithoutClick);
+        quickSettingsController.setExpansionHeightSetToMaxListener(this::onExpansionHeightSetToMax);
         shadeExpansionStateManager.addStateListener(this::onPanelStateChanged);
 
         mBottomAreaShadeAlphaAnimator = ValueAnimator.ofFloat(1f, 0);
@@ -976,7 +858,6 @@
         mLockIconViewController = lockIconViewController;
         mScreenOffAnimationController = screenOffAnimationController;
         mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
-        mRemoteInputManager = remoteInputManager;
         mLastDownEvents = new NPVCDownEventState.Buffer(MAX_DOWN_EVENT_BUFFER_SIZE);
 
         int currentMode = navigationModeController.addListener(
@@ -995,7 +876,8 @@
 
         if (DEBUG_DRAWABLE) {
             mView.getOverlay().add(new DebugDrawable(this, mView,
-                    mNotificationStackScrollLayoutController, mLockIconViewController));
+                    mNotificationStackScrollLayoutController, mLockIconViewController,
+                    mQsController));
         }
 
         mKeyguardUnfoldTransition = unfoldComponent.map(
@@ -1003,9 +885,6 @@
         mNotificationPanelUnfoldAnimationController = unfoldComponent.map(
                 SysUIUnfoldComponent::getNotificationPanelUnfoldAnimationController);
 
-        mUnocclusionTransitionFlagEnabled = featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION);
-
-        mQsFrameTranslateController = qsFrameTranslateController;
         updateUserSwitcherFlags();
         mKeyguardBottomAreaViewModel = keyguardBottomAreaViewModel;
         mKeyguardBottomAreaInteractor = keyguardBottomAreaInteractor;
@@ -1121,19 +1000,16 @@
         mNotificationStackScrollLayoutController.attach(stackScrollLayout);
         mNotificationStackScrollLayoutController.setOnHeightChangedListener(
                 new NsslHeightChangedListener());
-        mNotificationStackScrollLayoutController.setOverscrollTopChangedListener(
-                mOnOverscrollTopChangedListener);
-        mNotificationStackScrollLayoutController.setOnScrollListener(this::onNotificationScrolled);
-        mNotificationStackScrollLayoutController.setOnStackYChanged(this::onStackYChanged);
         mNotificationStackScrollLayoutController.setOnEmptySpaceClickListener(
                 mOnEmptySpaceClickListener);
+        mQsController.initNotificationStackScrollLayoutController();
+        mShadeExpansionStateManager.addQsExpansionListener(this::onQsExpansionChanged);
         addTrackingHeadsUpListener(mNotificationStackScrollLayoutController::setTrackingHeadsUp);
         setKeyguardBottomArea(mView.findViewById(R.id.keyguard_bottom_area));
 
         initBottomArea();
 
         mWakeUpCoordinator.setStackScroller(mNotificationStackScrollLayoutController);
-        mQsFrame = mView.findViewById(R.id.qs_frame);
         mPulseExpansionHandler.setUp(mNotificationStackScrollLayoutController);
         mWakeUpCoordinator.addListener(new NotificationWakeUpCoordinator.WakeUpListener() {
             @Override
@@ -1162,67 +1038,55 @@
         }
 
         mTapAgainViewController.init();
-        mLargeScreenShadeHeaderController.init();
+        mShadeHeaderController.init();
         mKeyguardUnfoldTransition.ifPresent(u -> u.setup(mView));
         mNotificationPanelUnfoldAnimationController.ifPresent(controller ->
                 controller.setup(mNotificationContainerParent));
 
-        if (mUnocclusionTransitionFlagEnabled) {
-            // Dreaming->Lockscreen
-            collectFlow(mView, mKeyguardTransitionInteractor.getDreamingToLockscreenTransition(),
-                    mDreamingToLockscreenTransition, mMainDispatcher);
-            collectFlow(mView, mDreamingToLockscreenTransitionViewModel.getLockscreenAlpha(),
-                    setTransitionAlpha(mNotificationStackScrollLayoutController),
-                    mMainDispatcher);
-            collectFlow(mView, mDreamingToLockscreenTransitionViewModel.lockscreenTranslationY(
-                    mDreamingToLockscreenTransitionTranslationY),
-                    setTransitionY(mNotificationStackScrollLayoutController),
-                    mMainDispatcher);
+        // Dreaming->Lockscreen
+        collectFlow(mView, mKeyguardTransitionInteractor.getDreamingToLockscreenTransition(),
+                mDreamingToLockscreenTransition, mMainDispatcher);
+        collectFlow(mView, mDreamingToLockscreenTransitionViewModel.getLockscreenAlpha(),
+                setTransitionAlpha(mNotificationStackScrollLayoutController), mMainDispatcher);
+        collectFlow(mView, mDreamingToLockscreenTransitionViewModel.lockscreenTranslationY(
+                mDreamingToLockscreenTransitionTranslationY),
+                setTransitionY(mNotificationStackScrollLayoutController), mMainDispatcher);
 
-            // Occluded->Lockscreen
-            collectFlow(mView, mKeyguardTransitionInteractor.getOccludedToLockscreenTransition(),
-                    mOccludedToLockscreenTransition, mMainDispatcher);
-            collectFlow(mView, mOccludedToLockscreenTransitionViewModel.getLockscreenAlpha(),
-                    setTransitionAlpha(mNotificationStackScrollLayoutController),
-                    mMainDispatcher);
-            collectFlow(mView, mOccludedToLockscreenTransitionViewModel.lockscreenTranslationY(
-                    mOccludedToLockscreenTransitionTranslationY),
-                    setTransitionY(mNotificationStackScrollLayoutController),
-                    mMainDispatcher);
+        // Occluded->Lockscreen
+        collectFlow(mView, mKeyguardTransitionInteractor.getOccludedToLockscreenTransition(),
+                mOccludedToLockscreenTransition, mMainDispatcher);
+        collectFlow(mView, mOccludedToLockscreenTransitionViewModel.getLockscreenAlpha(),
+                setTransitionAlpha(mNotificationStackScrollLayoutController), mMainDispatcher);
+        collectFlow(mView, mOccludedToLockscreenTransitionViewModel.lockscreenTranslationY(
+                mOccludedToLockscreenTransitionTranslationY),
+                setTransitionY(mNotificationStackScrollLayoutController), mMainDispatcher);
 
-            // Lockscreen->Dreaming
-            collectFlow(mView, mKeyguardTransitionInteractor.getLockscreenToDreamingTransition(),
-                    mLockscreenToDreamingTransition, mMainDispatcher);
-            collectFlow(mView, mLockscreenToDreamingTransitionViewModel.getLockscreenAlpha(),
-                    setTransitionAlpha(mNotificationStackScrollLayoutController),
-                    mMainDispatcher);
-            collectFlow(mView, mLockscreenToDreamingTransitionViewModel.lockscreenTranslationY(
-                    mLockscreenToDreamingTransitionTranslationY),
-                    setTransitionY(mNotificationStackScrollLayoutController),
-                    mMainDispatcher);
+        // Lockscreen->Dreaming
+        collectFlow(mView, mKeyguardTransitionInteractor.getLockscreenToDreamingTransition(),
+                mLockscreenToDreamingTransition, mMainDispatcher);
+        collectFlow(mView, mLockscreenToDreamingTransitionViewModel.getLockscreenAlpha(),
+                setTransitionAlpha(mNotificationStackScrollLayoutController), mMainDispatcher);
+        collectFlow(mView, mLockscreenToDreamingTransitionViewModel.lockscreenTranslationY(
+                mLockscreenToDreamingTransitionTranslationY),
+                setTransitionY(mNotificationStackScrollLayoutController), mMainDispatcher);
 
-            // Gone->Dreaming
-            collectFlow(mView, mKeyguardTransitionInteractor.getGoneToDreamingTransition(),
-                    mGoneToDreamingTransition, mMainDispatcher);
-            collectFlow(mView, mGoneToDreamingTransitionViewModel.getLockscreenAlpha(),
-                    setTransitionAlpha(mNotificationStackScrollLayoutController),
-                    mMainDispatcher);
-            collectFlow(mView, mGoneToDreamingTransitionViewModel.lockscreenTranslationY(
-                    mGoneToDreamingTransitionTranslationY),
-                    setTransitionY(mNotificationStackScrollLayoutController),
-                    mMainDispatcher);
+        // Gone->Dreaming
+        collectFlow(mView, mKeyguardTransitionInteractor.getGoneToDreamingTransition(),
+                mGoneToDreamingTransition, mMainDispatcher);
+        collectFlow(mView, mGoneToDreamingTransitionViewModel.getLockscreenAlpha(),
+                setTransitionAlpha(mNotificationStackScrollLayoutController), mMainDispatcher);
+        collectFlow(mView, mGoneToDreamingTransitionViewModel.lockscreenTranslationY(
+                mGoneToDreamingTransitionTranslationY),
+                setTransitionY(mNotificationStackScrollLayoutController), mMainDispatcher);
 
-            // Lockscreen->Occluded
-            collectFlow(mView, mKeyguardTransitionInteractor.getLockscreenToOccludedTransition(),
-                    mLockscreenToOccludedTransition, mMainDispatcher);
-            collectFlow(mView, mLockscreenToOccludedTransitionViewModel.getLockscreenAlpha(),
-                    setTransitionAlpha(mNotificationStackScrollLayoutController),
-                    mMainDispatcher);
-            collectFlow(mView, mLockscreenToOccludedTransitionViewModel.lockscreenTranslationY(
-                    mLockscreenToOccludedTransitionTranslationY),
-                    setTransitionY(mNotificationStackScrollLayoutController),
-                    mMainDispatcher);
-        }
+        // Lockscreen->Occluded
+        collectFlow(mView, mKeyguardTransitionInteractor.getLockscreenToOccludedTransition(),
+                mLockscreenToOccludedTransition, mMainDispatcher);
+        collectFlow(mView, mLockscreenToOccludedTransitionViewModel.getLockscreenAlpha(),
+                setTransitionAlpha(mNotificationStackScrollLayoutController), mMainDispatcher);
+        collectFlow(mView, mLockscreenToOccludedTransitionViewModel.lockscreenTranslationY(
+                mLockscreenToOccludedTransitionTranslationY),
+                setTransitionY(mNotificationStackScrollLayoutController), mMainDispatcher);
     }
 
     @VisibleForTesting
@@ -1236,24 +1100,14 @@
                 .setMaxLengthSeconds(0.4f).build();
         mStatusBarMinHeight = SystemBarUtils.getStatusBarHeight(mView.getContext());
         mStatusBarHeaderHeightKeyguard = Utils.getStatusBarHeaderHeightKeyguard(mView.getContext());
-        mQsPeekHeight = mResources.getDimensionPixelSize(R.dimen.qs_peek_height);
         mClockPositionAlgorithm.loadDimens(mResources);
-        mQsFalsingThreshold = mResources.getDimensionPixelSize(R.dimen.qs_falsing_threshold);
         mIndicationBottomPadding = mResources.getDimensionPixelSize(
                 R.dimen.keyguard_indication_bottom_padding);
         int statusbarHeight = SystemBarUtils.getStatusBarHeight(mView.getContext());
         mHeadsUpInset = statusbarHeight + mResources.getDimensionPixelSize(
                 R.dimen.heads_up_status_bar_padding);
-        mDistanceForQSFullShadeTransition = mResources.getDimensionPixelSize(
-                R.dimen.lockscreen_shade_qs_transition_distance);
         mMaxOverscrollAmountForPulse = mResources.getDimensionPixelSize(
                 R.dimen.pulse_expansion_max_top_overshoot);
-        mScrimCornerRadius = mResources.getDimensionPixelSize(
-                R.dimen.notification_scrim_corner_radius);
-        mScreenCornerRadius = (int) ScreenDecorationsUtils.getWindowCornerRadius(
-                mView.getContext());
-        mLockscreenNotificationQSPadding = mResources.getDimensionPixelSize(
-                R.dimen.notification_side_paddings);
         mUdfpsMaxYBurnInOffset = mResources.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y);
         mSplitShadeScrimTransitionDistance = mResources.getDimensionPixelSize(
                 R.dimen.split_shade_scrim_transition_distance);
@@ -1267,6 +1121,8 @@
                 R.dimen.gone_to_dreaming_transition_lockscreen_translation_y);
         mLockscreenToOccludedTransitionTranslationY = mResources.getDimensionPixelSize(
                 R.dimen.lockscreen_to_occluded_transition_lockscreen_translation_y);
+        // TODO (b/265193930): remove this and make QsController listen to NotificationPanelViews
+        mQsController.loadDimens();
     }
 
     private void updateViewControllers(KeyguardStatusView keyguardStatusView,
@@ -1309,40 +1165,13 @@
     }
 
     public void updateResources() {
-        mSplitShadeNotificationsScrimMarginBottom =
-                mResources.getDimensionPixelSize(
-                        R.dimen.split_shade_notifications_scrim_margin_bottom);
         final boolean newSplitShadeEnabled =
                 LargeScreenUtils.shouldUseSplitNotificationShade(mResources);
         final boolean splitShadeChanged = mSplitShadeEnabled != newSplitShadeEnabled;
         mSplitShadeEnabled = newSplitShadeEnabled;
-
-        if (mQs != null) {
-            mQs.setInSplitShade(mSplitShadeEnabled);
-        }
-
-        mUseLargeScreenShadeHeader =
-                LargeScreenUtils.shouldUseLargeScreenShadeHeader(mView.getResources());
-
-        mLargeScreenShadeHeaderHeight =
-                mResources.getDimensionPixelSize(R.dimen.large_screen_shade_header_height);
-        // TODO: When the flag is eventually removed, it means that we have a single view that is
-        // the same height in QQS and in Large Screen (large_screen_shade_header_height). Eventually
-        // the concept of largeScreenHeader or quickQsHeader will disappear outside of the class
-        // that controls the view as the offset needs to be the same regardless.
-        if (mUseLargeScreenShadeHeader || mFeatureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)) {
-            mQuickQsHeaderHeight = mLargeScreenShadeHeaderHeight;
-        } else {
-            mQuickQsHeaderHeight = SystemBarUtils.getQuickQsOffsetHeight(mView.getContext());
-        }
-        int topMargin = mUseLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight :
-                mResources.getDimensionPixelSize(R.dimen.notification_panel_margin_top);
-        mLargeScreenShadeHeaderController.setLargeScreenActive(mUseLargeScreenShadeHeader);
-        mAmbientState.setStackTopMargin(topMargin);
+        mQsController.updateResources();
         mNotificationsQSContainerController.updateResources();
-
         updateKeyguardStatusViewAlignment(/* animate= */false);
-
         mKeyguardMediaController.refreshMediaPosition();
 
         if (splitShadeChanged) {
@@ -1351,17 +1180,16 @@
 
         mSplitShadeFullTransitionDistance =
                 mResources.getDimensionPixelSize(R.dimen.split_shade_full_transition_distance);
-
-        mEnableQsClipping = mResources.getBoolean(R.bool.qs_enable_clipping);
     }
 
     private void onSplitShadeEnabledChanged() {
+        mShadeLog.logSplitShadeChanged(mSplitShadeEnabled);
         // when we switch between split shade and regular shade we want to enforce setting qs to
         // the default state: expanded for split shade and collapsed otherwise
         if (!isOnKeyguard() && mPanelExpanded) {
-            setQsExpanded(mSplitShadeEnabled);
+            mQsController.setExpanded(mSplitShadeEnabled);
         }
-        if (isOnKeyguard() && mQsExpanded && mSplitShadeEnabled) {
+        if (isOnKeyguard() && mQsController.getExpanded() && mSplitShadeEnabled) {
             // In single column keyguard - when you swipe from the top - QS is fully expanded and
             // StatusBarState is KEYGUARD. That state doesn't make sense for split shade,
             // where notifications are always visible and we effectively go to fully expanded
@@ -1371,7 +1199,7 @@
             mStatusBarStateController.setState(StatusBarState.SHADE_LOCKED, /* force= */false);
         }
         updateClockAppearance();
-        updateQsState();
+        mQsController.updateQsState();
         mNotificationStackScrollLayoutController.updateFooter();
     }
 
@@ -1479,11 +1307,6 @@
         mNotificationPanelUnfoldAnimationController.ifPresent(u -> u.setup(mView));
     }
 
-    @VisibleForTesting
-    void setQs(QS qs) {
-        mQs = qs;
-    }
-
     private void attachSplitShadeMediaPlayerContainer(FrameLayout container) {
         mKeyguardMediaController.attachSplitShadeContainer(container);
     }
@@ -1515,7 +1338,7 @@
             if (SPEW_LOGCAT) Log.d(TAG, "Skipping computeMaxKeyguardNotifications() by request");
         }
 
-        if (mKeyguardShowing && !mKeyguardBypassController.getBypassEnabled()) {
+        if (getKeyguardShowing() && !mKeyguardBypassController.getBypassEnabled()) {
             mNotificationStackScrollLayoutController.setMaxDisplayedNotifications(
                     mMaxAllowedKeyguardNotifications);
             mNotificationStackScrollLayoutController.setKeyguardBottomPaddingForDebug(
@@ -1564,39 +1387,14 @@
         mIsFullWidth = isFullWidth;
         mScrimController.setClipsQsScrim(isFullWidth);
         mNotificationStackScrollLayoutController.setIsFullWidth(isFullWidth);
-        if (mQs != null) {
-            mQs.setIsNotificationPanelFullWidth(isFullWidth);
-        }
-    }
-
-    private void startQsSizeChangeAnimation(int oldHeight, final int newHeight) {
-        if (mQsSizeChangeAnimator != null) {
-            oldHeight = (int) mQsSizeChangeAnimator.getAnimatedValue();
-            mQsSizeChangeAnimator.cancel();
-        }
-        mQsSizeChangeAnimator = ValueAnimator.ofInt(oldHeight, newHeight);
-        mQsSizeChangeAnimator.setDuration(300);
-        mQsSizeChangeAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
-        mQsSizeChangeAnimator.addUpdateListener(animation -> {
-            requestScrollerTopPaddingUpdate(false /* animate */);
-            updateExpandedHeightToMaxHeight();
-            int height = (int) mQsSizeChangeAnimator.getAnimatedValue();
-            mQs.setHeightOverride(height);
-        });
-        mQsSizeChangeAnimator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                mQsSizeChangeAnimator = null;
-            }
-        });
-        mQsSizeChangeAnimator.start();
+        mQsController.setNotificationPanelFullWidth(isFullWidth);
     }
 
     /**
      * Positions the clock and notifications dynamically depending on how many notifications are
      * showing.
      */
-    private void positionClockAndNotifications() {
+    void positionClockAndNotifications() {
         positionClockAndNotifications(false /* forceUpdate */);
     }
 
@@ -1621,7 +1419,7 @@
                 // so we should not add a padding for them
                 stackScrollerPadding = 0;
             } else {
-                stackScrollerPadding = getUnlockedStackScrollerPadding();
+                stackScrollerPadding = mQsController.getUnlockedStackScrollerPadding();
             }
         } else {
             stackScrollerPadding = mClockPositionResult.stackScrollerPaddingExpanded;
@@ -1669,8 +1467,9 @@
                 userSwitcherHeight,
                 userSwitcherPreferredY,
                 darkAmount, mOverStretchAmount,
-                bypassEnabled, getUnlockedStackScrollerPadding(),
-                computeQsExpansionFraction(),
+                bypassEnabled,
+                mQsController.getUnlockedStackScrollerPadding(),
+                mQsController.computeExpansionFraction(),
                 mDisplayTopInset,
                 mSplitShadeEnabled,
                 udfpsAodTopLocation,
@@ -1822,19 +1621,16 @@
         return mDozing && mDozeParameters.getAlwaysOn();
     }
 
+    boolean isDozing() {
+        return mDozing;
+    }
+
     private boolean hasVisibleNotifications() {
         return mNotificationStackScrollLayoutController
                 .getVisibleNotificationCount() != 0
                 || mMediaDataManager.hasActiveMediaOrRecommendation();
     }
 
-    /**
-     * @return the padding of the stackscroller when unlocked
-     */
-    private int getUnlockedStackScrollerPadding() {
-        return (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight;
-    }
-
     /** Returns space between top of lock icon and bottom of NotificationStackScrollLayout. */
     private float getLockIconPadding() {
         float lockIconPadding = 0f;
@@ -1952,23 +1748,23 @@
         mAnimateNextPositionUpdate = true;
     }
 
-    private void setQsExpansionEnabled() {
-        if (mQs == null) return;
-        mQs.setHeaderClickable(isQsExpansionEnabled());
-    }
+    /** Animate QS closing. */
+    public void animateCloseQs(boolean animateAway) {
+        if (mSplitShadeEnabled) {
+            collapsePanel(true, false, 1.0f);
+        } else {
+            mQsController.animateCloseQs(animateAway);
+        }
 
-    public void setQsExpansionEnabledPolicy(boolean qsExpansionEnabledPolicy) {
-        mQsExpansionEnabledPolicy = qsExpansionEnabledPolicy;
-        setQsExpansionEnabled();
     }
 
     public void resetViews(boolean animate) {
         mGutsManager.closeAndSaveGuts(true /* leavebehind */, true /* force */,
                 true /* controls */, -1 /* x */, -1 /* y */, true /* resetMenu */);
         if (animate && !isFullyCollapsed()) {
-            animateCloseQs(true /* animateAway */);
+            animateCloseQs(true);
         } else {
-            closeQs();
+            closeQsIfPossible();
         }
         mNotificationStackScrollLayoutController.setOverScrollAmount(0f, true /* onTop */, animate,
                 !animate /* cancelAnimators */);
@@ -1999,8 +1795,8 @@
             return;
         }
 
-        if (mQsExpanded) {
-            setQsExpandImmediate(true);
+        if (mQsController.getExpanded()) {
+            mQsController.setExpandImmediate(true);
             setShowShelfOnly(true);
         }
         debugLog("collapse: %s", this);
@@ -2019,33 +1815,11 @@
         }
     }
 
-    @VisibleForTesting
-    void setQsExpandImmediate(boolean expandImmediate) {
-        if (expandImmediate != mQsExpandImmediate) {
-            mQsExpandImmediate = expandImmediate;
-            mShadeExpansionStateManager.notifyExpandImmediateChange(expandImmediate);
-        }
-    }
-
-    @VisibleForTesting
-    boolean isQsExpandImmediate() {
-        return mQsExpandImmediate;
-    }
-
     private void setShowShelfOnly(boolean shelfOnly) {
         mNotificationStackScrollLayoutController.setShouldShowShelfOnly(
                 shelfOnly && !mSplitShadeEnabled);
     }
 
-    public void closeQs() {
-        cancelQsAnimation();
-        setQsExpansionHeight(mQsMinExpansionHeight);
-        // qsExpandImmediate is a safety latch in case we're calling closeQS while we're in the
-        // middle of animation - we need to make sure that value is always false when shade if
-        // fully collapsed or expanded
-        setQsExpandImmediate(false);
-    }
-
     @VisibleForTesting
     void cancelHeightAnimator() {
         if (mHeightAnimator != null) {
@@ -2061,39 +1835,9 @@
         mView.animate().cancel();
     }
 
-    /**
-     * Animate QS closing by flinging it.
-     * If QS is expanded, it will collapse into QQS and stop.
-     * If in split shade, it will collapse the whole shade.
-     *
-     * @param animateAway Do not stop when QS becomes QQS. Fling until QS isn't visible anymore.
-     */
-    public void animateCloseQs(boolean animateAway) {
-        if (mSplitShadeEnabled) {
-            collapsePanel(
-                    /* animate= */true, /* delayed= */false, /* speedUpFactor= */1.0f);
-            return;
-        }
-
-        if (mQsExpansionAnimator != null) {
-            if (!mQsAnimatorExpand) {
-                return;
-            }
-            float height = mQsExpansionHeight;
-            mQsExpansionAnimator.cancel();
-            setQsExpansionHeight(height);
-        }
-        flingSettings(0 /* vel */, animateAway ? FLING_HIDE : FLING_COLLAPSE);
-    }
-
-    private boolean isQsExpansionEnabled() {
-        return mQsExpansionEnabledPolicy && mQsExpansionEnabledAmbient
-                && !mRemoteInputManager.isRemoteInputActive();
-    }
-
     public void expandWithQs() {
-        if (isQsExpansionEnabled()) {
-            setQsExpandImmediate(true);
+        if (mQsController.isExpansionEnabled()) {
+            mQsController.setExpandImmediate(true);
             setShowShelfOnly(true);
         }
         if (mSplitShadeEnabled && isOnKeyguard()) {
@@ -2109,8 +1853,8 @@
         } else if (isFullyCollapsed()) {
             expand(true /* animate */);
         } else {
-            traceQsJank(true /* startTracing */, false /* wasCancelled */);
-            flingSettings(0 /* velocity */, FLING_EXPAND);
+            mQsController.traceQsJank(true /* startTracing */, false /* wasCancelled */);
+            mQsController.flingQs(0, FLING_EXPAND);
         }
     }
 
@@ -2125,8 +1869,8 @@
         if (mSplitShadeEnabled && (isShadeFullyOpen() || isExpanding())) {
             return;
         }
-        if (isQsExpanded()) {
-            flingSettings(0 /* velocity */, FLING_COLLAPSE);
+        if (mQsController.getExpanded()) {
+            mQsController.flingQs(0, FLING_COLLAPSE);
         } else {
             expand(true /* animate */);
         }
@@ -2143,8 +1887,7 @@
     @VisibleForTesting
     void flingToHeight(float vel, boolean expand, float target,
             float collapseSpeedUpFactor, boolean expandBecauseOfFalsing) {
-        mLastFlingWasExpanding = expand;
-        mShadeLog.logLastFlingWasExpanding(expand);
+        mQsController.setLastShadeFlingWasExpanding(expand);
         mHeadsUpTouchHelper.notifyFling(!expand);
         mKeyguardStateController.notifyPanelFlingStart(!expand /* flingingToDismiss */);
         setClosingWithAlphaFadeout(!expand && !isOnKeyguard() && getFadeoutAlpha() == 1.0f);
@@ -2158,7 +1901,6 @@
         // we want to perform an overshoot animation when flinging open
         final boolean addOverscroll =
                 expand
-                        && !mSplitShadeEnabled // Split shade has its own overscroll logic
                         && mStatusBarStateController.getState() != KEYGUARD
                         && mOverExpansion == 0.0f
                         && vel >= 0;
@@ -2216,7 +1958,7 @@
             @Override
             public void onAnimationStart(Animator animation) {
                 if (!mStatusBarStateController.isDozing()) {
-                    beginJankMonitoring();
+                    mQsController.beginJankMonitoring(isFullyCollapsed());
                 }
             }
 
@@ -2248,117 +1990,15 @@
         setAnimator(null);
         mKeyguardStateController.notifyPanelFlingEnd();
         if (!cancelled) {
-            endJankMonitoring();
+            mQsController.endJankMonitoring();
             notifyExpandingFinished();
         } else {
-            cancelJankMonitoring();
+            mQsController.cancelJankMonitoring();
         }
         updatePanelExpansionAndVisibility();
         mNotificationStackScrollLayoutController.setPanelFlinging(false);
     }
 
-    private boolean onQsIntercept(MotionEvent event) {
-        debugLog("onQsIntercept");
-        int pointerIndex = event.findPointerIndex(mQsTrackingPointer);
-        if (pointerIndex < 0) {
-            pointerIndex = 0;
-            mQsTrackingPointer = event.getPointerId(pointerIndex);
-        }
-        final float x = event.getX(pointerIndex);
-        final float y = event.getY(pointerIndex);
-
-        switch (event.getActionMasked()) {
-            case MotionEvent.ACTION_DOWN:
-                mInitialTouchY = y;
-                mInitialTouchX = x;
-                initVelocityTracker();
-                trackMovement(event);
-                float qsExpansionFraction = computeQsExpansionFraction();
-                // Intercept the touch if QS is between fully collapsed and fully expanded state
-                if (!mSplitShadeEnabled
-                        && qsExpansionFraction > 0.0 && qsExpansionFraction < 1.0) {
-                    mShadeLog.logMotionEvent(event,
-                            "onQsIntercept: down action, QS partially expanded/collapsed");
-                    return true;
-                }
-                if (mKeyguardShowing
-                        && shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, 0)) {
-                    // Dragging down on the lockscreen statusbar should prohibit other interactions
-                    // immediately, otherwise we'll wait on the touchslop. This is to allow
-                    // dragging down to expanded quick settings directly on the lockscreen.
-                    mView.getParent().requestDisallowInterceptTouchEvent(true);
-                }
-                if (mQsExpansionAnimator != null) {
-                    mInitialHeightOnTouch = mQsExpansionHeight;
-                    mShadeLog.logMotionEvent(event,
-                            "onQsIntercept: down action, QS tracking enabled");
-                    mQsTracking = true;
-                    traceQsJank(true /* startTracing */, false /* wasCancelled */);
-                    mNotificationStackScrollLayoutController.cancelLongPress();
-                }
-                break;
-            case MotionEvent.ACTION_POINTER_UP:
-                final int upPointer = event.getPointerId(event.getActionIndex());
-                if (mQsTrackingPointer == upPointer) {
-                    // gesture is ongoing, find a new pointer to track
-                    final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
-                    mQsTrackingPointer = event.getPointerId(newIndex);
-                    mInitialTouchX = event.getX(newIndex);
-                    mInitialTouchY = event.getY(newIndex);
-                }
-                break;
-
-            case MotionEvent.ACTION_MOVE:
-                final float h = y - mInitialTouchY;
-                trackMovement(event);
-                if (mQsTracking) {
-
-                    // Already tracking because onOverscrolled was called. We need to update here
-                    // so we don't stop for a frame until the next touch event gets handled in
-                    // onTouchEvent.
-                    setQsExpansionHeight(h + mInitialHeightOnTouch);
-                    trackMovement(event);
-                    return true;
-                } else {
-                    mShadeLog.logMotionEvent(event,
-                            "onQsIntercept: move ignored because qs tracking disabled");
-                }
-                float touchSlop = getTouchSlop(event);
-                if ((h > touchSlop || (h < -touchSlop && mQsExpanded))
-                        && Math.abs(h) > Math.abs(x - mInitialTouchX)
-                        && shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, h)) {
-                    mView.getParent().requestDisallowInterceptTouchEvent(true);
-                    mShadeLog.onQsInterceptMoveQsTrackingEnabled(h);
-                    mQsTracking = true;
-                    traceQsJank(true /* startTracing */, false /* wasCancelled */);
-                    onQsExpansionStarted();
-                    notifyExpandingFinished();
-                    mInitialHeightOnTouch = mQsExpansionHeight;
-                    mInitialTouchY = y;
-                    mInitialTouchX = x;
-                    mNotificationStackScrollLayoutController.cancelLongPress();
-                    return true;
-                } else {
-                    mShadeLog.logQsTrackingNotStarted(mInitialTouchY, y, h, touchSlop, mQsExpanded,
-                            mCollapsedOnDown, mKeyguardShowing, isQsExpansionEnabled());
-                }
-                break;
-
-            case MotionEvent.ACTION_CANCEL:
-            case MotionEvent.ACTION_UP:
-                trackMovement(event);
-                mShadeLog.logMotionEvent(event, "onQsIntercept: up action, QS tracking disabled");
-                mQsTracking = false;
-                break;
-        }
-        return false;
-    }
-
-    @VisibleForTesting
-    boolean isQsTracking() {
-        return mQsTracking;
-    }
-
     private boolean isInContentBounds(float x, float y) {
         float stackScrollerX = mNotificationStackScrollLayoutController.getX();
         return !mNotificationStackScrollLayoutController
@@ -2367,29 +2007,14 @@
                 && x < stackScrollerX + mNotificationStackScrollLayoutController.getWidth();
     }
 
-    private void traceQsJank(boolean startTracing, boolean wasCancelled) {
-        if (mInteractionJankMonitor == null) {
-            return;
-        }
-        if (startTracing) {
-            mInteractionJankMonitor.begin(mView, CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE);
-        } else {
-            if (wasCancelled) {
-                mInteractionJankMonitor.cancel(CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE);
-            } else {
-                mInteractionJankMonitor.end(CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE);
-            }
-        }
-    }
-
     private void initDownStates(MotionEvent event) {
         if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
-            mQsTouchAboveFalsingThreshold = mQsFullyExpanded;
             mDozingOnDown = mDozing;
             mDownX = event.getX();
             mDownY = event.getY();
             mCollapsedOnDown = isFullyCollapsed();
-            mIsPanelCollapseOnQQS = canPanelCollapseOnQQS(mDownX, mDownY);
+            mQsController.setCollapsedOnDown(mCollapsedOnDown);
+            mIsPanelCollapseOnQQS = mQsController.canPanelCollapseOnQQS(mDownX, mDownY);
             mListenForHeadsUp = mCollapsedOnDown && mHeadsUpManager.hasPinnedHeadsUp();
             mAllowExpandForSmallExpansion = mExpectingSynthesizedDown;
             mTouchSlopExceededBeforeDown = mExpectingSynthesizedDown;
@@ -2399,7 +2024,7 @@
                     event.getEventTime(),
                     mDownX,
                     mDownY,
-                    mQsTouchAboveFalsingThreshold,
+                    mQsController.updateAndGetTouchAboveFalsingThreshold(),
                     mDozingOnDown,
                     mCollapsedOnDown,
                     mIsPanelCollapseOnQQS,
@@ -2414,84 +2039,14 @@
         }
     }
 
-    /**
-     * Can the panel collapse in this motion because it was started on QQS?
-     *
-     * @param downX the x location where the touch started
-     * @param downY the y location where the touch started
-     * @return true if the panel could be collapsed because it stared on QQS
-     */
-    private boolean canPanelCollapseOnQQS(float downX, float downY) {
-        if (mCollapsedOnDown || mKeyguardShowing || mQsExpanded) {
-            return false;
-        }
-        View header = mQs == null ? mKeyguardStatusBar : mQs.getHeader();
-        return downX >= mQsFrame.getX() && downX <= mQsFrame.getX() + mQsFrame.getWidth()
-                && downY <= header.getBottom();
-
-    }
-
-    private void flingQsWithCurrentVelocity(float y, boolean isCancelMotionEvent) {
-        float vel = getCurrentQSVelocity();
-        boolean expandsQs = flingExpandsQs(vel);
-        if (expandsQs) {
-            if (mFalsingManager.isUnlockingDisabled() || isFalseTouch()) {
-                expandsQs = false;
-            } else {
-                logQsSwipeDown(y);
-            }
-        } else if (vel < 0) {
-            mFalsingManager.isFalseTouch(QS_COLLAPSE);
-        }
-
-        int flingType;
-        if (expandsQs && !isCancelMotionEvent) {
-            flingType = FLING_EXPAND;
-        } else if (mSplitShadeEnabled) {
-            flingType = FLING_HIDE;
-        } else {
-            flingType = FLING_COLLAPSE;
-        }
-        flingSettings(vel, flingType);
-    }
-
-    private void logQsSwipeDown(float y) {
-        float vel = getCurrentQSVelocity();
-        final int
-                gesture =
-                mBarState == KEYGUARD ? MetricsEvent.ACTION_LS_QS
-                        : MetricsEvent.ACTION_SHADE_QS_PULL;
-        mLockscreenGestureLogger.write(gesture,
-                (int) ((y - mInitialTouchY) / mCentralSurfaces.getDisplayDensity()),
-                (int) (vel / mCentralSurfaces.getDisplayDensity()));
-    }
-
-    private boolean flingExpandsQs(float vel) {
+    boolean flingExpandsQs(float vel) {
         if (Math.abs(vel) < mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
-            return computeQsExpansionFraction() > 0.5f;
+            return mQsController.computeExpansionFraction() > 0.5f;
         } else {
             return vel > 0;
         }
     }
 
-    private boolean isFalseTouch() {
-        if (mFalsingManager.isClassifierEnabled()) {
-            return mFalsingManager.isFalseTouch(Classifier.QUICK_SETTINGS);
-        }
-        return !mQsTouchAboveFalsingThreshold;
-    }
-
-    private float computeQsExpansionFraction() {
-        if (mQSAnimatingHiddenFromCollapsed) {
-            // When hiding QS from collapsed state, the expansion can sometimes temporarily
-            // be larger than 0 because of the timing, leading to flickers.
-            return 0.0f;
-        }
-        return Math.min(
-                1f, (mQsExpansionHeight - mQsMinExpansionHeight) / (mQsMaxExpansionHeight
-                        - mQsMinExpansionHeight));
-    }
-
     private boolean shouldExpandWhenNotFlinging() {
         if (getExpandedFraction() > 0.5f) {
             return true;
@@ -2509,121 +2064,13 @@
         return mNotificationStackScrollLayoutController.getOpeningHeight();
     }
 
-
-    private boolean handleQsTouch(MotionEvent event) {
-        if (isSplitShadeAndTouchXOutsideQs(event.getX())) {
-            return false;
-        }
-        final int action = event.getActionMasked();
-        boolean collapsedQs = !mQsExpanded && !mSplitShadeEnabled;
-        boolean expandedShadeCollapsedQs = getExpandedFraction() == 1f && mBarState != KEYGUARD
-                && collapsedQs && isQsExpansionEnabled();
-        if (action == MotionEvent.ACTION_DOWN && expandedShadeCollapsedQs) {
-            // Down in the empty area while fully expanded - go to QS.
-            mShadeLog.logMotionEvent(event, "handleQsTouch: down action, QS tracking enabled");
-            mQsTracking = true;
-            traceQsJank(true /* startTracing */, false /* wasCancelled */);
-            mConflictingQsExpansionGesture = true;
-            onQsExpansionStarted();
-            mInitialHeightOnTouch = mQsExpansionHeight;
-            mInitialTouchY = event.getY();
-            mInitialTouchX = event.getX();
-        }
-        if (!isFullyCollapsed() && !isShadeOrQsHeightAnimationRunning()) {
-            handleQsDown(event);
-        }
-        // defer touches on QQS to shade while shade is collapsing. Added margin for error
-        // as sometimes the qsExpansionFraction can be a tiny value instead of 0 when in QQS.
-        if (!mSplitShadeEnabled && !mLastFlingWasExpanding
-                && computeQsExpansionFraction() <= 0.01 && getExpandedFraction() < 1.0) {
-            mShadeLog.logMotionEvent(event,
-                    "handleQsTouch: shade touched while collapsing, QS tracking disabled");
-            mQsTracking = false;
-        }
-        if (!mQsExpandImmediate && mQsTracking) {
-            onQsTouch(event);
-            if (!mConflictingQsExpansionGesture && !mSplitShadeEnabled) {
-                mShadeLog.logMotionEvent(event,
-                        "handleQsTouch: not immediate expand or conflicting gesture");
-                return true;
-            }
-        }
-        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
-            mConflictingQsExpansionGesture = false;
-        }
-        if (action == MotionEvent.ACTION_DOWN && isFullyCollapsed() && isQsExpansionEnabled()) {
-            mTwoFingerQsExpandPossible = true;
-        }
-        if (mTwoFingerQsExpandPossible && isOpenQsEvent(event) && event.getY(event.getActionIndex())
-                < mStatusBarMinHeight) {
-            mMetricsLogger.count(COUNTER_PANEL_OPEN_QS, 1);
-            setQsExpandImmediate(true);
-            setShowShelfOnly(true);
-            updateExpandedHeightToMaxHeight();
-
-            // Normally, we start listening when the panel is expanded, but here we need to start
-            // earlier so the state is already up to date when dragging down.
-            setListening(true);
-        }
-        return false;
+    float getDisplayDensity() {
+        return mCentralSurfaces.getDisplayDensity();
     }
 
-    /** Returns whether split shade is enabled and an x coordinate is outside of the QS frame. */
-    private boolean isSplitShadeAndTouchXOutsideQs(float touchX) {
-        return mSplitShadeEnabled && (touchX < mQsFrame.getX()
-                || touchX > mQsFrame.getX() + mQsFrame.getWidth());
-    }
-
-    private boolean isInQsArea(float x, float y) {
-        if (isSplitShadeAndTouchXOutsideQs(x)) {
-            return false;
-        }
-        // Let's reject anything at the very bottom around the home handle in gesture nav
-        if (mIsGestureNavigation && y > mView.getHeight() - mNavigationBarBottomHeight) {
-            return false;
-        }
-        return y <= mNotificationStackScrollLayoutController.getBottomMostNotificationBottom()
-                || y <= mQs.getView().getY() + mQs.getView().getHeight();
-    }
-
-    private boolean isOpenQsEvent(MotionEvent event) {
-        final int pointerCount = event.getPointerCount();
-        final int action = event.getActionMasked();
-
-        final boolean
-                twoFingerDrag =
-                action == MotionEvent.ACTION_POINTER_DOWN && pointerCount == 2;
-
-        final boolean
-                stylusButtonClickDrag =
-                action == MotionEvent.ACTION_DOWN && (event.isButtonPressed(
-                        MotionEvent.BUTTON_STYLUS_PRIMARY) || event.isButtonPressed(
-                        MotionEvent.BUTTON_STYLUS_SECONDARY));
-
-        final boolean
-                mouseButtonClickDrag =
-                action == MotionEvent.ACTION_DOWN && (event.isButtonPressed(
-                        MotionEvent.BUTTON_SECONDARY) || event.isButtonPressed(
-                        MotionEvent.BUTTON_TERTIARY));
-
-        return twoFingerDrag || stylusButtonClickDrag || mouseButtonClickDrag;
-    }
-
-    private void handleQsDown(MotionEvent event) {
-        if (event.getActionMasked() == MotionEvent.ACTION_DOWN && shouldQuickSettingsIntercept(
-                event.getX(), event.getY(), -1)) {
-            debugLog("handleQsDown");
-            mFalsingCollector.onQsDown();
-            mShadeLog.logMotionEvent(event, "handleQsDown: down action, QS tracking enabled");
-            mQsTracking = true;
-            onQsExpansionStarted();
-            mInitialHeightOnTouch = mQsExpansionHeight;
-            mInitialTouchY = event.getY();
-            mInitialTouchX = event.getX();
-
-            // If we interrupt an expansion gesture here, make sure to update the state correctly.
-            notifyExpandingFinished();
-        }
+    /** Return whether a touch is near the gesture handle at the bottom of screen */
+    public boolean isInGestureNavHomeHandleArea(float x, float y) {
+        return mIsGestureNavigation && y > mView.getHeight() - mNavigationBarBottomHeight;
     }
 
     /** Input focus transfer is about to happen. */
@@ -2680,7 +2127,7 @@
         }
 
         // If we are already running a QS expansion, make sure that we keep the panel open.
-        if (mQsExpansionAnimator != null) {
+        if (mQsController.isExpansionAnimating()) {
             expands = true;
         }
         return expands;
@@ -2694,124 +2141,9 @@
         return isFullyCollapsed() || mBarState != StatusBarState.SHADE;
     }
 
-    private void onQsTouch(MotionEvent event) {
-        int pointerIndex = event.findPointerIndex(mQsTrackingPointer);
-        if (pointerIndex < 0) {
-            pointerIndex = 0;
-            mQsTrackingPointer = event.getPointerId(pointerIndex);
-        }
-        final float y = event.getY(pointerIndex);
-        final float x = event.getX(pointerIndex);
-        final float h = y - mInitialTouchY;
-
-        switch (event.getActionMasked()) {
-            case MotionEvent.ACTION_DOWN:
-                mShadeLog.logMotionEvent(event, "onQsTouch: down action, QS tracking enabled");
-                mQsTracking = true;
-                traceQsJank(true /* startTracing */, false /* wasCancelled */);
-                mInitialTouchY = y;
-                mInitialTouchX = x;
-                onQsExpansionStarted();
-                mInitialHeightOnTouch = mQsExpansionHeight;
-                initVelocityTracker();
-                trackMovement(event);
-                break;
-
-            case MotionEvent.ACTION_POINTER_UP:
-                final int upPointer = event.getPointerId(event.getActionIndex());
-                if (mQsTrackingPointer == upPointer) {
-                    // gesture is ongoing, find a new pointer to track
-                    final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
-                    final float newY = event.getY(newIndex);
-                    final float newX = event.getX(newIndex);
-                    mQsTrackingPointer = event.getPointerId(newIndex);
-                    mInitialHeightOnTouch = mQsExpansionHeight;
-                    mInitialTouchY = newY;
-                    mInitialTouchX = newX;
-                }
-                break;
-
-            case MotionEvent.ACTION_MOVE:
-                debugLog("onQSTouch move");
-                mShadeLog.logMotionEvent(event, "onQsTouch: move action, setting QS expansion");
-                setQsExpansionHeight(h + mInitialHeightOnTouch);
-                if (h >= getFalsingThreshold()) {
-                    mQsTouchAboveFalsingThreshold = true;
-                }
-                trackMovement(event);
-                break;
-
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                mShadeLog.logMotionEvent(event,
-                        "onQsTouch: up/cancel action, QS tracking disabled");
-                mQsTracking = false;
-                mQsTrackingPointer = -1;
-                trackMovement(event);
-                float fraction = computeQsExpansionFraction();
-                if (fraction != 0f || y >= mInitialTouchY) {
-                    flingQsWithCurrentVelocity(y,
-                            event.getActionMasked() == MotionEvent.ACTION_CANCEL);
-                } else {
-                    traceQsJank(false /* startTracing */,
-                            event.getActionMasked() == MotionEvent.ACTION_CANCEL);
-                }
-                if (mQsVelocityTracker != null) {
-                    mQsVelocityTracker.recycle();
-                    mQsVelocityTracker = null;
-                }
-                break;
-        }
-    }
-
-    private int getFalsingThreshold() {
+    int getFalsingThreshold() {
         float factor = mCentralSurfaces.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
-        return (int) (mQsFalsingThreshold * factor);
-    }
-
-    private void setOverScrolling(boolean overscrolling) {
-        mStackScrollerOverscrolling = overscrolling;
-        if (mQs == null) return;
-        mQs.setOverscrolling(overscrolling);
-    }
-
-    private void onQsExpansionStarted() {
-        cancelQsAnimation();
-        cancelHeightAnimator();
-
-        // Reset scroll position and apply that position to the expanded height.
-        float height = mQsExpansionHeight;
-        setQsExpansionHeight(height);
-        mNotificationStackScrollLayoutController.checkSnoozeLeavebehind();
-
-        // When expanding QS, let's authenticate the user if possible,
-        // this will speed up notification actions.
-        if (height == 0 && !mKeyguardStateController.canDismissLockScreen()) {
-            mUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.QS_EXPANDED);
-        }
-    }
-
-    @VisibleForTesting
-    void setQsExpanded(boolean expanded) {
-        boolean changed = mQsExpanded != expanded;
-        if (changed) {
-            mQsExpanded = expanded;
-            updateQsState();
-            updateExpandedHeightToMaxHeight();
-            setStatusAccessibilityImportance(expanded
-                    ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
-                    : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
-            updateSystemUiStateFlags();
-            NavigationBarView navigationBarView =
-                    mNavigationBarController.getNavigationBarView(mDisplayId);
-            if (navigationBarView != null) {
-                navigationBarView.onStatusBarPanelStateChanged();
-            }
-            mShadeExpansionStateManager.onQsExpansionChanged(expanded);
-            mShadeLog.logQsExpansionChanged("QS Expansion Changed.", expanded,
-                    mQsMinExpansionHeight, mQsMaxExpansionHeight, mStackScrollerOverscrolling,
-                    mDozing, mQsAnimatorExpand, mAnimatingQS);
-        }
+        return (int) (mQsController.getFalsingThreshold() * factor);
     }
 
     private void maybeAnimateBottomAreaAlpha() {
@@ -2843,403 +2175,29 @@
         }
     }
 
-    private void updateQsState() {
-        boolean qsFullScreen = mQsExpanded && !mSplitShadeEnabled;
-        mNotificationStackScrollLayoutController.setQsFullScreen(qsFullScreen);
-        mNotificationStackScrollLayoutController.setScrollingEnabled(
-                mBarState != KEYGUARD && (!qsFullScreen || mQsExpansionFromOverscroll));
-
-        if (mKeyguardUserSwitcherController != null && mQsExpanded
-                && !mStackScrollerOverscrolling) {
-            mKeyguardUserSwitcherController.closeSwitcherIfOpenAndNotSimple(true);
-        }
-        if (mQs == null) return;
-        mQs.setExpanded(mQsExpanded);
-    }
-
-    void setQsExpansionHeight(float height) {
-        height = Math.min(Math.max(height, mQsMinExpansionHeight), mQsMaxExpansionHeight);
-        mQsFullyExpanded = height == mQsMaxExpansionHeight && mQsMaxExpansionHeight != 0;
-        boolean qsAnimatingAway = !mQsAnimatorExpand && mAnimatingQS;
-        if (height > mQsMinExpansionHeight && !mQsExpanded && !mStackScrollerOverscrolling
-                && !mDozing && !qsAnimatingAway) {
-            setQsExpanded(true);
-        } else if (height <= mQsMinExpansionHeight && mQsExpanded) {
-            setQsExpanded(false);
-        }
-        mQsExpansionHeight = height;
-        updateQsExpansion();
-        requestScrollerTopPaddingUpdate(false /* animate */);
-        mKeyguardStatusBarViewController.updateViewState();
-        if (mBarState == StatusBarState.SHADE_LOCKED || mBarState == KEYGUARD) {
-            updateKeyguardBottomAreaAlpha();
-            positionClockAndNotifications();
-        }
-
-        if (mAccessibilityManager.isEnabled()) {
-            mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
-        }
-
-        if (!mFalsingManager.isUnlockingDisabled() && mQsFullyExpanded
-                && mFalsingCollector.shouldEnforceBouncer()) {
-            mCentralSurfaces.executeRunnableDismissingKeyguard(null, null /* cancelAction */,
-                    false /* dismissShade */, true /* afterKeyguardGone */, false /* deferred */);
-        }
-        if (DEBUG_DRAWABLE) {
-            mView.invalidate();
-        }
-    }
-
-    private void updateQsExpansion() {
-        if (mQs == null) return;
-        final float squishiness;
-        if ((mQsExpandImmediate || mQsExpanded) && !mSplitShadeEnabled) {
-            squishiness = 1;
-        } else if (mTransitioningToFullShadeProgress > 0.0f) {
-            squishiness = mLockscreenShadeTransitionController.getQsSquishTransitionFraction();
-        } else {
-            squishiness = mNotificationStackScrollLayoutController
-                    .getNotificationSquishinessFraction();
-        }
-        final float qsExpansionFraction = computeQsExpansionFraction();
-        final float adjustedExpansionFraction = mSplitShadeEnabled
-                ? 1f : computeQsExpansionFraction();
-        mQs.setQsExpansion(adjustedExpansionFraction, getExpandedFraction(), getHeaderTranslation(),
-                squishiness);
-        mMediaHierarchyManager.setQsExpansion(qsExpansionFraction);
-        int qsPanelBottomY = calculateQsBottomPosition(qsExpansionFraction);
-        mScrimController.setQsPosition(qsExpansionFraction, qsPanelBottomY);
-        setQSClippingBounds();
-
-        if (mSplitShadeEnabled) {
-            // In split shade we want to pretend that QS are always collapsed so their behaviour and
-            // interactions don't influence notifications as they do in portrait. But we want to set
-            // 0 explicitly in case we're rotating from non-split shade with QS expansion of 1.
-            mNotificationStackScrollLayoutController.setQsExpansionFraction(0);
-        } else {
-            mNotificationStackScrollLayoutController.setQsExpansionFraction(qsExpansionFraction);
-        }
-
-        mDepthController.setQsPanelExpansion(qsExpansionFraction);
-        mStatusBarKeyguardViewManager.setQsExpansion(qsExpansionFraction);
-
-        float shadeExpandedFraction = isOnKeyguard()
-                ? getLockscreenShadeDragProgress()
-                : getExpandedFraction();
-        mLargeScreenShadeHeaderController.setShadeExpandedFraction(shadeExpandedFraction);
-        mLargeScreenShadeHeaderController.setQsExpandedFraction(qsExpansionFraction);
-        mLargeScreenShadeHeaderController.setQsVisible(mQsVisible);
-    }
-
-    private float getLockscreenShadeDragProgress() {
+    /** */
+    public float getLockscreenShadeDragProgress() {
         // mTransitioningToFullShadeProgress > 0 means we're doing regular lockscreen to shade
         // transition. If that's not the case we should follow QS expansion fraction for when
         // user is pulling from the same top to go directly to expanded QS
-        return mTransitioningToFullShadeProgress > 0
+        return mQsController.getTransitioningToFullShadeProgress() > 0
                 ? mLockscreenShadeTransitionController.getQSDragProgress()
-                : computeQsExpansionFraction();
+                : mQsController.computeExpansionFraction();
     }
 
-    private void onStackYChanged(boolean shouldAnimate) {
-        if (mQs != null) {
-            if (shouldAnimate) {
-                animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_STANDARD,
-                        0 /* delay */);
-                mNotificationBoundsAnimationDelay = 0;
-            }
-            setQSClippingBounds();
-        }
-    }
-
-    private void onNotificationScrolled(int newScrollPosition) {
-        updateQSExpansionEnabledAmbient();
-    }
-
-    private void updateQSExpansionEnabledAmbient() {
-        final float scrollRangeToTop = mAmbientState.getTopPadding() - mQuickQsHeaderHeight;
-        mQsExpansionEnabledAmbient = mSplitShadeEnabled
-                || (mAmbientState.getScrollY() <= scrollRangeToTop);
-        setQsExpansionEnabled();
-    }
-
-    /**
-     * Updates scrim bounds, QS clipping, notifications clipping and keyguard status view clipping
-     * as well based on the bounds of the shade and QS state.
-     */
-    private void setQSClippingBounds() {
-        float qsExpansionFraction = computeQsExpansionFraction();
-        final int qsPanelBottomY = calculateQsBottomPosition(qsExpansionFraction);
-        final boolean qsVisible = (qsExpansionFraction > 0 || qsPanelBottomY > 0);
-        checkCorrectScrimVisibility(qsExpansionFraction);
-
-        int top = calculateTopQsClippingBound(qsPanelBottomY);
-        int bottom = calculateBottomQsClippingBound(top);
-        int left = calculateLeftQsClippingBound();
-        int right = calculateRightQsClippingBound();
-        // top should never be lower than bottom, otherwise it will be invisible.
-        top = Math.min(top, bottom);
-        applyQSClippingBounds(left, top, right, bottom, qsVisible);
-    }
-
-    private void checkCorrectScrimVisibility(float expansionFraction) {
-        // issues with scrims visible on keyguard occur only in split shade
-        if (mSplitShadeEnabled) {
-            boolean keyguardViewsVisible = mBarState == KEYGUARD && mKeyguardOnlyContentAlpha == 1;
-            // expansionFraction == 1 means scrims are fully visible as their size/visibility depend
-            // on QS expansion
-            if (expansionFraction == 1 && keyguardViewsVisible) {
-                Log.wtf(TAG,
-                        "Incorrect state, scrim is visible at the same time when clock is visible");
-            }
-        }
-    }
-
-    private int calculateTopQsClippingBound(int qsPanelBottomY) {
-        int top;
-        if (mSplitShadeEnabled) {
-            top = Math.min(qsPanelBottomY, mLargeScreenShadeHeaderHeight);
-        } else {
-            if (mTransitioningToFullShadeProgress > 0.0f) {
-                // If we're transitioning, let's use the actual value. The else case
-                // can be wrong during transitions when waiting for the keyguard to unlock
-                top = mTransitionToFullShadeQSPosition;
-            } else {
-                final float notificationTop = getQSEdgePosition();
-                if (isOnKeyguard()) {
-                    if (mKeyguardBypassController.getBypassEnabled()) {
-                        // When bypassing on the keyguard, let's use the panel bottom.
-                        // this should go away once we unify the stackY position and don't have
-                        // to do this min anymore below.
-                        top = qsPanelBottomY;
-                    } else {
-                        top = (int) Math.min(qsPanelBottomY, notificationTop);
-                    }
-                } else {
-                    top = (int) notificationTop;
-                }
-            }
-            top += mOverStretchAmount;
-            // Correction for instant expansion caused by HUN pull down/
-            if (mMinFraction > 0f && mMinFraction < 1f) {
-                float realFraction =
-                        (getExpandedFraction() - mMinFraction) / (1f - mMinFraction);
-                top *= MathUtils.saturate(realFraction / mMinFraction);
-            }
-        }
-        return top;
-    }
-
-    private int calculateBottomQsClippingBound(int top) {
-        if (mSplitShadeEnabled) {
-            return top + mNotificationStackScrollLayoutController.getHeight()
-                    + mSplitShadeNotificationsScrimMarginBottom;
-        } else {
-            return mView.getBottom();
-        }
-    }
-
-    private int calculateLeftQsClippingBound() {
-        if (mIsFullWidth) {
-            // left bounds can ignore insets, it should always reach the edge of the screen
-            return 0;
-        } else {
-            return mNotificationStackScrollLayoutController.getLeft() + mDisplayLeftInset;
-        }
-    }
-
-    private int calculateRightQsClippingBound() {
-        if (mIsFullWidth) {
-            return mView.getRight() + mDisplayRightInset;
-        } else {
-            return mNotificationStackScrollLayoutController.getRight() + mDisplayLeftInset;
-        }
-    }
-
-    /**
-     * Applies clipping to quick settings, notifications layout and
-     * updates bounds of the notifications background (notifications scrim).
-     *
-     * The parameters are bounds of the notifications area rectangle, this function
-     * calculates bounds for the QS clipping based on the notifications bounds.
-     */
-    private void applyQSClippingBounds(int left, int top, int right, int bottom,
-            boolean qsVisible) {
-        if (!mAnimateNextNotificationBounds || mLastQsClipBounds.isEmpty()) {
-            if (mQsClippingAnimation != null) {
-                // update the end position of the animator
-                mQsClippingAnimationEndBounds.set(left, top, right, bottom);
-            } else {
-                applyQSClippingImmediately(left, top, right, bottom, qsVisible);
-            }
-        } else {
-            mQsClippingAnimationEndBounds.set(left, top, right, bottom);
-            final int startLeft = mLastQsClipBounds.left;
-            final int startTop = mLastQsClipBounds.top;
-            final int startRight = mLastQsClipBounds.right;
-            final int startBottom = mLastQsClipBounds.bottom;
-            if (mQsClippingAnimation != null) {
-                mQsClippingAnimation.cancel();
-            }
-            mQsClippingAnimation = ValueAnimator.ofFloat(0.0f, 1.0f);
-            mQsClippingAnimation.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
-            mQsClippingAnimation.setDuration(mNotificationBoundsAnimationDuration);
-            mQsClippingAnimation.setStartDelay(mNotificationBoundsAnimationDelay);
-            mQsClippingAnimation.addUpdateListener(animation -> {
-                float fraction = animation.getAnimatedFraction();
-                int animLeft = (int) MathUtils.lerp(startLeft,
-                        mQsClippingAnimationEndBounds.left, fraction);
-                int animTop = (int) MathUtils.lerp(startTop,
-                        mQsClippingAnimationEndBounds.top, fraction);
-                int animRight = (int) MathUtils.lerp(startRight,
-                        mQsClippingAnimationEndBounds.right, fraction);
-                int animBottom = (int) MathUtils.lerp(startBottom,
-                        mQsClippingAnimationEndBounds.bottom, fraction);
-                applyQSClippingImmediately(animLeft, animTop, animRight, animBottom,
-                        qsVisible /* qsVisible */);
-            });
-            mQsClippingAnimation.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    mQsClippingAnimation = null;
-                    mIsQsTranslationResetAnimator = false;
-                    mIsPulseExpansionResetAnimator = false;
-                }
-            });
-            mQsClippingAnimation.start();
-        }
-        mAnimateNextNotificationBounds = false;
-        mNotificationBoundsAnimationDelay = 0;
-    }
-
-    private void applyQSClippingImmediately(int left, int top, int right, int bottom,
-            boolean qsVisible) {
-        int radius = mScrimCornerRadius;
-        boolean clipStatusView = false;
-        mLastQsClipBounds.set(left, top, right, bottom);
-        if (mIsFullWidth) {
-            clipStatusView = qsVisible;
-            float screenCornerRadius = mRecordingController.isRecording() ? 0 : mScreenCornerRadius;
-            radius = (int) MathUtils.lerp(screenCornerRadius, mScrimCornerRadius,
-                    Math.min(top / (float) mScrimCornerRadius, 1f));
-        }
-        if (mQs != null) {
-            float qsTranslation = 0;
-            boolean pulseExpanding = mPulseExpansionHandler.isExpanding();
-            if (mTransitioningToFullShadeProgress > 0.0f || pulseExpanding
-                    || (mQsClippingAnimation != null
-                    && (mIsQsTranslationResetAnimator || mIsPulseExpansionResetAnimator))) {
-                if (pulseExpanding || mIsPulseExpansionResetAnimator) {
-                    // qsTranslation should only be positive during pulse expansion because it's
-                    // already translating in from the top
-                    qsTranslation = Math.max(0, (top - mQs.getHeader().getHeight()) / 2.0f);
-                } else if (!mSplitShadeEnabled) {
-                    qsTranslation = (top - mQs.getHeader().getHeight()) * QS_PARALLAX_AMOUNT;
-                }
-            }
-            mQsTranslationForFullShadeTransition = qsTranslation;
-            updateQsFrameTranslation();
-            float currentTranslation = mQsFrame.getTranslationY();
-            mQsClipTop = mEnableQsClipping
-                    ? (int) (top - currentTranslation - mQsFrame.getTop()) : 0;
-            mQsClipBottom = mEnableQsClipping
-                    ? (int) (bottom - currentTranslation - mQsFrame.getTop()) : 0;
-            mQsVisible = qsVisible;
-            mQs.setQsVisible(mQsVisible);
-            mQs.setFancyClipping(
-                    mQsClipTop,
-                    mQsClipBottom,
-                    radius,
-                    qsVisible && !mSplitShadeEnabled);
-            mKeyguardInteractor.setQuickSettingsVisible(mQsVisible);
-        }
-        // The padding on this area is large enough that we can use a cheaper clipping strategy
-        mKeyguardStatusViewController.setClipBounds(clipStatusView ? mLastQsClipBounds : null);
-        // Increase the height of the notifications scrim when not in split shade
-        // (e.g. portrait tablet) so the rounded corners are not visible at the bottom,
-        // in this case they are rendered off-screen
-        final int notificationsScrimBottom = mSplitShadeEnabled ? bottom : bottom + radius;
-        mScrimController.setNotificationsBounds(left, top, right, notificationsScrimBottom);
-
-        if (mSplitShadeEnabled) {
-            mKeyguardStatusBarViewController.setNoTopClipping();
-        } else {
-            mKeyguardStatusBarViewController.updateTopClipping(top);
-        }
-
-        mScrimController.setScrimCornerRadius(radius);
-
-        // Convert global clipping coordinates to local ones,
-        // relative to NotificationStackScrollLayout
-        int nsslLeft = calculateNsslLeft(left);
-        int nsslRight = calculateNsslRight(right);
-        int nsslTop = getNotificationsClippingTopBounds(top);
-        int nsslBottom = bottom - mNotificationStackScrollLayoutController.getTop();
-        int bottomRadius = mSplitShadeEnabled ? radius : 0;
-        int topRadius = mSplitShadeEnabled && mExpandingFromHeadsUp ? 0 : radius;
-        mNotificationStackScrollLayoutController.setRoundedClippingBounds(
-                nsslLeft, nsslTop, nsslRight, nsslBottom, topRadius, bottomRadius);
-    }
-
-    private int calculateNsslLeft(int nsslLeftAbsolute) {
-        int left = nsslLeftAbsolute - mNotificationStackScrollLayoutController.getLeft();
-        if (mIsFullWidth) {
-            return left;
-        }
-        return left - mDisplayLeftInset;
-    }
-
-    private int calculateNsslRight(int nsslRightAbsolute) {
-        int right = nsslRightAbsolute - mNotificationStackScrollLayoutController.getLeft();
-        if (mIsFullWidth) {
-            return right;
-        }
-        return right - mDisplayLeftInset;
-    }
-
-    private int getNotificationsClippingTopBounds(int qsTop) {
-        if (mSplitShadeEnabled && mExpandingFromHeadsUp) {
-            // in split shade nssl has extra top margin so clipping at top 0 is not enough, we need
-            // to set top clipping bound to negative value to allow HUN to go up to the top edge of
-            // the screen without clipping.
-            return -mAmbientState.getStackTopMargin();
-        } else {
-            return qsTop - mNotificationStackScrollLayoutController.getTop();
-        }
-    }
-
-    private float getQSEdgePosition() {
-        // TODO: replace StackY with unified calculation
-        return Math.max(mQuickQsHeaderHeight * mAmbientState.getExpansionFraction(),
-                mAmbientState.getStackY()
-                        // need to adjust for extra margin introduced by large screen shade header
-                        + mAmbientState.getStackTopMargin() * mAmbientState.getExpansionFraction()
-                        - mAmbientState.getScrollY());
-    }
-
-    private int calculateQsBottomPosition(float qsExpansionFraction) {
-        if (mTransitioningToFullShadeProgress > 0.0f) {
-            return mTransitionToFullShadeQSPosition;
-        } else if (mSplitShadeEnabled) {
-            // in split shade - outside lockscreen transition handled above - we simply jump between
-            // two qs expansion values - either shade is closed and qs expansion is 0 or shade is
-            // open and qs expansion is 1
-            int qsBottomTarget = mQs.getDesiredHeight() + mLargeScreenShadeHeaderHeight;
-            return qsExpansionFraction > 0 ? qsBottomTarget : 0;
-        } else {
-            int qsBottomYFrom = (int) getHeaderTranslation() + mQs.getQsMinExpansionHeight();
-            int expandedTopMargin = mUseLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight : 0;
-            int qsBottomYTo = mQs.getDesiredHeight() + expandedTopMargin;
-            return (int) MathUtils.lerp(qsBottomYFrom, qsBottomYTo, qsExpansionFraction);
-        }
-    }
-
-    private String determineAccessibilityPaneTitle() {
-        if (mQs != null && mQs.isCustomizing()) {
+    String determineAccessibilityPaneTitle() {
+        if (mQsController != null && mQsController.isCustomizing()) {
             return mResources.getString(R.string.accessibility_desc_quick_settings_edit);
-        } else if (mQsExpansionHeight != 0.0f && mQsFullyExpanded) {
+        } else if (mQsController != null && mQsController.getExpansionHeight() != 0.0f
+                && mQsController.getFullyExpanded()) {
             // Upon initialisation when we are not layouted yet we don't want to announce that we
             // are fully expanded, hence the != 0.0f check.
-            return mResources.getString(R.string.accessibility_desc_quick_settings);
+            if (mSplitShadeEnabled) {
+                // In split shade, QS is expanded but it also shows notifications
+                return mResources.getString(R.string.accessibility_desc_qs_notification_shade);
+            } else {
+                return mResources.getString(R.string.accessibility_desc_quick_settings);
+            }
         } else if (mBarState == KEYGUARD) {
             return mResources.getString(R.string.accessibility_desc_lock_screen);
         } else {
@@ -3247,42 +2205,27 @@
         }
     }
 
-    float calculateNotificationsTopPadding() {
-        if (mSplitShadeEnabled) {
-            return mKeyguardShowing ? getKeyguardNotificationStaticPadding() : 0;
+    /** Returns the topPadding of notifications when on keyguard not respecting QS expansion. */
+    public int getKeyguardNotificationStaticPadding() {
+        if (!getKeyguardShowing()) {
+            return 0;
         }
-        if (mKeyguardShowing && (mQsExpandImmediate
-                || mIsExpanding && mQsExpandedWhenExpandingStarted)) {
-
-            // Either QS pushes the notifications down when fully expanded, or QS is fully above the
-            // notifications (mostly on tablets). maxNotificationPadding denotes the normal top
-            // padding on Keyguard, maxQsPadding denotes the top padding from the quick settings
-            // panel. We need to take the maximum and linearly interpolate with the panel expansion
-            // for a nice motion.
-            int maxNotificationPadding = getKeyguardNotificationStaticPadding();
-            int maxQsPadding = mQsMaxExpansionHeight;
-            int max = mBarState == KEYGUARD ? Math.max(
-                    maxNotificationPadding, maxQsPadding) : maxQsPadding;
-            return (int) MathUtils.lerp((float) mQsMinExpansionHeight, (float) max,
-                    getExpandedFraction());
-        } else if (mQsSizeChangeAnimator != null) {
-            return Math.max(
-                    (int) mQsSizeChangeAnimator.getAnimatedValue(),
-                    getKeyguardNotificationStaticPadding());
-        } else if (mKeyguardShowing) {
-            // We can only do the smoother transition on Keyguard when we also are not collapsing
-            // from a scrolled quick settings.
-            return MathUtils.lerp((float) getKeyguardNotificationStaticPadding(),
-                    (float) (mQsMaxExpansionHeight),
-                    computeQsExpansionFraction());
+        if (!mKeyguardBypassController.getBypassEnabled()) {
+            return mClockPositionResult.stackScrollerPadding;
+        }
+        int collapsedPosition = mHeadsUpInset;
+        if (!mNotificationStackScrollLayoutController.isPulseExpanding()) {
+            return collapsedPosition;
         } else {
-            return mQsFrameTranslateController.getNotificationsTopPadding(mQsExpansionHeight,
-                    mNotificationStackScrollLayoutController);
+            int expandedPosition =
+                    mClockPositionResult.stackScrollerPadding;
+            return (int) MathUtils.lerp(collapsedPosition, expandedPosition,
+                    mNotificationStackScrollLayoutController.calculateAppearFractionBypass());
         }
     }
 
     public boolean getKeyguardShowing() {
-        return mKeyguardShowing;
+        return mBarState == KEYGUARD;
     }
 
     public float getKeyguardNotificationTopPadding() {
@@ -3293,94 +2236,18 @@
         return mKeyguardNotificationBottomPadding;
     }
 
-    /** Returns the topPadding of notifications when on keyguard not respecting QS expansion. */
-    private int getKeyguardNotificationStaticPadding() {
-        if (!mKeyguardShowing) {
-            return 0;
-        }
-        if (!mKeyguardBypassController.getBypassEnabled()) {
-            return mClockPositionResult.stackScrollerPadding;
-        }
-        int collapsedPosition = mHeadsUpInset;
-        if (!mNotificationStackScrollLayoutController.isPulseExpanding()) {
-            return collapsedPosition;
-        } else {
-            int expandedPosition = mClockPositionResult.stackScrollerPadding;
-            return (int) MathUtils.lerp(collapsedPosition, expandedPosition,
-                    mNotificationStackScrollLayoutController.calculateAppearFractionBypass());
-        }
-    }
-
-    private void requestScrollerTopPaddingUpdate(boolean animate) {
+    void requestScrollerTopPaddingUpdate(boolean animate) {
         mNotificationStackScrollLayoutController.updateTopPadding(
-                calculateNotificationsTopPadding(), animate);
-        if (mKeyguardShowing && mKeyguardBypassController.getBypassEnabled()) {
+                mQsController.calculateNotificationsTopPadding(mIsExpanding,
+                        getKeyguardNotificationStaticPadding(), mExpandedFraction), animate);
+        if (getKeyguardShowing()
+                && mKeyguardBypassController.getBypassEnabled()) {
             // update the position of the header
-            updateQsExpansion();
+            mQsController.updateExpansion();
         }
     }
 
     /**
-     * Set the amount of pixels we have currently dragged down if we're transitioning to the full
-     * shade. 0.0f means we're not transitioning yet.
-     */
-    public void setTransitionToFullShadeAmount(float pxAmount, boolean animate, long delay) {
-        if (animate && mIsFullWidth) {
-            animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE,
-                    delay);
-            mIsQsTranslationResetAnimator = mQsTranslationForFullShadeTransition > 0.0f;
-        }
-        float endPosition = 0;
-        if (pxAmount > 0.0f) {
-            if (mSplitShadeEnabled) {
-                float qsHeight = MathUtils.lerp(mQsMinExpansionHeight, mQsMaxExpansionHeight,
-                        mLockscreenShadeTransitionController.getQSDragProgress());
-                setQsExpansionHeight(qsHeight);
-            }
-            if (mNotificationStackScrollLayoutController.getVisibleNotificationCount() == 0
-                    && !mMediaDataManager.hasActiveMediaOrRecommendation()) {
-                // No notifications are visible, let's animate to the height of qs instead
-                if (mQs != null) {
-                    // Let's interpolate to the header height instead of the top padding,
-                    // because the toppadding is way too low because of the large clock.
-                    // we still want to take into account the edgePosition though as that nicely
-                    // overshoots in the stackscroller
-                    endPosition = getQSEdgePosition()
-                            - mNotificationStackScrollLayoutController.getTopPadding()
-                            + mQs.getHeader().getHeight();
-                }
-            } else {
-                // Interpolating to the new bottom edge position!
-                endPosition = getQSEdgePosition()
-                        + mNotificationStackScrollLayoutController.getFullShadeTransitionInset();
-                if (isOnKeyguard()) {
-                    endPosition -= mLockscreenNotificationQSPadding;
-                }
-            }
-        }
-
-        // Calculate the overshoot amount such that we're reaching the target after our desired
-        // distance, but only reach it fully once we drag a full shade length.
-        mTransitioningToFullShadeProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(
-                MathUtils.saturate(pxAmount / mDistanceForQSFullShadeTransition));
-
-        int position = (int) MathUtils.lerp((float) 0, endPosition,
-                mTransitioningToFullShadeProgress);
-        if (mTransitioningToFullShadeProgress > 0.0f) {
-            // we want at least 1 pixel otherwise the panel won't be clipped
-            position = Math.max(1, position);
-        }
-        mTransitionToFullShadeQSPosition = position;
-        updateQsExpansion();
-    }
-
-    /** Called when pulse expansion has finished and this is going to the full shade. */
-    public void onPulseExpansionFinished() {
-        animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE, 0);
-        mIsPulseExpansionResetAnimator = true;
-    }
-
-    /**
      * Set the alpha and translationY of the keyguard elements which only show on the lockscreen,
      * but not in shade locked / shade. This is used when dragging down to the full shade.
      */
@@ -3404,154 +2271,14 @@
         mKeyguardStatusBarViewController.setAlpha(alpha);
     }
 
-    private void trackMovement(MotionEvent event) {
-        if (mQsVelocityTracker != null) mQsVelocityTracker.addMovement(event);
-    }
-
-    private void initVelocityTracker() {
-        if (mQsVelocityTracker != null) {
-            mQsVelocityTracker.recycle();
-        }
-        mQsVelocityTracker = VelocityTracker.obtain();
-    }
-
-    private float getCurrentQSVelocity() {
-        if (mQsVelocityTracker == null) {
-            return 0;
-        }
-        mQsVelocityTracker.computeCurrentVelocity(1000);
-        return mQsVelocityTracker.getYVelocity();
-    }
-
-    private void cancelQsAnimation() {
-        if (mQsExpansionAnimator != null) {
-            mQsExpansionAnimator.cancel();
-        }
-    }
-
-    /** @see #flingSettings(float, int, Runnable, boolean) */
-    public void flingSettings(float vel, int type) {
-        flingSettings(vel, type, null /* onFinishRunnable */, false /* isClick */);
-    }
-
-    /**
-     * Animates QS or QQS as if the user had swiped up or down.
-     *
-     * @param vel              Finger velocity or 0 when not initiated by touch events.
-     * @param type             Either {@link #FLING_EXPAND}, {@link #FLING_COLLAPSE} or {@link
-     *                         #FLING_HIDE}.
-     * @param onFinishRunnable Runnable to be executed at the end of animation.
-     * @param isClick          If originated by click (different interpolator and duration.)
-     */
-    private void flingSettings(float vel, int type, final Runnable onFinishRunnable,
-            boolean isClick) {
-        float target;
-        switch (type) {
-            case FLING_EXPAND:
-                target = mQsMaxExpansionHeight;
-                break;
-            case FLING_COLLAPSE:
-                target = mQsMinExpansionHeight;
-                break;
-            case FLING_HIDE:
-            default:
-                if (mQs != null) {
-                    mQs.closeDetail();
-                }
-                target = 0;
-        }
-        if (target == mQsExpansionHeight) {
-            if (onFinishRunnable != null) {
-                onFinishRunnable.run();
-            }
-            traceQsJank(false /* startTracing */, type != FLING_EXPAND /* wasCancelled */);
-            return;
-        }
-
-        // If we move in the opposite direction, reset velocity and use a different duration.
-        boolean oppositeDirection = false;
-        boolean expanding = type == FLING_EXPAND;
-        if (vel > 0 && !expanding || vel < 0 && expanding) {
-            vel = 0;
-            oppositeDirection = true;
-        }
-        ValueAnimator animator = ValueAnimator.ofFloat(mQsExpansionHeight, target);
-        if (isClick) {
-            animator.setInterpolator(Interpolators.TOUCH_RESPONSE);
-            animator.setDuration(368);
-        } else {
-            mFlingAnimationUtils.apply(animator, mQsExpansionHeight, target, vel);
-        }
-        if (oppositeDirection) {
-            animator.setDuration(350);
-        }
-        animator.addUpdateListener(
-                animation -> setQsExpansionHeight((Float) animation.getAnimatedValue()));
-        animator.addListener(new AnimatorListenerAdapter() {
-            private boolean mIsCanceled;
-
-            @Override
-            public void onAnimationStart(Animator animation) {
-                notifyExpandingStarted();
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                mIsCanceled = true;
-            }
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                mQSAnimatingHiddenFromCollapsed = false;
-                mAnimatingQS = false;
-                notifyExpandingFinished();
-                mNotificationStackScrollLayoutController.resetCheckSnoozeLeavebehind();
-                mQsExpansionAnimator = null;
-                if (onFinishRunnable != null) {
-                    onFinishRunnable.run();
-                }
-                traceQsJank(false /* startTracing */, mIsCanceled /* wasCancelled */);
-            }
-        });
-        // Let's note that we're animating QS. Moving the animator here will cancel it immediately,
-        // so we need a separate flag.
-        mAnimatingQS = true;
-        animator.start();
-        mQsExpansionAnimator = animator;
-        mQsAnimatorExpand = expanding;
-        mQSAnimatingHiddenFromCollapsed = computeQsExpansionFraction() == 0.0f && target == 0;
-    }
-
-    /**
-     * @return Whether we should intercept a gesture to open Quick Settings.
-     */
-    private boolean shouldQuickSettingsIntercept(float x, float y, float yDiff) {
-        if (!isQsExpansionEnabled() || mCollapsedOnDown
-                || (mKeyguardShowing && mKeyguardBypassController.getBypassEnabled())
-                || mSplitShadeEnabled) {
-            return false;
-        }
-        View header = mKeyguardShowing || mQs == null ? mKeyguardStatusBar : mQs.getHeader();
-        int frameTop = mKeyguardShowing || mQs == null ? 0 : mQsFrame.getTop();
-        mQsInterceptRegion.set(
-                /* left= */ (int) mQsFrame.getX(),
-                /* top= */ header.getTop() + frameTop,
-                /* right= */ (int) mQsFrame.getX() + mQsFrame.getWidth(),
-                /* bottom= */ header.getBottom() + frameTop);
-        // Also allow QS to intercept if the touch is near the notch.
-        mStatusBarTouchableRegionManager.updateRegionForNotch(mQsInterceptRegion);
-        final boolean onHeader = mQsInterceptRegion.contains((int) x, (int) y);
-
-        if (mQsExpanded) {
-            return onHeader || (yDiff < 0 && isInQsArea(x, y));
-        } else {
-            return onHeader;
-        }
+    /** */
+    public float getKeyguardOnlyContentAlpha() {
+        return mKeyguardOnlyContentAlpha;
     }
 
     @VisibleForTesting
     boolean canCollapsePanelOnTouch() {
-        if (!isInSettings() && mBarState == KEYGUARD) {
+        if (!mQsController.getExpanded() && mBarState == KEYGUARD) {
             return true;
         }
 
@@ -3559,20 +2286,22 @@
             return true;
         }
 
-        return !mSplitShadeEnabled && (isInSettings() || mIsPanelCollapseOnQQS);
+        return !mSplitShadeEnabled && (mQsController.getExpanded() || mIsPanelCollapseOnQQS);
     }
 
     int getMaxPanelHeight() {
         int min = mStatusBarMinHeight;
         if (!(mBarState == KEYGUARD)
                 && mNotificationStackScrollLayoutController.getNotGoneChildCount() == 0) {
-            int minHeight = mQsMinExpansionHeight;
+            int minHeight = mQsController.getMinExpansionHeight();
             min = Math.max(min, minHeight);
         }
         int maxHeight;
-        if (mQsExpandImmediate || mQsExpanded || mIsExpanding && mQsExpandedWhenExpandingStarted
+        if (mQsController.isExpandImmediate() || mQsController.getExpanded()
+                || mIsExpanding && mQsController.getExpandedWhenExpandingStarted()
                 || mPulsing || mSplitShadeEnabled) {
-            maxHeight = calculatePanelHeightQsExpanded();
+            maxHeight = mQsController.calculatePanelHeightExpanded(
+                    mClockPositionResult.stackScrollerPadding);
         } else {
             maxHeight = calculatePanelHeightShade();
         }
@@ -3580,17 +2309,15 @@
         if (maxHeight == 0) {
             Log.wtf(TAG, "maxPanelHeight is invalid. mOverExpansion: "
                     + mOverExpansion + ", calculatePanelHeightQsExpanded: "
-                    + calculatePanelHeightQsExpanded() + ", calculatePanelHeightShade: "
-                    + calculatePanelHeightShade() + ", mStatusBarMinHeight = "
-                    + mStatusBarMinHeight + ", mQsMinExpansionHeight = " + mQsMinExpansionHeight);
+                    + mQsController.calculatePanelHeightExpanded(
+                            mClockPositionResult.stackScrollerPadding)
+                    + ", calculatePanelHeightShade: " + calculatePanelHeightShade()
+                    + ", mStatusBarMinHeight = " + mStatusBarMinHeight
+                    + ", mQsMinExpansionHeight = " + mQsController.getMinExpansionHeight());
         }
         return maxHeight;
     }
 
-    public boolean isInSettings() {
-        return mQsExpanded;
-    }
-
     public boolean isExpanding() {
         return mIsExpanding;
     }
@@ -3603,7 +2330,8 @@
             mShadeLog.logExpansionChanged("onHeightUpdated: fully expanded.",
                     mExpandedFraction, isExpanded(), mTracking, mExpansionDragDownAmountPx);
         }
-        if (!mQsExpanded || mQsExpandImmediate || mIsExpanding && mQsExpandedWhenExpandingStarted) {
+        if (!mQsController.getExpanded() || mQsController.isExpandImmediate()
+                || mIsExpanding && mQsController.getExpandedWhenExpandingStarted()) {
             // Updating the clock position will set the top padding which might
             // trigger a new panel height and re-position the clock.
             // This is a circular dependency and should be avoided, otherwise we'll have
@@ -3614,14 +2342,8 @@
                 positionClockAndNotifications();
             }
         }
-        // Below is true when QS are expanded and we swipe up from the same bottom of panel to
-        // close the whole shade with one motion. Also this will be always true when closing
-        // split shade as there QS are always expanded so every collapsing motion is motion from
-        // expanded QS to closed panel
-        boolean collapsingShadeFromExpandedQs = mQsExpanded && !mQsTracking
-                && mQsExpansionAnimator == null && !mQsExpansionFromOverscroll;
         boolean goingBetweenClosedShadeAndExpandedQs =
-                mQsExpandImmediate || collapsingShadeFromExpandedQs;
+                mQsController.isGoingBetweenClosedShadeAndExpandedQs();
         // in split shade we react when HUN is visible only if shade height is over HUN start
         // height - which means user is swiping down. Otherwise shade QS will either not show at all
         // with HUN movement or it will blink when touching HUN initially
@@ -3631,7 +2353,7 @@
             float qsExpansionFraction;
             if (mSplitShadeEnabled) {
                 qsExpansionFraction = 1;
-            } else if (mKeyguardShowing) {
+            } else if (getKeyguardShowing()) {
                 // On Keyguard, interpolate the QS expansion linearly to the panel expansion
                 qsExpansionFraction = expandedHeight / (getMaxPanelHeight());
             } else {
@@ -3640,13 +2362,15 @@
                 float panelHeightQsCollapsed =
                         mNotificationStackScrollLayoutController.getIntrinsicPadding()
                                 + mNotificationStackScrollLayoutController.getLayoutMinHeight();
-                float panelHeightQsExpanded = calculatePanelHeightQsExpanded();
+                float panelHeightQsExpanded = mQsController.calculatePanelHeightExpanded(
+                        mClockPositionResult.stackScrollerPadding);
                 qsExpansionFraction = (expandedHeight - panelHeightQsCollapsed)
                         / (panelHeightQsExpanded - panelHeightQsCollapsed);
             }
-            float targetHeight = mQsMinExpansionHeight
-                    + qsExpansionFraction * (mQsMaxExpansionHeight - mQsMinExpansionHeight);
-            setQsExpansionHeight(targetHeight);
+            float targetHeight = mQsController.getMinExpansionHeight() + qsExpansionFraction
+                    * (mQsController.getMaxExpansionHeight()
+                    - mQsController.getMinExpansionHeight());
+            mQsController.setExpansionHeight(targetHeight);
         }
         updateExpandedHeight(expandedHeight);
         updateHeader();
@@ -3663,8 +2387,8 @@
         if (mPanelExpanded != isExpanded) {
             mPanelExpanded = isExpanded;
             mShadeExpansionStateManager.onShadeExpansionFullyChanged(isExpanded);
-            if (!isExpanded && mQs != null && mQs.isCustomizing()) {
-                mQs.closeCustomizer();
+            if (!isExpanded) {
+                mQsController.closeQsCustomizer();
             }
         }
     }
@@ -3686,40 +2410,6 @@
         }
     }
 
-    int calculatePanelHeightQsExpanded() {
-        float
-                notificationHeight =
-                mNotificationStackScrollLayoutController.getHeight()
-                        - mNotificationStackScrollLayoutController.getEmptyBottomMargin()
-                        - mNotificationStackScrollLayoutController.getTopPadding();
-
-        // When only empty shade view is visible in QS collapsed state, simulate that we would have
-        // it in expanded QS state as well so we don't run into troubles when fading the view in/out
-        // and expanding/collapsing the whole panel from/to quick settings.
-        if (mNotificationStackScrollLayoutController.getNotGoneChildCount() == 0
-                && mNotificationStackScrollLayoutController.isShowingEmptyShadeView()) {
-            notificationHeight = mNotificationStackScrollLayoutController.getEmptyShadeViewHeight();
-        }
-        int maxQsHeight = mQsMaxExpansionHeight;
-
-        // If an animation is changing the size of the QS panel, take the animated value.
-        if (mQsSizeChangeAnimator != null) {
-            maxQsHeight = (int) mQsSizeChangeAnimator.getAnimatedValue();
-        }
-        float totalHeight = Math.max(maxQsHeight,
-                mBarState == KEYGUARD ? mClockPositionResult.stackScrollerPadding
-                        : 0) + notificationHeight
-                + mNotificationStackScrollLayoutController.getTopPaddingOverflow();
-        if (totalHeight > mNotificationStackScrollLayoutController.getHeight()) {
-            float
-                    fullyCollapsedHeight =
-                    maxQsHeight + mNotificationStackScrollLayoutController.getLayoutMinHeight();
-            totalHeight = Math.max(fullyCollapsedHeight,
-                    mNotificationStackScrollLayoutController.getHeight());
-        }
-        return (int) totalHeight;
-    }
-
     private void updateNotificationTranslucency() {
         if (mIsOcclusionTransitionRunning) {
             return;
@@ -3738,10 +2428,10 @@
 
     private float getFadeoutAlpha() {
         float alpha;
-        if (mQsMinExpansionHeight == 0) {
+        if (mQsController.getMinExpansionHeight() == 0) {
             return 1.0f;
         }
-        alpha = getExpandedHeight() / mQsMinExpansionHeight;
+        alpha = getExpandedHeight() / mQsController.getMinExpansionHeight();
         alpha = Math.max(0, Math.min(alpha, 1));
         alpha = (float) Math.pow(alpha, 0.75);
         return alpha;
@@ -3752,30 +2442,7 @@
         if (mBarState == KEYGUARD) {
             mKeyguardStatusBarViewController.updateViewState();
         }
-        updateQsExpansion();
-    }
-
-    private float getHeaderTranslation() {
-        if (mSplitShadeEnabled) {
-            // in split shade QS don't translate, just (un)squish and overshoot
-            return 0;
-        }
-        if (mBarState == KEYGUARD && !mKeyguardBypassController.getBypassEnabled()) {
-            return -mQs.getQsMinExpansionHeight();
-        }
-        float appearAmount = mNotificationStackScrollLayoutController
-                .calculateAppearFraction(mExpandedHeight);
-        float startHeight = -mQsExpansionHeight;
-        if (mBarState == StatusBarState.SHADE) {
-            // Small parallax as we pull down and clip QS
-            startHeight = -mQsExpansionHeight * QS_PARALLAX_AMOUNT;
-        }
-        if (mKeyguardBypassController.getBypassEnabled() && isOnKeyguard()) {
-            appearAmount = mNotificationStackScrollLayoutController.calculateAppearFractionBypass();
-            startHeight = -mQs.getQsMinExpansionHeight();
-        }
-        float translation = MathUtils.lerp(startHeight, 0, Math.min(1.0f, appearAmount));
-        return Math.min(0, translation);
+        mQsController.updateExpansion();
     }
 
     private void updateKeyguardBottomAreaAlpha() {
@@ -3792,38 +2459,19 @@
                 isUnlockHintRunning() ? 0 : KeyguardBouncerConstants.ALPHA_EXPANSION_THRESHOLD, 1f,
                 0f, 1f,
                 getExpandedFraction());
-        float alpha = Math.min(expansionAlpha, 1 - computeQsExpansionFraction());
+        float alpha = Math.min(expansionAlpha, 1 - mQsController.computeExpansionFraction());
         alpha *= mBottomAreaShadeAlpha;
         mKeyguardBottomAreaInteractor.setAlpha(alpha);
         mLockIconViewController.setAlpha(alpha);
     }
 
-    private void onExpandingStarted() {
-        mNotificationStackScrollLayoutController.onExpansionStarted();
-        mIsExpanding = true;
-        mQsExpandedWhenExpandingStarted = mQsFullyExpanded;
-        mMediaHierarchyManager.setCollapsingShadeFromQS(mQsExpandedWhenExpandingStarted &&
-                /* We also start expanding when flinging closed Qs. Let's exclude that */
-                !mAnimatingQS);
-        if (mQsExpanded) {
-            onQsExpansionStarted();
-        }
-        // Since there are QS tiles in the header now, we need to make sure we start listening
-        // immediately so they can be up to date.
-        if (mQs == null) return;
-        mQs.setHeaderListening(true);
-    }
-
     private void onExpandingFinished() {
-        if (!mUnocclusionTransitionFlagEnabled) {
-            mScrimController.onExpandingFinished();
-        }
         mNotificationStackScrollLayoutController.onExpansionStopped();
         mHeadsUpManager.onExpandingFinished();
         mConversationNotificationManager.onNotificationPanelExpandStateChanged(isFullyCollapsed());
         mIsExpanding = false;
         mMediaHierarchyManager.setCollapsingShadeFromQS(false);
-        mMediaHierarchyManager.setQsExpanded(mQsExpanded);
+        mMediaHierarchyManager.setQsExpanded(mQsController.getExpanded());
         if (isFullyCollapsed()) {
             DejankUtils.postAfterTraversal(() -> setListening(false));
 
@@ -3838,10 +2486,10 @@
         if (mBarState != SHADE) {
             // updating qsExpandImmediate is done in onPanelStateChanged for unlocked shade but
             // on keyguard panel state is always OPEN so we need to have that extra update
-            setQsExpandImmediate(false);
+            mQsController.setExpandImmediate(false);
         }
         setShowShelfOnly(false);
-        mTwoFingerQsExpandPossible = false;
+        mQsController.setTwoFingerExpandPossible(false);
         updateTrackingHeadsUp(null);
         mExpandingFromHeadsUp = false;
         setPanelScrimMinFraction(0.0f);
@@ -3864,8 +2512,7 @@
 
     private void setListening(boolean listening) {
         mKeyguardStatusBarViewController.setBatteryListening(listening);
-        if (mQs == null) return;
-        mQs.setListening(listening);
+        mQsController.setListening(listening);
     }
 
     public void expand(boolean animate) {
@@ -3899,7 +2546,7 @@
                                         this);
                                 if (mAnimateAfterExpanding) {
                                     notifyExpandingStarted();
-                                    beginJankMonitoring();
+                                    mQsController.beginJankMonitoring(isFullyCollapsed());
                                     fling(0  /* expand */);
                                 } else {
                                     mShadeHeightLogger.logFunctionCall("expand");
@@ -3926,18 +2573,17 @@
             return;
         }
         mOverExpansion = overExpansion;
-        // Translating the quick settings by half the overexpansion to center it in the background
-        // frame
-        updateQsFrameTranslation();
+        if (mSplitShadeEnabled) {
+            mQsController.setOverScrollAmount((int) overExpansion);
+            mScrimController.setNotificationsOverScrollAmount((int) overExpansion);
+        } else {
+            // Translating the quick settings by half the overexpansion to center it in the
+            // background frame
+            mQsController.updateQsFrameTranslation();
+        }
         mNotificationStackScrollLayoutController.setOverExpansion(overExpansion);
     }
 
-    private void updateQsFrameTranslation() {
-        mQsFrameTranslateController.translateQsFrame(mQsFrame, mQs,
-                mNavigationBarBottomHeight + mAmbientState.getStackTopMargin());
-
-    }
-
     private void falsingAdditionalTapRequired() {
         if (mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED) {
             mTapAgainViewController.show();
@@ -3964,8 +2610,8 @@
         notifyExpandingStarted();
         updatePanelExpansionAndVisibility();
         mScrimController.onTrackingStarted();
-        if (mQsFullyExpanded) {
-            setQsExpandImmediate(true);
+        if (mQsController.getFullyExpanded()) {
+            mQsController.setExpandImmediate(true);
             setShowShelfOnly(true);
         }
         mNotificationStackScrollLayoutController.onPanelTrackingStarted();
@@ -4042,8 +2688,8 @@
         // the required distance to be a specific and constant value, to make sure the expansion
         // motion has the expected speed. We also only want this on non-lockscreen for now.
         if (mSplitShadeEnabled && mBarState == SHADE) {
-            boolean transitionFromHeadsUp =
-                    mHeadsUpManager.isTrackingHeadsUp() || mExpandingFromHeadsUp;
+            boolean transitionFromHeadsUp = (mHeadsUpManager != null
+                    && mHeadsUpManager.isTrackingHeadsUp()) || mExpandingFromHeadsUp;
             // heads-up starting height is too close to mSplitShadeFullTransitionDistance and
             // when dragging HUN transition is already 90% complete. It makes shade become
             // immediately visible when starting to drag. We want to set distance so that
@@ -4061,25 +2707,6 @@
         }
     }
 
-    @VisibleForTesting
-    boolean isTrackingBlocked() {
-        return mConflictingQsExpansionGesture && mQsExpanded || mBlockingExpansionForCurrentTouch;
-    }
-
-    public boolean isQsExpanded() {
-        return mQsExpanded;
-    }
-
-    /** Returns whether the QS customizer is currently active. */
-    public boolean isQsCustomizing() {
-        return mQs.isCustomizing();
-    }
-
-    /** Close the QS customizer if it is open. */
-    public void closeQsCustomizer() {
-        mQs.closeCustomizer();
-    }
-
     public void setIsLaunchAnimationRunning(boolean running) {
         boolean wasRunning = mIsLaunchAnimationRunning;
         mIsLaunchAnimationRunning = running;
@@ -4104,14 +2731,6 @@
         }
     }
 
-    public void setQsScrimEnabled(boolean qsScrimEnabled) {
-        boolean changed = mQsScrimEnabled != qsScrimEnabled;
-        mQsScrimEnabled = qsScrimEnabled;
-        if (changed) {
-            updateQsState();
-        }
-    }
-
     public void onScreenTurningOn() {
         mKeyguardStatusViewController.dozeTimeTick();
     }
@@ -4140,7 +2759,7 @@
                 }
                 break;
             case StatusBarState.SHADE_LOCKED:
-                if (!mQsExpanded) {
+                if (!mQsController.getExpanded()) {
                     mStatusBarStateController.setState(KEYGUARD);
                 }
                 break;
@@ -4289,66 +2908,6 @@
         return !mShowIconsWhenExpanded;
     }
 
-    private void onQsPanelScrollChanged(int scrollY) {
-        mLargeScreenShadeHeaderController.setQsScrollY(scrollY);
-        if (scrollY > 0 && !mQsFullyExpanded) {
-            debugLog("Scrolling while not expanded. Forcing expand");
-            // If we are scrolling QS, we should be fully expanded.
-            expandWithQs();
-        }
-    }
-
-    private final class QsFragmentListener implements FragmentListener {
-        @Override
-        public void onFragmentViewCreated(String tag, Fragment fragment) {
-            mQs = (QS) fragment;
-            mQs.setPanelView(mHeightListener);
-            mQs.setCollapseExpandAction(mCollapseExpandAction);
-            mQs.setHeaderClickable(isQsExpansionEnabled());
-            mQs.setOverscrolling(mStackScrollerOverscrolling);
-            mQs.setInSplitShade(mSplitShadeEnabled);
-            mQs.setIsNotificationPanelFullWidth(mIsFullWidth);
-
-            // recompute internal state when qspanel height changes
-            mQs.getView().addOnLayoutChangeListener(
-                    (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
-                        final int height = bottom - top;
-                        final int oldHeight = oldBottom - oldTop;
-                        if (height != oldHeight) {
-                            onQsHeightChanged();
-                        }
-                    });
-            mQs.setCollapsedMediaVisibilityChangedListener((visible) -> {
-                if (mQs.getHeader().isShown()) {
-                    animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_STANDARD,
-                            0 /* delay */);
-                    mNotificationStackScrollLayoutController.animateNextTopPaddingChange();
-                }
-            });
-            mLockscreenShadeTransitionController.setQS(mQs);
-            mShadeTransitionController.setQs(mQs);
-            mNotificationStackScrollLayoutController.setQsHeader((ViewGroup) mQs.getHeader());
-            mQs.setScrollListener(mQsScrollListener);
-            updateQsExpansion();
-        }
-
-        @Override
-        public void onFragmentViewDestroyed(String tag, Fragment fragment) {
-            // Manual handling of fragment lifecycle is only required because this bridges
-            // non-fragment and fragment code. Once we are using a fragment for the notification
-            // panel, mQs will not need to be null cause it will be tied to the same lifecycle.
-            if (fragment == mQs) {
-                mQs = null;
-            }
-        }
-    }
-
-    private void animateNextNotificationBounds(long duration, long delay) {
-        mAnimateNextNotificationBounds = true;
-        mNotificationBoundsAnimationDuration = duration;
-        mNotificationBoundsAnimationDelay = delay;
-    }
-
     public void setTouchAndAnimationDisabled(boolean disabled) {
         mTouchDisabled = disabled;
         if (mTouchDisabled) {
@@ -4371,9 +2930,11 @@
         if (dozing == mDozing) return;
         mView.setDozing(dozing);
         mDozing = dozing;
+        // TODO (b/) make listeners for this
         mNotificationStackScrollLayoutController.setDozing(mDozing, animate);
         mKeyguardBottomAreaInteractor.setAnimateDozingTransitions(animate);
         mKeyguardStatusBarViewController.setDozing(mDozing);
+        mQsController.setDozing(mDozing);
 
         if (dozing) {
             mBottomAreaShadeAlphaAnimator.cancel();
@@ -4564,33 +3125,13 @@
         ipw.print("mMaxAllowedKeyguardNotifications=");
         ipw.println(mMaxAllowedKeyguardNotifications);
         ipw.print("mAnimateNextPositionUpdate="); ipw.println(mAnimateNextPositionUpdate);
-        ipw.print("mQuickQsHeaderHeight="); ipw.println(mQuickQsHeaderHeight);
-        ipw.print("mQsTrackingPointer="); ipw.println(mQsTrackingPointer);
-        ipw.print("mQsTracking="); ipw.println(mQsTracking);
-        ipw.print("mConflictingQsExpansionGesture="); ipw.println(mConflictingQsExpansionGesture);
         ipw.print("mPanelExpanded="); ipw.println(mPanelExpanded);
-        ipw.print("mQsExpanded="); ipw.println(mQsExpanded);
-        ipw.print("mQsExpandedWhenExpandingStarted="); ipw.println(mQsExpandedWhenExpandingStarted);
-        ipw.print("mQsFullyExpanded="); ipw.println(mQsFullyExpanded);
-        ipw.print("mKeyguardShowing="); ipw.println(mKeyguardShowing);
         ipw.print("mKeyguardQsUserSwitchEnabled="); ipw.println(mKeyguardQsUserSwitchEnabled);
         ipw.print("mKeyguardUserSwitcherEnabled="); ipw.println(mKeyguardUserSwitcherEnabled);
         ipw.print("mDozing="); ipw.println(mDozing);
         ipw.print("mDozingOnDown="); ipw.println(mDozingOnDown);
         ipw.print("mBouncerShowing="); ipw.println(mBouncerShowing);
         ipw.print("mBarState="); ipw.println(mBarState);
-        ipw.print("mInitialHeightOnTouch="); ipw.println(mInitialHeightOnTouch);
-        ipw.print("mInitialTouchX="); ipw.println(mInitialTouchX);
-        ipw.print("mInitialTouchY="); ipw.println(mInitialTouchY);
-        ipw.print("mQsExpansionHeight="); ipw.println(mQsExpansionHeight);
-        ipw.print("mQsMinExpansionHeight="); ipw.println(mQsMinExpansionHeight);
-        ipw.print("mQsMaxExpansionHeight="); ipw.println(mQsMaxExpansionHeight);
-        ipw.print("mQsPeekHeight="); ipw.println(mQsPeekHeight);
-        ipw.print("mStackScrollerOverscrolling="); ipw.println(mStackScrollerOverscrolling);
-        ipw.print("mQsExpansionFromOverscroll="); ipw.println(mQsExpansionFromOverscroll);
-        ipw.print("mLastOverscroll="); ipw.println(mLastOverscroll);
-        ipw.print("mQsExpansionEnabledPolicy="); ipw.println(mQsExpansionEnabledPolicy);
-        ipw.print("mQsExpansionEnabledAmbient="); ipw.println(mQsExpansionEnabledAmbient);
         ipw.print("mStatusBarMinHeight="); ipw.println(mStatusBarMinHeight);
         ipw.print("mStatusBarHeaderHeightKeyguard="); ipw.println(mStatusBarHeaderHeightKeyguard);
         ipw.print("mOverStretchAmount="); ipw.println(mOverStretchAmount);
@@ -4599,17 +3140,8 @@
         ipw.print("mDisplayTopInset="); ipw.println(mDisplayTopInset);
         ipw.print("mDisplayRightInset="); ipw.println(mDisplayRightInset);
         ipw.print("mDisplayLeftInset="); ipw.println(mDisplayLeftInset);
-        ipw.print("mLargeScreenShadeHeaderHeight="); ipw.println(mLargeScreenShadeHeaderHeight);
-        ipw.print("mSplitShadeNotificationsScrimMarginBottom=");
-        ipw.println(mSplitShadeNotificationsScrimMarginBottom);
         ipw.print("mIsExpanding="); ipw.println(mIsExpanding);
-        ipw.print("mQsExpandImmediate="); ipw.println(mQsExpandImmediate);
-        ipw.print("mTwoFingerQsExpandPossible="); ipw.println(mTwoFingerQsExpandPossible);
         ipw.print("mHeaderDebugInfo="); ipw.println(mHeaderDebugInfo);
-        ipw.print("mQsAnimatorExpand="); ipw.println(mQsAnimatorExpand);
-        ipw.print("mQsScrimEnabled="); ipw.println(mQsScrimEnabled);
-        ipw.print("mQsTouchAboveFalsingThreshold="); ipw.println(mQsTouchAboveFalsingThreshold);
-        ipw.print("mQsFalsingThreshold="); ipw.println(mQsFalsingThreshold);
         ipw.print("mHeadsUpStartHeight="); ipw.println(mHeadsUpStartHeight);
         ipw.print("mListenForHeadsUp="); ipw.println(mListenForHeadsUp);
         ipw.print("mNavigationBarBottomHeight="); ipw.println(mNavigationBarBottomHeight);
@@ -4625,7 +3157,6 @@
         ipw.println(mBlockingExpansionForCurrentTouch);
         ipw.print("mExpectingSynthesizedDown="); ipw.println(mExpectingSynthesizedDown);
         ipw.print("mLastEventSynthesizedDown="); ipw.println(mLastEventSynthesizedDown);
-        ipw.print("mLastFlingWasExpanding="); ipw.println(mLastFlingWasExpanding);
         ipw.print("mInterpolatedDarkAmount="); ipw.println(mInterpolatedDarkAmount);
         ipw.print("mLinearDarkAmount="); ipw.println(mLinearDarkAmount);
         ipw.print("mPulsing="); ipw.println(mPulsing);
@@ -4636,40 +3167,14 @@
         ipw.print("mHeadsUpInset="); ipw.println(mHeadsUpInset);
         ipw.print("mHeadsUpPinnedMode="); ipw.println(mHeadsUpPinnedMode);
         ipw.print("mAllowExpandForSmallExpansion="); ipw.println(mAllowExpandForSmallExpansion);
-        ipw.print("mLockscreenNotificationQSPadding=");
-        ipw.println(mLockscreenNotificationQSPadding);
-        ipw.print("mTransitioningToFullShadeProgress=");
-        ipw.println(mTransitioningToFullShadeProgress);
-        ipw.print("mTransitionToFullShadeQSPosition=");
-        ipw.println(mTransitionToFullShadeQSPosition);
-        ipw.print("mDistanceForQSFullShadeTransition=");
-        ipw.println(mDistanceForQSFullShadeTransition);
-        ipw.print("mQsTranslationForFullShadeTransition=");
-        ipw.println(mQsTranslationForFullShadeTransition);
         ipw.print("mMaxOverscrollAmountForPulse="); ipw.println(mMaxOverscrollAmountForPulse);
-        ipw.print("mAnimateNextNotificationBounds="); ipw.println(mAnimateNextNotificationBounds);
-        ipw.print("mNotificationBoundsAnimationDelay=");
-        ipw.println(mNotificationBoundsAnimationDelay);
-        ipw.print("mNotificationBoundsAnimationDuration=");
-        ipw.println(mNotificationBoundsAnimationDuration);
         ipw.print("mIsPanelCollapseOnQQS="); ipw.println(mIsPanelCollapseOnQQS);
-        ipw.print("mAnimatingQS="); ipw.println(mAnimatingQS);
-        ipw.print("mIsQsTranslationResetAnimator="); ipw.println(mIsQsTranslationResetAnimator);
-        ipw.print("mIsPulseExpansionResetAnimator="); ipw.println(mIsPulseExpansionResetAnimator);
         ipw.print("mKeyguardOnlyContentAlpha="); ipw.println(mKeyguardOnlyContentAlpha);
         ipw.print("mKeyguardOnlyTransitionTranslationY=");
         ipw.println(mKeyguardOnlyTransitionTranslationY);
         ipw.print("mUdfpsMaxYBurnInOffset="); ipw.println(mUdfpsMaxYBurnInOffset);
         ipw.print("mIsGestureNavigation="); ipw.println(mIsGestureNavigation);
         ipw.print("mOldLayoutDirection="); ipw.println(mOldLayoutDirection);
-        ipw.print("mScrimCornerRadius="); ipw.println(mScrimCornerRadius);
-        ipw.print("mScreenCornerRadius="); ipw.println(mScreenCornerRadius);
-        ipw.print("mQSAnimatingHiddenFromCollapsed="); ipw.println(mQSAnimatingHiddenFromCollapsed);
-        ipw.print("mUseLargeScreenShadeHeader="); ipw.println(mUseLargeScreenShadeHeader);
-        ipw.print("mEnableQsClipping="); ipw.println(mEnableQsClipping);
-        ipw.print("mQsClipTop="); ipw.println(mQsClipTop);
-        ipw.print("mQsClipBottom="); ipw.println(mQsClipBottom);
-        ipw.print("mQsVisible="); ipw.println(mQsVisible);
         ipw.print("mMinFraction="); ipw.println(mMinFraction);
         ipw.print("mStatusViewCentered="); ipw.println(mStatusViewCentered);
         ipw.print("mSplitShadeFullTransitionDistance=");
@@ -4815,7 +3320,7 @@
     }
 
     public void disable(int state1, int state2, boolean animated) {
-        mLargeScreenShadeHeaderController.disable(state1, state2, animated);
+        mShadeHeaderController.disable(state1, state2, animated);
     }
 
     /**
@@ -4854,12 +3359,12 @@
     public void updateSystemUiStateFlags() {
         if (SysUiState.DEBUG) {
             Log.d(TAG, "Updating panel sysui state flags: fullyExpanded="
-                    + isFullyExpanded() + " inQs=" + isInSettings());
+                    + isFullyExpanded() + " inQs=" + mQsController.getExpanded());
         }
         mSysUiState.setFlag(SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED,
-                        isFullyExpanded() && !isInSettings())
-                .setFlag(SYSUI_STATE_QUICK_SETTINGS_EXPANDED, isFullyExpanded() && isInSettings())
-                .commitUpdate(mDisplayId);
+                        isFullyExpanded() && !mQsController.getExpanded())
+                .setFlag(SYSUI_STATE_QUICK_SETTINGS_EXPANDED,
+                        isFullyExpanded() && mQsController.getExpanded()).commitUpdate(mDisplayId);
     }
 
     private void debugLog(String fmt, Object... args) {
@@ -4872,11 +3377,11 @@
     void notifyExpandingStarted() {
         if (!mExpanding) {
             mExpanding = true;
-            onExpandingStarted();
+            mIsExpanding = true;
+            mQsController.onExpandingStarted(mQsController.getFullyExpanded());
         }
     }
 
-    @VisibleForTesting
     void notifyExpandingFinished() {
         endClosing();
         if (mExpanding) {
@@ -4885,7 +3390,7 @@
         }
     }
 
-    private float getTouchSlop(MotionEvent event) {
+    float getTouchSlop(MotionEvent event) {
         // Adjust the touch slop if another gesture may be being performed.
         return event.getClassification() == MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE
                 ? mTouchSlop * mSlopMultiplier
@@ -4959,7 +3464,7 @@
     public void startExpandMotion(float newX, float newY, boolean startTracking,
             float expandedHeight) {
         if (!mHandlingPointerUp && !mStatusBarStateController.isDozing()) {
-            beginJankMonitoring();
+            mQsController.beginJankMonitoring(isFullyCollapsed());
         }
         mInitialOffsetOnTouch = expandedHeight;
         if (!mTracking || isFullyCollapsed()) {
@@ -5077,7 +3582,7 @@
 
     private void fling(float vel, boolean expand, float collapseSpeedUpFactor,
             boolean expandBecauseOfFalsing) {
-        float target = expand ? getMaxPanelHeight() : 0;
+        float target = expand ? getMaxPanelTransitionDistance() : 0;
         if (!expand) {
             setClosing(true);
         }
@@ -5121,7 +3626,8 @@
         setExpandedHeightInternal(height);
     }
 
-    private void updateExpandedHeightToMaxHeight() {
+    /** Try to set expanded height to max. */
+    void updateExpandedHeightToMaxHeight() {
         float currentMaxPanelHeight = getMaxPanelHeight();
 
         if (isFullyCollapsed()) {
@@ -5132,7 +3638,8 @@
             return;
         }
 
-        if (mTracking && !isTrackingBlocked()) {
+        if (mTracking && !(mBlockingExpansionForCurrentTouch
+                || mQsController.isTrackingBlocked())) {
             return;
         }
 
@@ -5160,7 +3667,7 @@
             float maxPanelHeight = getMaxPanelTransitionDistance();
             if (mHeightAnimator == null) {
                 // Split shade has its own overscroll logic
-                if (mTracking && !mSplitShadeEnabled) {
+                if (mTracking) {
                     float overExpansionPixels = Math.max(0, h - maxPanelHeight);
                     setOverExpansionInternal(overExpansionPixels, true /* isFromGesture */);
                 }
@@ -5174,6 +3681,7 @@
                     mHeightAnimator.end();
                 }
             }
+            mQsController.setShadeExpandedHeight(mExpandedHeight);
             mExpansionDragDownAmountPx = h;
             mExpandedFraction = Math.min(1f,
                     maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight);
@@ -5213,7 +3721,7 @@
         return mExpandedHeight;
     }
 
-    private float getExpandedFraction() {
+    float getExpandedFraction() {
         return mExpandedFraction;
     }
 
@@ -5244,7 +3752,7 @@
             return true;
         } else {
             // case of two finger swipe from the top of keyguard
-            return computeQsExpansionFraction() == 1;
+            return mQsController.computeExpansionFraction() == 1;
         }
     }
 
@@ -5342,7 +3850,7 @@
     }
 
     /** Returns whether a shade or QS expansion animation is running */
-    private boolean isShadeOrQsHeightAnimationRunning() {
+    public boolean isShadeOrQsHeightAnimationRunning() {
         return mHeightAnimator != null && !mHintAnimationRunning && !mIsSpringBackAnimation;
     }
 
@@ -5477,44 +3985,135 @@
         return mView.isEnabled();
     }
 
-    private void beginJankMonitoring() {
-        if (mInteractionJankMonitor == null) {
-            return;
-        }
-        InteractionJankMonitor.Configuration.Builder builder =
-                InteractionJankMonitor.Configuration.Builder.withView(
-                                InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE,
-                                mView)
-                        .setTag(isFullyCollapsed() ? "Expand" : "Collapse");
-        mInteractionJankMonitor.begin(builder);
+    int getDisplayRightInset() {
+        return mDisplayRightInset;
     }
 
-    private void endJankMonitoring() {
-        if (mInteractionJankMonitor == null) {
-            return;
-        }
-        InteractionJankMonitor.getInstance().end(
-                InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
+    int getDisplayLeftInset() {
+        return mDisplayLeftInset;
     }
 
-    private void cancelJankMonitoring() {
-        if (mInteractionJankMonitor == null) {
-            return;
+    float getOverStretchAmount() {
+        return mOverStretchAmount;
+    }
+
+    float getMinFraction() {
+        return mMinFraction;
+    }
+
+    boolean getCollapsedOnDown() {
+        return mCollapsedOnDown;
+    }
+
+    int getNavigationBarBottomHeight() {
+        return mNavigationBarBottomHeight;
+    }
+
+    boolean isExpandingFromHeadsUp() {
+        return mExpandingFromHeadsUp;
+    }
+
+    /**
+     * We don't always want to close QS when requested as shade might be in a different state
+     * already e.g. when going from collapse to expand very quickly. In that case StatusBar
+     * window might send signal to collapse QS but we might be already expanding and in split
+     * shade QS are always expanded
+     */
+    private void closeQsIfPossible() {
+        boolean openOrOpening = isShadeFullyOpen() || isExpanding();
+        if (!(mSplitShadeEnabled && openOrOpening)) {
+            mQsController.closeQs();
         }
-        InteractionJankMonitor.getInstance().cancel(
-                InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
+    }
+
+    /** TODO: remove need for this delegate (b/254870148) */
+    public void setQsScrimEnabled(boolean qsScrimEnabled) {
+        mQsController.setScrimEnabled(qsScrimEnabled);
     }
 
     private ShadeExpansionStateManager getShadeExpansionStateManager() {
         return mShadeExpansionStateManager;
     }
 
+    private void onQsExpansionChanged(boolean expanded) {
+        updateExpandedHeightToMaxHeight();
+        setStatusAccessibilityImportance(expanded
+                ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
+                : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+        updateSystemUiStateFlags();
+        NavigationBarView navigationBarView =
+                mNavigationBarController.getNavigationBarView(mDisplayId);
+        if (navigationBarView != null) {
+            navigationBarView.onStatusBarPanelStateChanged();
+        }
+    }
+
+    @VisibleForTesting
+    void onQsSetExpansionHeightCalled(boolean qsFullyExpanded) {
+        requestScrollerTopPaddingUpdate(false);
+        mKeyguardStatusBarViewController.updateViewState();
+        int barState = getBarState();
+        if (barState == SHADE_LOCKED || barState == KEYGUARD) {
+            updateKeyguardBottomAreaAlpha();
+            positionClockAndNotifications();
+        }
+
+        if (mAccessibilityManager.isEnabled()) {
+            mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
+        }
+
+        if (!mFalsingManager.isUnlockingDisabled() && qsFullyExpanded
+                && mFalsingCollector.shouldEnforceBouncer()) {
+            mCentralSurfaces.executeRunnableDismissingKeyguard(null, null,
+                    false, true, false);
+        }
+        if (DEBUG_DRAWABLE) {
+            mView.invalidate();
+        }
+    }
+
+    private void onQsStateUpdated(boolean qsExpanded, boolean isStackScrollerOverscrolling) {
+        if (mKeyguardUserSwitcherController != null && qsExpanded
+                && !isStackScrollerOverscrolling) {
+            mKeyguardUserSwitcherController.closeSwitcherIfOpenAndNotSimple(true);
+        }
+    }
+
+    private void onQsClippingImmediatelyApplied(boolean clipStatusView,
+            Rect lastQsClipBounds, int top, boolean qsFragmentCreated, boolean qsVisible) {
+        if (qsFragmentCreated) {
+            mKeyguardInteractor.setQuickSettingsVisible(qsVisible);
+        }
+
+        // The padding on this area is large enough that
+        // we can use a cheaper clipping strategy
+        mKeyguardStatusViewController.setClipBounds(
+                clipStatusView ? lastQsClipBounds : null);
+        if (mSplitShadeEnabled) {
+            mKeyguardStatusBarViewController.setNoTopClipping();
+        } else {
+            mKeyguardStatusBarViewController.updateTopClipping(top);
+        }
+    }
+
+    private void onFlingQsWithoutClick(ValueAnimator animator, float qsExpansionHeight,
+            float target, float vel) {
+        mFlingAnimationUtils.apply(animator, qsExpansionHeight, target, vel);
+    }
+
+    private void onExpansionHeightSetToMax(boolean requestPaddingUpdate) {
+        if (requestPaddingUpdate) {
+            requestScrollerTopPaddingUpdate(false /* animate */);
+        }
+        updateExpandedHeightToMaxHeight();
+    }
+
     private final class NsslHeightChangedListener implements
             ExpandableView.OnHeightChangedListener {
         @Override
         public void onHeightChanged(ExpandableView view, boolean needsAnimation) {
             // Block update if we are in QS and just the top padding changed (i.e. view == null).
-            if (view == null && mQsExpanded) {
+            if (view == null && mQsController.getExpanded()) {
                 return;
             }
             if (needsAnimation && mInterpolatedDarkAmount == 0) {
@@ -5530,7 +4129,7 @@
                     == firstRow))) {
                 requestScrollerTopPaddingUpdate(false /* animate */);
             }
-            if (mKeyguardShowing) {
+            if (getKeyguardShowing()) {
                 updateMaxDisplayedNotifications(true);
             }
             updateExpandedHeightToMaxHeight();
@@ -5540,62 +4139,6 @@
         public void onReset(ExpandableView view) {}
     }
 
-    private void collapseOrExpand() {
-        onQsExpansionStarted();
-        if (mQsExpanded) {
-            flingSettings(0 /* vel */, FLING_COLLAPSE, null /* onFinishRunnable */,
-                    true /* isClick */);
-        } else if (isQsExpansionEnabled()) {
-            mLockscreenGestureLogger.write(MetricsEvent.ACTION_SHADE_QS_TAP, 0, 0);
-            flingSettings(0 /* vel */, FLING_EXPAND, null /* onFinishRunnable */,
-                    true /* isClick */);
-        }
-    }
-
-    private final class NsslOverscrollTopChangedListener implements
-            NotificationStackScrollLayout.OnOverscrollTopChangedListener {
-        @Override
-        public void onOverscrollTopChanged(float amount, boolean isRubberbanded) {
-            // When in split shade, overscroll shouldn't carry through to QS
-            if (mSplitShadeEnabled) {
-                return;
-            }
-            cancelQsAnimation();
-            if (!isQsExpansionEnabled()) {
-                amount = 0f;
-            }
-            float rounded = amount >= 1f ? amount : 0f;
-            setOverScrolling(rounded != 0f && isRubberbanded);
-            mQsExpansionFromOverscroll = rounded != 0f;
-            mLastOverscroll = rounded;
-            updateQsState();
-            setQsExpansionHeight(mQsMinExpansionHeight + rounded);
-        }
-
-        @Override
-        public void flingTopOverscroll(float velocity, boolean open) {
-            // in split shade touches affect QS only when touch happens within QS
-            if (isSplitShadeAndTouchXOutsideQs(mInitialTouchX)) {
-                return;
-            }
-            mLastOverscroll = 0f;
-            mQsExpansionFromOverscroll = false;
-            if (open) {
-                // During overscrolling, qsExpansion doesn't actually change that the qs is
-                // becoming expanded. Any layout could therefore reset the position again. Let's
-                // make sure we can expand
-                setOverScrolling(false);
-            }
-            setQsExpansionHeight(mQsExpansionHeight);
-            boolean canExpand = isQsExpansionEnabled();
-            flingSettings(!canExpand && open ? 0f : velocity,
-                    open && canExpand ? FLING_EXPAND : FLING_COLLAPSE, () -> {
-                        setOverScrolling(false);
-                        updateQsState();
-                    }, false /* isClick */);
-        }
-    }
-
     private void onDynamicPrivacyChanged() {
         // Do not request animation when pulsing or waking up, otherwise the clock will be out
         // of sync with the notification panel.
@@ -5645,19 +4188,6 @@
         }
     }
 
-    private void onQsHeightChanged() {
-        mQsMaxExpansionHeight = mQs != null ? mQs.getDesiredHeight() : 0;
-        if (mQsExpanded && mQsFullyExpanded) {
-            mQsExpansionHeight = mQsMaxExpansionHeight;
-            requestScrollerTopPaddingUpdate(false /* animate */);
-            updateExpandedHeightToMaxHeight();
-        }
-        if (mAccessibilityManager.isEnabled()) {
-            mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
-        }
-        mNotificationStackScrollLayoutController.setMaxTopPadding(mQsMaxExpansionHeight);
-    }
-
     private final class ConfigurationListener implements
             ConfigurationController.ConfigurationListener {
         @Override
@@ -5733,8 +4263,9 @@
 
             setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade);
 
+            // TODO: maybe add a listener for barstate
             mBarState = statusBarState;
-            mKeyguardShowing = keyguardShowing;
+            mQsController.setBarState(statusBarState);
 
             boolean fromShadeToKeyguard = statusBarState == KEYGUARD
                     && (oldState == SHADE || oldState == SHADE_LOCKED);
@@ -5742,7 +4273,7 @@
                 // user can go to keyguard from different shade states and closing animation
                 // may not fully run - we always want to make sure we close QS when that happens
                 // as we never need QS open in fresh keyguard state
-                closeQs();
+                mQsController.closeQs();
             }
 
             if (oldState == KEYGUARD && (goingToFullShade
@@ -5758,7 +4289,7 @@
                     duration = StackStateAnimator.ANIMATION_DURATION_STANDARD;
                 }
                 mKeyguardStatusBarViewController.animateKeyguardStatusBarOut(startDelay, duration);
-                updateQSMinHeight();
+                mQsController.updateMinHeight();
             } else if (oldState == StatusBarState.SHADE_LOCKED
                     && statusBarState == KEYGUARD) {
                 mKeyguardStatusBarViewController.animateKeyguardStatusBarIn();
@@ -5786,9 +4317,7 @@
                             keyguardShowing ? View.VISIBLE : View.INVISIBLE);
                 }
                 if (keyguardShowing && oldState != mBarState) {
-                    if (mQs != null) {
-                        mQs.hideImmediately();
-                    }
+                    mQsController.hideQsImmediately();
                 }
             }
             mKeyguardStatusBarViewController.updateForHeadsUp();
@@ -5800,7 +4329,7 @@
             // The update needs to happen after the headerSlide in above, otherwise the translation
             // would reset
             maybeAnimateBottomAreaAlpha();
-            updateQsState();
+            mQsController.updateQsState();
         }
 
         @Override
@@ -5877,7 +4406,7 @@
         @Override
         public void onViewAttachedToWindow(View v) {
             mFragmentService.getFragmentHostManager(mView)
-                    .addTagListener(QS.TAG, mQsFragmentListener);
+                    .addTagListener(QS.TAG, mQsController.getQsFragmentListener());
             mStatusBarStateController.addCallback(mStatusBarStateListener);
             mStatusBarStateListener.onStateChanged(mStatusBarStateController.getState());
             mConfigurationController.addCallback(mConfigurationListener);
@@ -5894,7 +4423,7 @@
         public void onViewDetachedFromWindow(View v) {
             mContentResolver.unregisterContentObserver(mSettingsChangeObserver);
             mFragmentService.getFragmentHostManager(mView)
-                    .removeTagListener(QS.TAG, mQsFragmentListener);
+                    .removeTagListener(QS.TAG, mQsController.getQsFragmentListener());
             mStatusBarStateController.removeCallback(mStatusBarStateListener);
             mConfigurationController.removeCallback(mConfigurationListener);
             mFalsingManager.removeTapListener(mFalsingTapListener);
@@ -5919,28 +4448,9 @@
             // Update Clock Pivot (used by anti-burnin transformations)
             mKeyguardStatusViewController.updatePivot(mView.getWidth(), mView.getHeight());
 
-            // Calculate quick setting heights.
-            int oldMaxHeight = mQsMaxExpansionHeight;
-            if (mQs != null) {
-                updateQSMinHeight();
-                mQsMaxExpansionHeight = mQs.getDesiredHeight();
-                mNotificationStackScrollLayoutController.setMaxTopPadding(mQsMaxExpansionHeight);
-            }
+            int oldMaxHeight = mQsController.updateHeightsOnShadeLayoutChange();
             positionClockAndNotifications();
-            if (mQsExpanded && mQsFullyExpanded) {
-                mQsExpansionHeight = mQsMaxExpansionHeight;
-                requestScrollerTopPaddingUpdate(false /* animate */);
-                updateExpandedHeightToMaxHeight();
-
-                // Size has changed, start an animation.
-                if (mQsMaxExpansionHeight != oldMaxHeight) {
-                    startQsSizeChangeAnimation(oldMaxHeight, mQsMaxExpansionHeight);
-                }
-            } else if (!mQsExpanded && mQsExpansionAnimator == null) {
-                setQsExpansionHeight(mQsMinExpansionHeight + mLastOverscroll);
-            } else {
-                mShadeLog.v("onLayoutChange: qs expansion not set");
-            }
+            mQsController.handleShadeLayoutChanged(oldMaxHeight);
             updateExpandedHeight(getExpandedHeight());
             updateHeader();
 
@@ -5949,9 +4459,8 @@
             // container the desired height so when closing the QS detail, it stays smaller after
             // the size change animation is finished but the detail view is still being animated
             // away (this animation takes longer than the size change animation).
-            if (mQsSizeChangeAnimator == null && mQs != null) {
-                mQs.setHeightOverride(mQs.getDesiredHeight());
-            }
+            mQsController.setHeightOverrideToDesiredHeight();
+
             updateMaxHeadsUpTranslation();
             updateGestureExclusionRect();
             if (mExpandAfterLayoutRunnable != null) {
@@ -5962,18 +4471,6 @@
         }
     }
 
-    private void updateQSMinHeight() {
-        float previousMin = mQsMinExpansionHeight;
-        if (mKeyguardShowing || mSplitShadeEnabled) {
-            mQsMinExpansionHeight = 0;
-        } else {
-            mQsMinExpansionHeight = mQs.getQsMinExpansionHeight();
-        }
-        if (mQsExpansionHeight == previousMin) {
-            mQsExpansionHeight = mQsMinExpansionHeight;
-        }
-    }
-
     @NonNull
     private WindowInsets onApplyShadeWindowInsets(WindowInsets insets) {
         // the same types of insets that are handled in NotificationShadeWindowView
@@ -5982,6 +4479,7 @@
         mDisplayTopInset = combinedInsets.top;
         mDisplayRightInset = combinedInsets.right;
         mDisplayLeftInset = combinedInsets.left;
+        mQsController.setDisplayInsets(mDisplayRightInset, mDisplayLeftInset);
 
         mNavigationBarBottomHeight = insets.getStableInsetBottom();
         updateMaxHeadsUpTranslation();
@@ -5994,10 +4492,10 @@
     }
 
     private void onPanelStateChanged(@PanelState int state) {
-        updateQSExpansionEnabledAmbient();
+        mQsController.updateExpansionEnabledAmbient();
 
         if (state == STATE_OPEN && mCurrentPanelState != state) {
-            setQsExpandImmediate(false);
+            mQsController.setExpandImmediate(false);
             mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
         }
         if (state == STATE_OPENING) {
@@ -6005,12 +4503,12 @@
             // to locked will trigger this event and we're not actually in the process of opening
             // the shade, lockscreen is just always expanded
             if (mSplitShadeEnabled && !isOnKeyguard()) {
-                setQsExpandImmediate(true);
+                mQsController.setExpandImmediate(true);
             }
             mOpenCloseListener.onOpenStarted();
         }
         if (state == STATE_CLOSED) {
-            setQsExpandImmediate(false);
+            mQsController.setExpandImmediate(false);
             // Close the status bar in the next frame so we can show the end of the
             // animation.
             mView.post(mMaybeHideExpandedRunnable);
@@ -6076,7 +4574,7 @@
         /** @see ViewGroup#onInterceptTouchEvent(MotionEvent) */
         public boolean onInterceptTouchEvent(MotionEvent event) {
             mShadeLog.logMotionEvent(event, "NPVC onInterceptTouchEvent");
-            if (mQs.disallowPanelTouches()) {
+            if (mQsController.disallowTouches()) {
                 mShadeLog.logMotionEvent(event,
                         "NPVC not intercepting touch, panel touches disallowed");
                 return false;
@@ -6098,14 +4596,14 @@
                         + "HeadsUpTouchHelper");
                 return true;
             }
-            if (!shouldQuickSettingsIntercept(mDownX, mDownY, 0)
+            if (!mQsController.shouldQuickSettingsIntercept(mDownX, mDownY, 0)
                     && mPulseExpansionHandler.onInterceptTouchEvent(event)) {
                 mShadeLog.v("NotificationPanelViewController MotionEvent intercepted: "
                         + "PulseExpansionHandler");
                 return true;
             }
 
-            if (!isFullyCollapsed() && onQsIntercept(event)) {
+            if (!isFullyCollapsed() && mQsController.onIntercept(event)) {
                 debugLog("onQsIntercept true");
                 mShadeLog.v("NotificationPanelViewController MotionEvent intercepted: "
                         + "QsIntercept");
@@ -6139,11 +4637,6 @@
 
             switch (event.getActionMasked()) {
                 case MotionEvent.ACTION_DOWN:
-                    if (mTracking) {
-                        // TODO(b/247126247) fix underlying issue. Should be ACTION_POINTER_DOWN.
-                        mShadeLog.d("Don't intercept down event while already tracking");
-                        return false;
-                    }
                     mCentralSurfaces.userActivity();
                     mAnimatingOnDown = mHeightAnimator != null && !mIsSpringBackAnimation;
                     mMinExpandHeight = 0.0f;
@@ -6231,16 +4724,10 @@
                             "onTouch: duplicate down event detected... ignoring");
                     return true;
                 }
-                if (mTracking) {
-                    // TODO(b/247126247) fix underlying issue. Should be ACTION_POINTER_DOWN.
-                    mShadeLog.d("Don't handle down event while already tracking");
-                    return true;
-                }
                 mLastTouchDownTime = event.getDownTime();
             }
 
-
-            if (mQsFullyExpanded && mQs != null && mQs.disallowPanelTouches()) {
+            if (mQsController.isFullyExpandedAndTouchesDisallowed()) {
                 mShadeLog.logMotionEvent(event,
                         "onTouch: ignore touch, panel touches disallowed and qs fully expanded");
                 return false;
@@ -6271,7 +4758,7 @@
             // If pulse is expanding already, let's give it the touch. There are situations
             // where the panel starts expanding even though we're also pulsing
             boolean pulseShouldGetTouch = (!mIsExpanding
-                    && !shouldQuickSettingsIntercept(mDownX, mDownY, 0))
+                    && !mQsController.shouldQuickSettingsIntercept(mDownX, mDownY, 0))
                     || mPulseExpansionHandler.isExpanding();
             if (pulseShouldGetTouch && mPulseExpansionHandler.onTouchEvent(event)) {
                 // We're expanding all the other ones shouldn't get this anymore
@@ -6289,7 +4776,8 @@
             }
             boolean handled = mHeadsUpTouchHelper.onTouchEvent(event);
 
-            if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && handleQsTouch(event)) {
+            if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && mQsController.handleTouch(
+                    event, isFullyCollapsed(), isShadeOrQsHeightAnimationRunning())) {
                 mShadeLog.logMotionEvent(event, "onTouch: handleQsTouch handled event");
                 return true;
             }
@@ -6444,7 +4932,9 @@
                         mTouchAboveFalsingThreshold = true;
                         mUpwardsWhenThresholdReached = isDirectionUpwards(x, y);
                     }
-                    if ((!mGestureWaitForTouchSlop || mTracking) && !isTrackingBlocked()) {
+                    if ((!mGestureWaitForTouchSlop || mTracking)
+                            && !(mBlockingExpansionForCurrentTouch
+                            || mQsController.isTrackingBlocked())) {
                         // Count h==0 as part of swipe-up,
                         // otherwise {@link NotificationStackScrollLayout}
                         // wrongly enables stack height updates at the start of lockscreen swipe-up
@@ -6462,9 +4952,9 @@
                     // mHeightAnimator is null, there is no remaining frame, ends instrumenting.
                     if (mHeightAnimator == null) {
                         if (event.getActionMasked() == MotionEvent.ACTION_UP) {
-                            endJankMonitoring();
+                            mQsController.endJankMonitoring();
                         } else {
-                            cancelJankMonitoring();
+                            mQsController.cancelJankMonitoring();
                         }
                     }
                     break;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
index 1f0cbf9..74a61a3 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.shade;
 
-import static android.os.Trace.TRACE_TAG_ALWAYS;
+import static android.os.Trace.TRACE_TAG_APP;
 import static android.view.WindowInsets.Type.systemBars;
 
 import static com.android.systemui.statusbar.phone.CentralSurfaces.DEBUG;
@@ -328,7 +328,7 @@
 
     @Override
     public void requestLayout() {
-        Trace.instant(TRACE_TAG_ALWAYS, "NotificationShadeWindowView#requestLayout");
+        Trace.instant(TRACE_TAG_APP, "NotificationShadeWindowView#requestLayout");
         super.requestLayout();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index 60fa865..87350b46 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -38,8 +38,6 @@
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.dock.DockManager;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
@@ -132,7 +130,6 @@
             NotificationInsetsController notificationInsetsController,
             AmbientState ambientState,
             PulsingGestureListener pulsingGestureListener,
-            FeatureFlags featureFlags,
             KeyguardBouncerViewModel keyguardBouncerViewModel,
             KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory,
             AlternateBouncerInteractor alternateBouncerInteractor,
@@ -165,10 +162,8 @@
                 keyguardBouncerViewModel,
                 keyguardBouncerComponentFactory);
 
-        if (featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION)) {
-            collectFlow(mView, keyguardTransitionInteractor.getLockscreenToDreamingTransition(),
-                    mLockscreenToDreamingTransition);
-        }
+        collectFlow(mView, keyguardTransitionInteractor.getLockscreenToDreamingTransition(),
+                mLockscreenToDreamingTransition);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
index de02115..fb7c5c2 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
@@ -29,8 +29,6 @@
 import androidx.constraintlayout.widget.ConstraintSet.TOP
 import com.android.systemui.R
 import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
 import com.android.systemui.fragments.FragmentService
 import com.android.systemui.navigationbar.NavigationModeController
 import com.android.systemui.plugins.qs.QS
@@ -49,14 +47,13 @@
 internal const val INSET_DEBOUNCE_MILLIS = 500L
 
 class NotificationsQSContainerController @Inject constructor(
-    view: NotificationsQuickSettingsContainer,
-    private val navigationModeController: NavigationModeController,
-    private val overviewProxyService: OverviewProxyService,
-    private val largeScreenShadeHeaderController: LargeScreenShadeHeaderController,
-    private val shadeExpansionStateManager: ShadeExpansionStateManager,
-    private val featureFlags: FeatureFlags,
-    private val fragmentService: FragmentService,
-    @Main private val delayableExecutor: DelayableExecutor
+        view: NotificationsQuickSettingsContainer,
+        private val navigationModeController: NavigationModeController,
+        private val overviewProxyService: OverviewProxyService,
+        private val shadeHeaderController: ShadeHeaderController,
+        private val shadeExpansionStateManager: ShadeExpansionStateManager,
+        private val fragmentService: FragmentService,
+        @Main private val delayableExecutor: DelayableExecutor
 ) : ViewController<NotificationsQuickSettingsContainer>(view), QSContainerController {
 
     private var qsExpanded = false
@@ -75,8 +72,6 @@
     private var panelMarginHorizontal = 0
     private var topMargin = 0
 
-    private val useCombinedQSHeaders = featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)
-
     private var isGestureNavigation = true
     private var taskbarVisible = false
     private val taskbarVisibilityListener: OverviewProxyListener = object : OverviewProxyListener {
@@ -184,7 +179,7 @@
     override fun setCustomizerShowing(showing: Boolean, animationDuration: Long) {
         if (showing != isQSCustomizing) {
             isQSCustomizing = showing
-            largeScreenShadeHeaderController.startCustomizingAnimation(showing, animationDuration)
+            shadeHeaderController.startCustomizingAnimation(showing, animationDuration)
             updateBottomSpacing()
         }
     }
@@ -250,9 +245,7 @@
         if (largeScreenShadeHeaderActive) {
             constraintSet.constrainHeight(R.id.split_shade_status_bar, largeScreenShadeHeaderHeight)
         } else {
-            if (useCombinedQSHeaders) {
-                constraintSet.constrainHeight(R.id.split_shade_status_bar, WRAP_CONTENT)
-            }
+            constraintSet.constrainHeight(R.id.split_shade_status_bar, WRAP_CONTENT)
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt b/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt
new file mode 100644
index 0000000..3eec7fa0e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/QsBatteryModeController.kt
@@ -0,0 +1,70 @@
+package com.android.systemui.shade
+
+import android.content.Context
+import android.view.DisplayCutout
+import com.android.systemui.R
+import com.android.systemui.battery.BatteryMeterView
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
+import javax.inject.Inject
+
+/**
+ * Controls [BatteryMeterView.BatteryPercentMode]. It takes into account cutout and qs-qqs
+ * transition fraction when determining the mode.
+ */
+class QsBatteryModeController
+@Inject
+constructor(
+    private val context: Context,
+    private val insetsProvider: StatusBarContentInsetsProvider,
+) {
+
+    private companion object {
+        // MotionLayout frames are in [0, 100]. Where 0 and 100 are reserved for start and end
+        // frames.
+        const val MOTION_LAYOUT_MAX_FRAME = 100
+        // We add a single buffer frame to ensure that battery view faded out completely when we are
+        // about to change it's state
+        const val BUFFER_FRAME_COUNT = 1
+    }
+
+    private var fadeInStartFraction: Float = 0f
+    private var fadeOutCompleteFraction: Float = 0f
+
+    init {
+        updateResources()
+    }
+
+    /**
+     * Returns an appropriate [BatteryMeterView.BatteryPercentMode] for the [qsExpandedFraction] and
+     * [cutout]. We don't show battery estimation in qqs header on the devices with center cutout.
+     * The result might be null when the battery icon is invisible during the qs-qqs transition
+     * animation.
+     */
+    @BatteryMeterView.BatteryPercentMode
+    fun getBatteryMode(cutout: DisplayCutout?, qsExpandedFraction: Float): Int? =
+        when {
+            qsExpandedFraction > fadeInStartFraction -> BatteryMeterView.MODE_ESTIMATE
+            qsExpandedFraction < fadeOutCompleteFraction ->
+                if (hasCenterCutout(cutout)) {
+                    BatteryMeterView.MODE_ON
+                } else {
+                    BatteryMeterView.MODE_ESTIMATE
+                }
+            else -> null
+        }
+
+    fun updateResources() {
+        fadeInStartFraction =
+            (context.resources.getInteger(R.integer.fade_in_start_frame) - BUFFER_FRAME_COUNT) /
+                MOTION_LAYOUT_MAX_FRAME.toFloat()
+        fadeOutCompleteFraction =
+            (context.resources.getInteger(R.integer.fade_out_complete_frame) + BUFFER_FRAME_COUNT) /
+                MOTION_LAYOUT_MAX_FRAME.toFloat()
+    }
+
+    private fun hasCenterCutout(cutout: DisplayCutout?): Boolean =
+        cutout?.let {
+            !insetsProvider.currentRotationHasCornerCutout() && !it.boundingRectTop.isEmpty
+        }
+            ?: false
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
new file mode 100644
index 0000000..099ad94
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
@@ -0,0 +1,2087 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.systemui.shade;
+
+import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE;
+import static com.android.systemui.classifier.Classifier.QS_COLLAPSE;
+import static com.android.systemui.shade.NotificationPanelViewController.COUNTER_PANEL_OPEN_QS;
+import static com.android.systemui.shade.NotificationPanelViewController.FLING_COLLAPSE;
+import static com.android.systemui.shade.NotificationPanelViewController.FLING_EXPAND;
+import static com.android.systemui.shade.NotificationPanelViewController.FLING_HIDE;
+import static com.android.systemui.shade.NotificationPanelViewController.QS_PARALLAX_AMOUNT;
+import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.app.Fragment;
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.util.Log;
+import android.util.MathUtils;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.FrameLayout;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.policy.ScreenDecorationsUtils;
+import com.android.internal.policy.SystemBarUtils;
+import com.android.keyguard.FaceAuthApiRequestReason;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
+import com.android.systemui.classifier.Classifier;
+import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.media.controls.pipeline.MediaDataManager;
+import com.android.systemui.media.controls.ui.MediaHierarchyManager;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.qs.QS;
+import com.android.systemui.screenrecord.RecordingController;
+import com.android.systemui.shade.transition.ShadeTransitionController;
+import com.android.systemui.statusbar.LockscreenShadeTransitionController;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationShadeDepthController;
+import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.QsFrameTranslateController;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.stack.AmbientState;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
+import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
+import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
+import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.LargeScreenUtils;
+
+import javax.inject.Inject;
+
+import dagger.Lazy;
+
+/** Handles QuickSettings touch handling, expansion and animation state
+ * TODO (b/264460656) make this dumpable
+ */
+@CentralSurfacesComponent.CentralSurfacesScope
+public class QuickSettingsController {
+    public static final String TAG = "QuickSettingsController";
+
+    private QS mQs;
+    private final Lazy<NotificationPanelViewController> mPanelViewControllerLazy;
+
+    private final NotificationPanelView mPanelView;
+    private final KeyguardStatusBarView mKeyguardStatusBar;
+    private final FrameLayout mQsFrame;
+
+    private final QsFrameTranslateController mQsFrameTranslateController;
+    private final ShadeTransitionController mShadeTransitionController;
+    private final PulseExpansionHandler mPulseExpansionHandler;
+    private final ShadeExpansionStateManager mShadeExpansionStateManager;
+    private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
+    private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
+    private final NotificationShadeDepthController mDepthController;
+    private final ShadeHeaderController mShadeHeaderController;
+    private final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+    private final KeyguardStateController mKeyguardStateController;
+    private final KeyguardBypassController mKeyguardBypassController;
+    private final NotificationRemoteInputManager mRemoteInputManager;
+    private VelocityTracker mQsVelocityTracker;
+    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    private final ScrimController mScrimController;
+    private final MediaDataManager mMediaDataManager;
+    private final MediaHierarchyManager mMediaHierarchyManager;
+    private final AmbientState mAmbientState;
+    private final RecordingController mRecordingController;
+    private final FalsingCollector mFalsingCollector;
+    private final LockscreenGestureLogger mLockscreenGestureLogger;
+    private final ShadeLogger mShadeLog;
+    private final FeatureFlags mFeatureFlags;
+    private final InteractionJankMonitor mInteractionJankMonitor;
+    private final FalsingManager mFalsingManager;
+    private final AccessibilityManager mAccessibilityManager;
+    private final MetricsLogger mMetricsLogger;
+    private final Resources mResources;
+
+    /** Whether the notifications are displayed full width (no margins on the side). */
+    private boolean mIsFullWidth;
+    private int mTouchSlop;
+    private float mSlopMultiplier;
+    /** the current {@link StatusBarState} */
+    private int mBarState;
+    private int mStatusBarMinHeight;
+    private boolean mScrimEnabled = true;
+    private int mScrimCornerRadius;
+    private int mScreenCornerRadius;
+    private boolean mUseLargeScreenShadeHeader;
+    private int mLargeScreenShadeHeaderHeight;
+    private int mDisplayRightInset = 0; // in pixels
+    private int mDisplayLeftInset = 0; // in pixels
+    private boolean mSplitShadeEnabled;
+    /**
+     * The padding between the start of notifications and the qs boundary on the lockscreen.
+     * On lockscreen, notifications aren't inset this extra amount, but we still want the
+     * qs boundary to be padded.
+     */
+    private int mLockscreenNotificationPadding;
+    private int mSplitShadeNotificationsScrimMarginBottom;
+    private boolean mDozing;
+    private boolean mEnableClipping;
+    private int mFalsingThreshold;
+    /**
+     * Position of the qs bottom during the full shade transition. This is needed as the toppadding
+     * can change during state changes, which makes it much harder to do animations
+     */
+    private int mTransitionToFullShadePosition;
+    private boolean mCollapsedOnDown;
+    private float mShadeExpandedHeight = 0;
+    private boolean mLastShadeFlingWasExpanding;
+
+    private float mInitialHeightOnTouch;
+    private float mInitialTouchX;
+    private float mInitialTouchY;
+    /** whether current touch Y delta is above falsing threshold */
+    private boolean mTouchAboveFalsingThreshold;
+    /** whether we are tracking a touch on QS container */
+    private boolean mTracking;
+    /** pointerId of the pointer we're currently tracking */
+    private int mTrackingPointer;
+
+    /**
+     * Indicates that QS is in expanded state which can happen by:
+     * - single pane shade: expanding shade and then expanding QS
+     * - split shade: just expanding shade (QS are expanded automatically)
+     */
+    private boolean mExpanded;
+    /** Indicates QS is at its max height */
+    private boolean mFullyExpanded;
+    /**
+     * Determines if QS should be already expanded when expanding shade.
+     * Used for split shade, two finger gesture as well as accessibility shortcut to QS.
+     * It needs to be set when movement starts as it resets at the end of expansion/collapse.
+     */
+    private boolean mExpandImmediate;
+    private boolean mExpandedWhenExpandingStarted;
+    private boolean mAnimatingHiddenFromCollapsed;
+    private boolean mVisible;
+    private float mExpansionHeight;
+    /**
+     * QS height when QS expansion fraction is 0 so when QS is collapsed. That state doesn't really
+     * exist for split shade so currently this value is always 0 then.
+     */
+    private int mMinExpansionHeight;
+    /** QS height when QS expansion fraction is 1 so qs is fully expanded */
+    private int mMaxExpansionHeight;
+    /** Expansion fraction of the notification shade */
+    private float mShadeExpandedFraction;
+    private int mPeekHeight;
+    private float mLastOverscroll;
+    private boolean mExpansionFromOverscroll;
+    private boolean mExpansionEnabledPolicy = true;
+    private boolean mExpansionEnabledAmbient = true;
+    private float mQuickQsHeaderHeight;
+    /**
+     * Determines if QS should be already expanded when expanding shade.
+     * Used for split shade, two finger gesture as well as accessibility shortcut to QS.
+     * It needs to be set when movement starts as it resets at the end of expansion/collapse.
+     */
+    private boolean mTwoFingerExpandPossible;
+    /** Whether the ongoing gesture might both trigger the expansion in both the view and QS. */
+    private boolean mConflictingExpansionGesture;
+    /**
+     * If we are in a panel collapsing motion, we reset scrollY of our scroll view but still
+     * need to take this into account in our panel height calculation.
+     */
+    private boolean mAnimatorExpand;
+
+    /**
+     * The amount of progress we are currently in if we're transitioning to the full shade.
+     * 0.0f means we're not transitioning yet, while 1 means we're all the way in the full
+     * shade. This value can also go beyond 1.1 when we're overshooting!
+     */
+    private float mTransitioningToFullShadeProgress;
+    /** Distance a full shade transition takes in order for qs to fully transition to the shade. */
+    private int mDistanceForFullShadeTransition;
+    private boolean mStackScrollerOverscrolling;
+    /** Indicates QS is animating - set by flingQs */
+    private boolean mAnimating;
+    /** Whether the current animator is resetting the qs translation. */
+    private boolean mIsTranslationResettingAnimator;
+    /** Whether the current animator is resetting the pulse expansion after a drag down. */
+    private boolean mIsPulseExpansionResettingAnimator;
+    /** The translation amount for QS for the full shade transition. */
+    private float mTranslationForFullShadeTransition;
+    /** Should we animate the next bounds update. */
+    private boolean mAnimateNextNotificationBounds;
+    /** The delay for the next bounds animation. */
+    private long mNotificationBoundsAnimationDelay;
+    /** The duration of the notification bounds animation. */
+    private long mNotificationBoundsAnimationDuration;
+
+    private final Region mInterceptRegion = new Region();
+    /** The end bounds of a clipping animation. */
+    private final Rect mClippingAnimationEndBounds = new Rect();
+    private final Rect mLastClipBounds = new Rect();
+
+    /** The animator for the qs clipping bounds. */
+    private ValueAnimator mClippingAnimator = null;
+    /** The main animator for QS expansion */
+    private ValueAnimator mExpansionAnimator;
+    /** The animator for QS size change */
+    private ValueAnimator mSizeChangeAnimator;
+
+    private ExpansionHeightListener mExpansionHeightListener;
+    private QsStateUpdateListener mQsStateUpdateListener;
+    private ApplyClippingImmediatelyListener mApplyClippingImmediatelyListener;
+    private FlingQsWithoutClickListener mFlingQsWithoutClickListener;
+    private ExpansionHeightSetToMaxListener mExpansionHeightSetToMaxListener;
+    private final QS.HeightListener mQsHeightListener = this::onHeightChanged;
+    private final Runnable mQsCollapseExpandAction = this::collapseOrExpandQs;
+    private final QS.ScrollListener mQsScrollListener = this::onScroll;
+
+    @Inject
+    public QuickSettingsController(
+            Lazy<NotificationPanelViewController> panelViewControllerLazy,
+            NotificationPanelView panelView,
+            QsFrameTranslateController qsFrameTranslateController,
+            ShadeTransitionController shadeTransitionController,
+            PulseExpansionHandler pulseExpansionHandler,
+            NotificationRemoteInputManager remoteInputManager,
+            ShadeExpansionStateManager shadeExpansionStateManager,
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+            NotificationStackScrollLayoutController notificationStackScrollLayoutController,
+            LockscreenShadeTransitionController lockscreenShadeTransitionController,
+            NotificationShadeDepthController notificationShadeDepthController,
+            ShadeHeaderController shadeHeaderController,
+            StatusBarTouchableRegionManager statusBarTouchableRegionManager,
+            KeyguardStateController keyguardStateController,
+            KeyguardBypassController keyguardBypassController,
+            KeyguardUpdateMonitor keyguardUpdateMonitor,
+            ScrimController scrimController,
+            MediaDataManager mediaDataManager,
+            MediaHierarchyManager mediaHierarchyManager,
+            AmbientState ambientState,
+            RecordingController recordingController,
+            FalsingManager falsingManager,
+            FalsingCollector falsingCollector,
+            AccessibilityManager accessibilityManager,
+            LockscreenGestureLogger lockscreenGestureLogger,
+            MetricsLogger metricsLogger,
+            FeatureFlags featureFlags,
+            InteractionJankMonitor interactionJankMonitor,
+            ShadeLogger shadeLog
+    ) {
+        mPanelViewControllerLazy = panelViewControllerLazy;
+        mPanelView = panelView;
+        mQsFrame = mPanelView.findViewById(R.id.qs_frame);
+        mKeyguardStatusBar = mPanelView.findViewById(R.id.keyguard_header);
+        mResources = mPanelView.getResources();
+        mSplitShadeEnabled = LargeScreenUtils.shouldUseSplitNotificationShade(mResources);
+        mQsFrameTranslateController = qsFrameTranslateController;
+        mShadeTransitionController = shadeTransitionController;
+        mPulseExpansionHandler = pulseExpansionHandler;
+        pulseExpansionHandler.setPulseExpandAbortListener(() -> {
+            if (mQs != null) {
+                mQs.animateHeaderSlidingOut();
+            }
+        });
+        mRemoteInputManager = remoteInputManager;
+        mShadeExpansionStateManager = shadeExpansionStateManager;
+        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+        mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
+        mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
+        mDepthController = notificationShadeDepthController;
+        mShadeHeaderController = shadeHeaderController;
+        mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
+        mKeyguardStateController = keyguardStateController;
+        mKeyguardBypassController = keyguardBypassController;
+        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+        mScrimController = scrimController;
+        mMediaDataManager = mediaDataManager;
+        mMediaHierarchyManager = mediaHierarchyManager;
+        mAmbientState = ambientState;
+        mRecordingController = recordingController;
+        mFalsingManager = falsingManager;
+        mFalsingCollector = falsingCollector;
+        mAccessibilityManager = accessibilityManager;
+
+        mLockscreenGestureLogger = lockscreenGestureLogger;
+        mMetricsLogger = metricsLogger;
+        mShadeLog = shadeLog;
+        mFeatureFlags = featureFlags;
+        mInteractionJankMonitor = interactionJankMonitor;
+
+        mShadeExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged);
+        mLockscreenShadeTransitionController.addCallback(new LockscreenShadeTransitionCallback());
+    }
+
+    @VisibleForTesting
+    void setQs(QS qs) {
+        mQs = qs;
+    }
+
+    public void setExpansionHeightListener(ExpansionHeightListener listener) {
+        mExpansionHeightListener = listener;
+    }
+
+    public void setQsStateUpdateListener(QsStateUpdateListener listener) {
+        mQsStateUpdateListener = listener;
+    }
+
+    public void setApplyClippingImmediatelyListener(ApplyClippingImmediatelyListener listener) {
+        mApplyClippingImmediatelyListener = listener;
+    }
+
+    public void setFlingQsWithoutClickListener(FlingQsWithoutClickListener listener) {
+        mFlingQsWithoutClickListener = listener;
+    }
+
+    public void setExpansionHeightSetToMaxListener(ExpansionHeightSetToMaxListener callback) {
+        mExpansionHeightSetToMaxListener = callback;
+    }
+
+    void loadDimens() {
+        final ViewConfiguration configuration = ViewConfiguration.get(this.mPanelView.getContext());
+        mTouchSlop = configuration.getScaledTouchSlop();
+        mSlopMultiplier = configuration.getScaledAmbiguousGestureMultiplier();
+        mPeekHeight = mResources.getDimensionPixelSize(R.dimen.qs_peek_height);
+        mStatusBarMinHeight = SystemBarUtils.getStatusBarHeight(mPanelView.getContext());
+        mScrimCornerRadius = mResources.getDimensionPixelSize(
+                R.dimen.notification_scrim_corner_radius);
+        mScreenCornerRadius = (int) ScreenDecorationsUtils.getWindowCornerRadius(
+                mPanelView.getContext());
+        mFalsingThreshold = mResources.getDimensionPixelSize(R.dimen.qs_falsing_threshold);
+        mLockscreenNotificationPadding = mResources.getDimensionPixelSize(
+                R.dimen.notification_side_paddings);
+        mDistanceForFullShadeTransition = mResources.getDimensionPixelSize(
+                R.dimen.lockscreen_shade_qs_transition_distance);
+    }
+
+    void updateResources() {
+        mSplitShadeEnabled = LargeScreenUtils.shouldUseSplitNotificationShade(mResources);
+        if (mQs != null) {
+            mQs.setInSplitShade(mSplitShadeEnabled);
+        }
+        mSplitShadeNotificationsScrimMarginBottom =
+                mResources.getDimensionPixelSize(
+                        R.dimen.split_shade_notifications_scrim_margin_bottom);
+
+        mUseLargeScreenShadeHeader =
+                LargeScreenUtils.shouldUseLargeScreenShadeHeader(mPanelView.getResources());
+        mLargeScreenShadeHeaderHeight =
+                mResources.getDimensionPixelSize(R.dimen.large_screen_shade_header_height);
+        int topMargin = mUseLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight :
+                mResources.getDimensionPixelSize(R.dimen.notification_panel_margin_top);
+        mShadeHeaderController.setLargeScreenActive(mUseLargeScreenShadeHeader);
+        mAmbientState.setStackTopMargin(topMargin);
+
+        mQuickQsHeaderHeight = mLargeScreenShadeHeaderHeight;
+
+        mEnableClipping = mResources.getBoolean(R.bool.qs_enable_clipping);
+    }
+
+    // TODO (b/265054088): move this and others to a CoreStartable
+    void initNotificationStackScrollLayoutController() {
+        mNotificationStackScrollLayoutController.setOverscrollTopChangedListener(
+                new NsslOverscrollTopChangedListener());
+        mNotificationStackScrollLayoutController.setOnStackYChanged(this::onStackYChanged);
+        mNotificationStackScrollLayoutController.setOnScrollListener(this::onNotificationScrolled);
+    }
+
+    private void onStackYChanged(boolean shouldAnimate) {
+        if (isQsFragmentCreated()) {
+            if (shouldAnimate) {
+                setAnimateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_STANDARD,
+                        0 /* delay */);
+            }
+            setClippingBounds();
+        }
+    }
+
+    private void onNotificationScrolled(int newScrollPosition) {
+        updateExpansionEnabledAmbient();
+    }
+
+    @VisibleForTesting
+    void setStatusBarMinHeight(int height) {
+        mStatusBarMinHeight = height;
+    }
+
+    int getHeaderHeight() {
+        return mQs.getHeader().getHeight();
+    }
+
+    /** Returns the padding of the stackscroller when unlocked */
+    int getUnlockedStackScrollerPadding() {
+        return (mQs != null ? mQs.getHeader().getHeight() : 0) + mPeekHeight;
+    }
+
+    public boolean isExpansionEnabled() {
+        return mExpansionEnabledPolicy && mExpansionEnabledAmbient
+                && !mRemoteInputManager.isRemoteInputActive();
+    }
+
+    public float getTransitioningToFullShadeProgress() {
+        return mTransitioningToFullShadeProgress;
+    }
+
+    /** */
+    @VisibleForTesting
+    boolean isExpandImmediate() {
+        return mExpandImmediate;
+    }
+
+    float getInitialTouchY() {
+        return mInitialTouchY;
+    }
+
+    /** Returns whether split shade is enabled and an x coordinate is outside of the QS frame. */
+    private boolean isSplitShadeAndTouchXOutsideQs(float touchX) {
+        return mSplitShadeEnabled && touchX < mQsFrame.getX()
+                || touchX > mQsFrame.getX() + mQsFrame.getWidth();
+    }
+
+    /** Returns whether touch is within QS area */
+    private boolean isTouchInQsArea(float x, float y) {
+        if (isSplitShadeAndTouchXOutsideQs(x)) {
+            return false;
+        }
+        // TODO (b/265193930): remove dependency on NPVC
+        // Let's reject anything at the very bottom around the home handle in gesture nav
+        if (mPanelViewControllerLazy.get().isInGestureNavHomeHandleArea(x, y)) {
+            return false;
+        }
+        return y <= mNotificationStackScrollLayoutController.getBottomMostNotificationBottom()
+                || y <= mQs.getView().getY() + mQs.getView().getHeight();
+    }
+
+    /** Returns whether or not event should open QS */
+    @VisibleForTesting
+    boolean isOpenQsEvent(MotionEvent event) {
+        final int pointerCount = event.getPointerCount();
+        final int action = event.getActionMasked();
+
+        final boolean
+                twoFingerDrag =
+                action == MotionEvent.ACTION_POINTER_DOWN && pointerCount == 2;
+
+        final boolean
+                stylusButtonClickDrag =
+                action == MotionEvent.ACTION_DOWN && (event.isButtonPressed(
+                        MotionEvent.BUTTON_STYLUS_PRIMARY) || event.isButtonPressed(
+                        MotionEvent.BUTTON_STYLUS_SECONDARY));
+
+        final boolean
+                mouseButtonClickDrag =
+                action == MotionEvent.ACTION_DOWN && (event.isButtonPressed(
+                        MotionEvent.BUTTON_SECONDARY) || event.isButtonPressed(
+                        MotionEvent.BUTTON_TERTIARY));
+
+        return twoFingerDrag || stylusButtonClickDrag || mouseButtonClickDrag;
+    }
+
+
+    public boolean getExpanded() {
+        return mExpanded;
+    }
+
+    @VisibleForTesting
+    boolean isTracking() {
+        return mTracking;
+    }
+
+    public boolean getFullyExpanded() {
+        return mFullyExpanded;
+    }
+
+    boolean isGoingBetweenClosedShadeAndExpandedQs() {
+        // Below is true when QS are expanded and we swipe up from the same bottom of panel to
+        // close the whole shade with one motion. Also this will be always true when closing
+        // split shade as there QS are always expanded so every collapsing motion is motion from
+        // expanded QS to closed panel
+        return mExpandImmediate || (mExpanded
+                && !mTracking && !isExpansionAnimating()
+                && !mExpansionFromOverscroll);
+    }
+
+    private boolean isQsFragmentCreated() {
+        return mQs != null;
+    }
+
+    public boolean isCustomizing() {
+        return isQsFragmentCreated() && mQs.isCustomizing();
+    }
+
+    public float getExpansionHeight() {
+        return mExpansionHeight;
+    }
+
+    public boolean getExpandedWhenExpandingStarted() {
+        return mExpandedWhenExpandingStarted;
+    }
+
+    public int getMinExpansionHeight() {
+        return mMinExpansionHeight;
+    }
+
+    public boolean isFullyExpandedAndTouchesDisallowed() {
+        return isQsFragmentCreated() && getFullyExpanded() && disallowTouches();
+    }
+
+    public int getMaxExpansionHeight() {
+        return mMaxExpansionHeight;
+    }
+
+    private boolean isQsFalseTouch() {
+        if (mFalsingManager.isClassifierEnabled()) {
+            return mFalsingManager.isFalseTouch(Classifier.QUICK_SETTINGS);
+        }
+        return !mTouchAboveFalsingThreshold;
+    }
+
+    public int getFalsingThreshold() {
+        return mFalsingThreshold;
+    }
+
+    /**
+     * Returns Whether we should intercept a gesture to open Quick Settings.
+     */
+    public boolean shouldQuickSettingsIntercept(float x, float y, float yDiff) {
+        boolean keyguardShowing = mBarState == KEYGUARD;
+        if (!isExpansionEnabled() || mCollapsedOnDown || (keyguardShowing
+                && mKeyguardBypassController.getBypassEnabled()) || mSplitShadeEnabled) {
+            return false;
+        }
+        View header = keyguardShowing || mQs == null ? mKeyguardStatusBar : mQs.getHeader();
+        int frameTop = keyguardShowing
+                || mQs == null ? 0 : mQsFrame.getTop();
+        mInterceptRegion.set(
+                /* left= */ (int) mQsFrame.getX(),
+                /* top= */ header.getTop() + frameTop,
+                /* right= */ (int) mQsFrame.getX() + mQsFrame.getWidth(),
+                /* bottom= */ header.getBottom() + frameTop);
+        // Also allow QS to intercept if the touch is near the notch.
+        mStatusBarTouchableRegionManager.updateRegionForNotch(mInterceptRegion);
+        final boolean onHeader = mInterceptRegion.contains((int) x, (int) y);
+
+        if (getExpanded()) {
+            return onHeader || (yDiff < 0 && isTouchInQsArea(x, y));
+        } else {
+            return onHeader;
+        }
+    }
+
+    /** Returns amount header should be translated */
+    private float getHeaderTranslation() {
+        if (mSplitShadeEnabled) {
+            // in split shade QS don't translate, just (un)squish and overshoot
+            return 0;
+        }
+        if (mBarState == KEYGUARD && !mKeyguardBypassController.getBypassEnabled()) {
+            return -mQs.getQsMinExpansionHeight();
+        }
+        float appearAmount = mNotificationStackScrollLayoutController
+                .calculateAppearFraction(mShadeExpandedHeight);
+        float startHeight = -getExpansionHeight();
+        if (mBarState == StatusBarState.SHADE) {
+            // Small parallax as we pull down and clip QS
+            startHeight = -getExpansionHeight() * QS_PARALLAX_AMOUNT;
+        }
+        if (mKeyguardBypassController.getBypassEnabled() && mBarState == KEYGUARD) {
+            appearAmount = mNotificationStackScrollLayoutController.calculateAppearFractionBypass();
+            startHeight = -mQs.getQsMinExpansionHeight();
+        }
+        float translation = MathUtils.lerp(startHeight, 0, Math.min(1.0f, appearAmount));
+        return Math.min(0, translation);
+    }
+
+    /**
+     * Can the panel collapse in this motion because it was started on QQS?
+     *
+     * @param downX the x location where the touch started
+     * @param downY the y location where the touch started
+     * Returns true if the panel could be collapsed because it stared on QQS
+     */
+    public boolean canPanelCollapseOnQQS(float downX, float downY) {
+        if (mCollapsedOnDown || mBarState == KEYGUARD || getExpanded()) {
+            return false;
+        }
+        View header = mQs == null ? mKeyguardStatusBar : mQs.getHeader();
+        return downX >= mQsFrame.getX() && downX <= mQsFrame.getX() + mQsFrame.getWidth()
+                && downY <= header.getBottom();
+    }
+
+    /** Closes the Qs customizer. */
+    public void closeQsCustomizer() {
+        mQs.closeCustomizer();
+    }
+
+    /** Returns whether touches from the notification panel should be disallowed */
+    public boolean disallowTouches() {
+        return mQs.disallowPanelTouches();
+    }
+
+    void setListening(boolean listening) {
+        if (mQs != null) {
+            mQs.setListening(listening);
+        }
+    }
+
+    void hideQsImmediately() {
+        if (mQs != null) {
+            mQs.hideImmediately();
+        }
+    }
+
+    public void setDozing(boolean dozing) {
+        mDozing = dozing;
+    }
+
+    /**
+     * This method closes QS but in split shade it should be used only in special cases: to make
+     * sure QS closes when shade is closed as well. Otherwise it will result in QS disappearing
+     * from split shade
+     */
+    public void closeQs() {
+        if (mSplitShadeEnabled) {
+            mShadeLog.d("Closing QS while in split shade");
+        }
+        cancelExpansionAnimation();
+        setExpansionHeight(getMinExpansionHeight());
+        // qsExpandImmediate is a safety latch in case we're calling closeQS while we're in the
+        // middle of animation - we need to make sure that value is always false when shade if
+        // fully collapsed or expanded
+        setExpandImmediate(false);
+    }
+
+    @VisibleForTesting
+    void setExpanded(boolean expanded) {
+        boolean changed = mExpanded != expanded;
+        if (changed) {
+            mExpanded = expanded;
+            updateQsState();
+            mShadeExpansionStateManager.onQsExpansionChanged(expanded);
+            mShadeLog.logQsExpansionChanged("QS Expansion Changed.", expanded,
+                    getMinExpansionHeight(), getMaxExpansionHeight(),
+                    mStackScrollerOverscrolling, mAnimatorExpand, mAnimating);
+        }
+    }
+
+    void setLastShadeFlingWasExpanding(boolean expanding) {
+        mLastShadeFlingWasExpanding = expanding;
+        mShadeLog.logLastFlingWasExpanding(expanding);
+    }
+
+    /** update Qs height state */
+    public void setExpansionHeight(float height) {
+        checkCorrectSplitShadeState(height);
+        int maxHeight = getMaxExpansionHeight();
+        height = Math.min(Math.max(
+                height, getMinExpansionHeight()), maxHeight);
+        mFullyExpanded = height == maxHeight && maxHeight != 0;
+        boolean qsAnimatingAway = !mAnimatorExpand && mAnimating;
+        if (height > getMinExpansionHeight() && !getExpanded()
+                && !mStackScrollerOverscrolling
+                && !mDozing && !qsAnimatingAway) {
+            setExpanded(true);
+        } else if (height <= getMinExpansionHeight()
+                && getExpanded()) {
+            setExpanded(false);
+        }
+        mExpansionHeight = height;
+        updateExpansion();
+
+        if (mExpansionHeightListener != null) {
+            mExpansionHeightListener.onQsSetExpansionHeightCalled(getFullyExpanded());
+        }
+    }
+
+    /** TODO(b/269742565) Remove this logging */
+    private void checkCorrectSplitShadeState(float height) {
+        if (mSplitShadeEnabled && height == 0
+                && mPanelViewControllerLazy.get().isShadeFullyOpen()) {
+            Log.wtfStack(TAG, "qsExpansion set to 0 while split shade is expanding or open");
+        }
+    }
+
+    /** */
+    public void setHeightOverrideToDesiredHeight() {
+        if (isSizeChangeAnimationRunning() && isQsFragmentCreated()) {
+            mQs.setHeightOverride(mQs.getDesiredHeight());
+        }
+    }
+
+    /** Updates quick setting heights and returns old max height. */
+    int updateHeightsOnShadeLayoutChange() {
+        int oldMaxHeight = getMaxExpansionHeight();
+        if (isQsFragmentCreated()) {
+            updateMinHeight();
+            mMaxExpansionHeight = mQs.getDesiredHeight();
+            mNotificationStackScrollLayoutController.setMaxTopPadding(
+                    getMaxExpansionHeight());
+        }
+        return oldMaxHeight;
+    }
+
+    /** Called when Shade view layout changed. Updates QS expansion or
+     * starts size change animation if height has changed. */
+    void handleShadeLayoutChanged(int oldMaxHeight) {
+        if (mExpanded && mFullyExpanded) {
+            mExpansionHeight = mMaxExpansionHeight;
+            if (mExpansionHeightSetToMaxListener != null) {
+                mExpansionHeightSetToMaxListener.onExpansionHeightSetToMax(true);
+            }
+
+            // Size has changed, start an animation.
+            if (getMaxExpansionHeight() != oldMaxHeight) {
+                startSizeChangeAnimation(oldMaxHeight,
+                        getMaxExpansionHeight());
+            }
+        } else if (!getExpanded()
+                && !isExpansionAnimating()) {
+            setExpansionHeight(getMinExpansionHeight() + mLastOverscroll);
+        } else {
+            mShadeLog.v("onLayoutChange: qs expansion not set");
+        }
+    }
+
+    private boolean isSizeChangeAnimationRunning() {
+        return mSizeChangeAnimator != null;
+    }
+
+    private void startSizeChangeAnimation(int oldHeight, final int newHeight) {
+        if (mSizeChangeAnimator != null) {
+            oldHeight = (int) mSizeChangeAnimator.getAnimatedValue();
+            mSizeChangeAnimator.cancel();
+        }
+        mSizeChangeAnimator = ValueAnimator.ofInt(oldHeight, newHeight);
+        mSizeChangeAnimator.setDuration(300);
+        mSizeChangeAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+        mSizeChangeAnimator.addUpdateListener(animation -> {
+            if (mExpansionHeightSetToMaxListener != null) {
+                mExpansionHeightSetToMaxListener.onExpansionHeightSetToMax(true);
+            }
+
+            int height = (int) mSizeChangeAnimator.getAnimatedValue();
+            mQs.setHeightOverride(height);
+        });
+        mSizeChangeAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mSizeChangeAnimator = null;
+            }
+        });
+        mSizeChangeAnimator.start();
+    }
+
+    void setNotificationPanelFullWidth(boolean isFullWidth) {
+        mIsFullWidth = isFullWidth;
+        if (mQs != null) {
+            mQs.setIsNotificationPanelFullWidth(isFullWidth);
+        }
+    }
+
+    void setBarState(int barState) {
+        mBarState = barState;
+    }
+
+    /** */
+    public void setExpansionEnabledPolicy(boolean expansionEnabledPolicy) {
+        mExpansionEnabledPolicy = expansionEnabledPolicy;
+        if (mQs != null) {
+            mQs.setHeaderClickable(isExpansionEnabled());
+        }
+    }
+
+    void setOverScrollAmount(int overExpansion) {
+        mQs.setOverScrollAmount(overExpansion);
+    }
+
+    private void setOverScrolling(boolean overscrolling) {
+        mStackScrollerOverscrolling = overscrolling;
+        if (mQs != null) {
+            mQs.setOverscrolling(overscrolling);
+        }
+    }
+
+    /** Sets Qs ScrimEnabled and updates QS state. */
+    public void setScrimEnabled(boolean scrimEnabled) {
+        boolean changed = mScrimEnabled != scrimEnabled;
+        mScrimEnabled = scrimEnabled;
+        if (changed) {
+            updateQsState();
+        }
+    }
+
+    void setCollapsedOnDown(boolean collapsedOnDown) {
+        mCollapsedOnDown = collapsedOnDown;
+    }
+
+    void setShadeExpandedHeight(float shadeExpandedHeight) {
+        mShadeExpandedHeight = shadeExpandedHeight;
+    }
+
+    @VisibleForTesting
+    float getShadeExpandedHeight() {
+        return mShadeExpandedHeight;
+    }
+
+    @VisibleForTesting
+    void setExpandImmediate(boolean expandImmediate) {
+        if (expandImmediate != mExpandImmediate) {
+            mShadeLog.logQsExpandImmediateChanged(expandImmediate);
+            mExpandImmediate = expandImmediate;
+            mShadeExpansionStateManager.notifyExpandImmediateChange(expandImmediate);
+        }
+    }
+
+    void setTwoFingerExpandPossible(boolean expandPossible) {
+        mTwoFingerExpandPossible = expandPossible;
+    }
+
+    @VisibleForTesting
+    boolean isTwoFingerExpandPossible() {
+        return mTwoFingerExpandPossible;
+    }
+
+    /** Called when Qs starts expanding */
+    private void onExpansionStarted() {
+        cancelExpansionAnimation();
+        // TODO (b/265193930): remove dependency on NPVC
+        mPanelViewControllerLazy.get().cancelHeightAnimator();
+        // end
+
+        // Reset scroll position and apply that position to the expanded height.
+        float height = mExpansionHeight;
+        setExpansionHeight(height);
+        mNotificationStackScrollLayoutController.checkSnoozeLeavebehind();
+
+        // When expanding QS, let's authenticate the user if possible,
+        // this will speed up notification actions.
+        if (height == 0 && !mKeyguardStateController.canDismissLockScreen()) {
+            mKeyguardUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.QS_EXPANDED);
+        }
+    }
+
+    void updateQsState() {
+        boolean qsFullScreen = mExpanded && !mSplitShadeEnabled;
+        mNotificationStackScrollLayoutController.setQsFullScreen(qsFullScreen);
+        mNotificationStackScrollLayoutController.setScrollingEnabled(
+                mBarState != KEYGUARD && (!qsFullScreen || mExpansionFromOverscroll));
+
+        if (mQsStateUpdateListener != null) {
+            mQsStateUpdateListener.onQsStateUpdated(mExpanded, mStackScrollerOverscrolling);
+        }
+
+        if (mQs == null) return;
+        mQs.setExpanded(mExpanded);
+    }
+
+    /** update expanded state of QS */
+    public void updateExpansion() {
+        if (mQs == null) return;
+        final float squishiness;
+        if ((mExpandImmediate || mExpanded) && !mSplitShadeEnabled) {
+            squishiness = 1;
+        } else if (mTransitioningToFullShadeProgress > 0.0f) {
+            squishiness = mLockscreenShadeTransitionController.getQsSquishTransitionFraction();
+        } else {
+            squishiness = mNotificationStackScrollLayoutController
+                    .getNotificationSquishinessFraction();
+        }
+        final float qsExpansionFraction = computeExpansionFraction();
+        final float adjustedExpansionFraction = mSplitShadeEnabled
+                ? 1f : computeExpansionFraction();
+        mQs.setQsExpansion(
+                adjustedExpansionFraction,
+                mShadeExpandedFraction,
+                getHeaderTranslation(),
+                squishiness
+        );
+        mMediaHierarchyManager.setQsExpansion(qsExpansionFraction);
+        int qsPanelBottomY = calculateBottomPosition(qsExpansionFraction);
+        mScrimController.setQsPosition(qsExpansionFraction, qsPanelBottomY);
+        setClippingBounds();
+
+        if (mSplitShadeEnabled) {
+            // In split shade we want to pretend that QS are always collapsed so their behaviour and
+            // interactions don't influence notifications as they do in portrait. But we want to set
+            // 0 explicitly in case we're rotating from non-split shade with QS expansion of 1.
+            mNotificationStackScrollLayoutController.setQsExpansionFraction(0);
+        } else {
+            mNotificationStackScrollLayoutController.setQsExpansionFraction(qsExpansionFraction);
+        }
+
+        mDepthController.setQsPanelExpansion(qsExpansionFraction);
+        mStatusBarKeyguardViewManager.setQsExpansion(qsExpansionFraction);
+
+        // TODO (b/265193930): remove dependency on NPVC
+        float shadeExpandedFraction = mBarState == KEYGUARD
+                ? mPanelViewControllerLazy.get().getLockscreenShadeDragProgress()
+                : mShadeExpandedFraction;
+        mShadeHeaderController.setShadeExpandedFraction(shadeExpandedFraction);
+        mShadeHeaderController.setQsExpandedFraction(qsExpansionFraction);
+        mShadeHeaderController.setQsVisible(mVisible);
+    }
+
+    /** */
+    public void updateExpansionEnabledAmbient() {
+        final float scrollRangeToTop = mAmbientState.getTopPadding() - mQuickQsHeaderHeight;
+        mExpansionEnabledAmbient = mSplitShadeEnabled
+                || (mAmbientState.getScrollY() <= scrollRangeToTop);
+        if (mQs != null) {
+            mQs.setHeaderClickable(isExpansionEnabled());
+        }
+    }
+
+    /** Calculate y value of bottom of QS */
+    private int calculateBottomPosition(float qsExpansionFraction) {
+        if (mTransitioningToFullShadeProgress > 0.0f) {
+            return mTransitionToFullShadePosition;
+        } else {
+            int qsBottomYFrom = (int) getHeaderTranslation() + mQs.getQsMinExpansionHeight();
+            int expandedTopMargin = mUseLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight : 0;
+            int qsBottomYTo = mQs.getDesiredHeight() + expandedTopMargin;
+            return (int) MathUtils.lerp(qsBottomYFrom, qsBottomYTo, qsExpansionFraction);
+        }
+    }
+
+    /** Calculate fraction of current QS expansion state */
+    public float computeExpansionFraction() {
+        if (mAnimatingHiddenFromCollapsed) {
+            // When hiding QS from collapsed state, the expansion can sometimes temporarily
+            // be larger than 0 because of the timing, leading to flickers.
+            return 0.0f;
+        }
+        return Math.min(
+                1f, (mExpansionHeight - mMinExpansionHeight) / (mMaxExpansionHeight
+                        - mMinExpansionHeight));
+    }
+
+    void updateMinHeight() {
+        float previousMin = mMinExpansionHeight;
+        if (mBarState == KEYGUARD || mSplitShadeEnabled) {
+            mMinExpansionHeight = 0;
+        } else {
+            mMinExpansionHeight = mQs.getQsMinExpansionHeight();
+        }
+        if (mExpansionHeight == previousMin) {
+            mExpansionHeight = mMinExpansionHeight;
+        }
+    }
+
+    void updateQsFrameTranslation() {
+        // TODO (b/265193930): remove dependency on NPVC
+        mQsFrameTranslateController.translateQsFrame(mQsFrame, mQs,
+                mPanelViewControllerLazy.get().getNavigationBarBottomHeight()
+                        + mAmbientState.getStackTopMargin());
+    }
+
+    /** Called when shade starts expanding. */
+    public void onExpandingStarted(boolean qsFullyExpanded) {
+        mNotificationStackScrollLayoutController.onExpansionStarted();
+        mExpandedWhenExpandingStarted = qsFullyExpanded;
+        mMediaHierarchyManager.setCollapsingShadeFromQS(mExpandedWhenExpandingStarted
+                /* We also start expanding when flinging closed Qs. Let's exclude that */
+                && !mAnimating);
+        if (mExpanded) {
+            onExpansionStarted();
+        }
+        // Since there are QS tiles in the header now, we need to make sure we start listening
+        // immediately so they can be up to date.
+        if (mQs == null) return;
+        mQs.setHeaderListening(true);
+    }
+
+    /** Set animate next notification bounds. */
+    private void setAnimateNextNotificationBounds(long duration, long delay) {
+        mAnimateNextNotificationBounds = true;
+        mNotificationBoundsAnimationDuration = duration;
+        mNotificationBoundsAnimationDelay = delay;
+    }
+
+    /**
+     * Updates scrim bounds, QS clipping, notifications clipping and keyguard status view clipping
+     * as well based on the bounds of the shade and QS state.
+     */
+    private void setClippingBounds() {
+        float qsExpansionFraction = computeExpansionFraction();
+        final int qsPanelBottomY = calculateBottomPosition(qsExpansionFraction);
+        final boolean qsVisible = (qsExpansionFraction > 0 || qsPanelBottomY > 0);
+        checkCorrectScrimVisibility(qsExpansionFraction);
+
+        int top = calculateTopClippingBound(qsPanelBottomY);
+        int bottom = calculateBottomClippingBound(top);
+        int left = calculateLeftClippingBound();
+        int right = calculateRightClippingBound();
+        // top should never be lower than bottom, otherwise it will be invisible.
+        top = Math.min(top, bottom);
+        applyClippingBounds(left, top, right, bottom, qsVisible);
+    }
+
+    /**
+     * Applies clipping to quick settings, notifications layout and
+     * updates bounds of the notifications background (notifications scrim).
+     *
+     * The parameters are bounds of the notifications area rectangle, this function
+     * calculates bounds for the QS clipping based on the notifications bounds.
+     */
+    private void applyClippingBounds(int left, int top, int right, int bottom,
+            boolean qsVisible) {
+        if (!mAnimateNextNotificationBounds || mLastClipBounds.isEmpty()) {
+            if (mClippingAnimator != null) {
+                // update the end position of the animator
+                mClippingAnimationEndBounds.set(left, top, right, bottom);
+            } else {
+                applyClippingImmediately(left, top, right, bottom, qsVisible);
+            }
+        } else {
+            mClippingAnimationEndBounds.set(left, top, right, bottom);
+            final int startLeft = mLastClipBounds.left;
+            final int startTop = mLastClipBounds.top;
+            final int startRight = mLastClipBounds.right;
+            final int startBottom = mLastClipBounds.bottom;
+            if (mClippingAnimator != null) {
+                mClippingAnimator.cancel();
+            }
+            mClippingAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
+            mClippingAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+            mClippingAnimator.setDuration(mNotificationBoundsAnimationDuration);
+            mClippingAnimator.setStartDelay(mNotificationBoundsAnimationDelay);
+            mClippingAnimator.addUpdateListener(animation -> {
+                float fraction = animation.getAnimatedFraction();
+                int animLeft = (int) MathUtils.lerp(startLeft,
+                        mClippingAnimationEndBounds.left, fraction);
+                int animTop = (int) MathUtils.lerp(startTop,
+                        mClippingAnimationEndBounds.top, fraction);
+                int animRight = (int) MathUtils.lerp(startRight,
+                        mClippingAnimationEndBounds.right, fraction);
+                int animBottom = (int) MathUtils.lerp(startBottom,
+                        mClippingAnimationEndBounds.bottom, fraction);
+                applyClippingImmediately(animLeft, animTop, animRight, animBottom,
+                        qsVisible /* qsVisible */);
+            });
+            mClippingAnimator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mClippingAnimator = null;
+                    mIsTranslationResettingAnimator = false;
+                    mIsPulseExpansionResettingAnimator = false;
+                }
+            });
+            mClippingAnimator.start();
+        }
+        mAnimateNextNotificationBounds = false;
+        mNotificationBoundsAnimationDelay = 0;
+    }
+
+    private void applyClippingImmediately(int left, int top, int right, int bottom,
+            boolean qsVisible) {
+        int radius = mScrimCornerRadius;
+        boolean clipStatusView = false;
+        mLastClipBounds.set(left, top, right, bottom);
+        if (mIsFullWidth) {
+            clipStatusView = qsVisible;
+            float screenCornerRadius = mRecordingController.isRecording() ? 0 : mScreenCornerRadius;
+            radius = (int) MathUtils.lerp(screenCornerRadius, mScrimCornerRadius,
+                    Math.min(top / (float) mScrimCornerRadius, 1f));
+        }
+        if (isQsFragmentCreated()) {
+            float qsTranslation = 0;
+            boolean pulseExpanding = mPulseExpansionHandler.isExpanding();
+            if (mTransitioningToFullShadeProgress > 0.0f
+                    || pulseExpanding || (mClippingAnimator != null
+                    && (mIsTranslationResettingAnimator || mIsPulseExpansionResettingAnimator))) {
+                if (pulseExpanding || mIsPulseExpansionResettingAnimator) {
+                    // qsTranslation should only be positive during pulse expansion because it's
+                    // already translating in from the top
+                    qsTranslation = Math.max(0, (top - getHeaderHeight()) / 2.0f);
+                } else if (!mSplitShadeEnabled) {
+                    qsTranslation = (top - getHeaderHeight()) * QS_PARALLAX_AMOUNT;
+                }
+            }
+            mTranslationForFullShadeTransition = qsTranslation;
+            updateQsFrameTranslation();
+            float currentTranslation = mQsFrame.getTranslationY();
+            int clipTop = mEnableClipping
+                    ? (int) (top - currentTranslation - mQsFrame.getTop()) : 0;
+            int clipBottom = mEnableClipping
+                    ? (int) (bottom - currentTranslation - mQsFrame.getTop()) : 0;
+            mVisible = qsVisible;
+            mQs.setQsVisible(qsVisible);
+            mQs.setFancyClipping(
+                    clipTop,
+                    clipBottom,
+                    radius,
+                    qsVisible && !mSplitShadeEnabled);
+
+        }
+
+        // Increase the height of the notifications scrim when not in split shade
+        // (e.g. portrait tablet) so the rounded corners are not visible at the bottom,
+        // in this case they are rendered off-screen
+        final int notificationsScrimBottom = mSplitShadeEnabled ? bottom : bottom + radius;
+        mScrimController.setNotificationsBounds(left, top, right, notificationsScrimBottom);
+
+        if (mApplyClippingImmediatelyListener != null) {
+            mApplyClippingImmediatelyListener.onQsClippingImmediatelyApplied(clipStatusView,
+                    mLastClipBounds, top, isQsFragmentCreated(), mVisible);
+        }
+
+        mScrimController.setScrimCornerRadius(radius);
+
+        // Convert global clipping coordinates to local ones,
+        // relative to NotificationStackScrollLayout
+        int nsslLeft = calculateNsslLeft(left);
+        int nsslRight = calculateNsslRight(right);
+        int nsslTop = getNotificationsClippingTopBounds(top);
+        int nsslBottom = bottom - mNotificationStackScrollLayoutController.getTop();
+        int bottomRadius = mSplitShadeEnabled ? radius : 0;
+        // TODO (b/265193930): remove dependency on NPVC
+        int topRadius = mSplitShadeEnabled
+                && mPanelViewControllerLazy.get().isExpandingFromHeadsUp() ? 0 : radius;
+        mNotificationStackScrollLayoutController.setRoundedClippingBounds(
+                nsslLeft, nsslTop, nsslRight, nsslBottom, topRadius, bottomRadius);
+    }
+
+    void setDisplayInsets(int leftInset, int rightInset) {
+        mDisplayLeftInset = leftInset;
+        mDisplayRightInset = rightInset;
+    }
+
+    private int calculateNsslLeft(int nsslLeftAbsolute) {
+        int left = nsslLeftAbsolute - mNotificationStackScrollLayoutController.getLeft();
+        if (mIsFullWidth) {
+            return left;
+        }
+        return left - mDisplayLeftInset;
+    }
+
+    private int calculateNsslRight(int nsslRightAbsolute) {
+        int right = nsslRightAbsolute - mNotificationStackScrollLayoutController.getLeft();
+        if (mIsFullWidth) {
+            return right;
+        }
+        return right - mDisplayLeftInset;
+    }
+
+    private int getNotificationsClippingTopBounds(int qsTop) {
+        // TODO (b/265193930): remove dependency on NPVC
+        if (mSplitShadeEnabled && mPanelViewControllerLazy.get().isExpandingFromHeadsUp()) {
+            // in split shade nssl has extra top margin so clipping at top 0 is not enough, we need
+            // to set top clipping bound to negative value to allow HUN to go up to the top edge of
+            // the screen without clipping.
+            return -mAmbientState.getStackTopMargin();
+        } else {
+            return qsTop - mNotificationStackScrollLayoutController.getTop();
+        }
+    }
+
+    private void checkCorrectScrimVisibility(float expansionFraction) {
+        // issues with scrims visible on keyguard occur only in split shade
+        if (mSplitShadeEnabled) {
+            // TODO (b/265193930): remove dependency on NPVC
+            boolean keyguardViewsVisible = mBarState == KEYGUARD
+                            && mPanelViewControllerLazy.get().getKeyguardOnlyContentAlpha() == 1;
+            // expansionFraction == 1 means scrims are fully visible as their size/visibility depend
+            // on QS expansion
+            if (expansionFraction == 1 && keyguardViewsVisible) {
+                Log.wtf(TAG,
+                        "Incorrect state, scrim is visible at the same time when clock is visible");
+            }
+        }
+    }
+
+    /** Calculate top padding for notifications */
+    public float calculateNotificationsTopPadding(boolean isShadeExpanding,
+            int keyguardNotificationStaticPadding, float expandedFraction) {
+        boolean keyguardShowing = mBarState == KEYGUARD;
+        if (mSplitShadeEnabled) {
+            return keyguardShowing
+                    ? keyguardNotificationStaticPadding : 0;
+        }
+        if (keyguardShowing && (isExpandImmediate()
+                || isShadeExpanding && getExpandedWhenExpandingStarted())) {
+
+            // Either QS pushes the notifications down when fully expanded, or QS is fully above the
+            // notifications (mostly on tablets). maxNotificationPadding denotes the normal top
+            // padding on Keyguard, maxQsPadding denotes the top padding from the quick settings
+            // panel. We need to take the maximum and linearly interpolate with the panel expansion
+            // for a nice motion.
+            int maxQsPadding = getMaxExpansionHeight();
+            int max = keyguardShowing ? Math.max(
+                    keyguardNotificationStaticPadding, maxQsPadding) : maxQsPadding;
+            return (int) MathUtils.lerp((float) getMinExpansionHeight(),
+                    (float) max, expandedFraction);
+        } else if (isSizeChangeAnimationRunning()) {
+            return Math.max((int) mSizeChangeAnimator.getAnimatedValue(),
+                    keyguardNotificationStaticPadding);
+        } else if (keyguardShowing) {
+            // We can only do the smoother transition on Keyguard when we also are not collapsing
+            // from a scrolled quick settings.
+            return MathUtils.lerp((float) keyguardNotificationStaticPadding,
+                    (float) (getMaxExpansionHeight()), computeExpansionFraction());
+        } else {
+            return mQsFrameTranslateController.getNotificationsTopPadding(
+                    mExpansionHeight, mNotificationStackScrollLayoutController);
+        }
+    }
+
+    /** Calculate height of QS panel */
+    public int calculatePanelHeightExpanded(int stackScrollerPadding) {
+        float
+                notificationHeight =
+                mNotificationStackScrollLayoutController.getHeight()
+                        - mNotificationStackScrollLayoutController.getEmptyBottomMargin()
+                        - mNotificationStackScrollLayoutController.getTopPadding();
+
+        // When only empty shade view is visible in QS collapsed state, simulate that we would have
+        // it in expanded QS state as well so we don't run into troubles when fading the view in/out
+        // and expanding/collapsing the whole panel from/to quick settings.
+        if (mNotificationStackScrollLayoutController.getNotGoneChildCount() == 0
+                && mNotificationStackScrollLayoutController.isShowingEmptyShadeView()) {
+            notificationHeight = mNotificationStackScrollLayoutController.getEmptyShadeViewHeight();
+        }
+        int maxQsHeight = mMaxExpansionHeight;
+
+        // If an animation is changing the size of the QS panel, take the animated value.
+        if (mSizeChangeAnimator != null) {
+            maxQsHeight = (int) mSizeChangeAnimator.getAnimatedValue();
+        }
+        float totalHeight = Math.max(maxQsHeight, mBarState == KEYGUARD ? stackScrollerPadding : 0)
+                + notificationHeight
+                + mNotificationStackScrollLayoutController.getTopPaddingOverflow();
+        if (totalHeight > mNotificationStackScrollLayoutController.getHeight()) {
+            float
+                    fullyCollapsedHeight =
+                    maxQsHeight + mNotificationStackScrollLayoutController.getLayoutMinHeight();
+            totalHeight = Math.max(fullyCollapsedHeight,
+                    mNotificationStackScrollLayoutController.getHeight());
+        }
+        return (int) totalHeight;
+    }
+
+    private float getEdgePosition() {
+        // TODO: replace StackY with unified calculation
+        return Math.max(mQuickQsHeaderHeight * mAmbientState.getExpansionFraction(),
+                mAmbientState.getStackY()
+                        // need to adjust for extra margin introduced by large screen shade header
+                        + mAmbientState.getStackTopMargin() * mAmbientState.getExpansionFraction()
+                        - mAmbientState.getScrollY());
+    }
+
+    private int calculateTopClippingBound(int qsPanelBottomY) {
+        int top;
+        if (mSplitShadeEnabled) {
+            top = Math.min(qsPanelBottomY, mLargeScreenShadeHeaderHeight);
+        } else {
+            if (mTransitioningToFullShadeProgress > 0.0f) {
+                // If we're transitioning, let's use the actual value. The else case
+                // can be wrong during transitions when waiting for the keyguard to unlock
+                top = mTransitionToFullShadePosition;
+            } else {
+                final float notificationTop = getEdgePosition();
+                if (mBarState == KEYGUARD) {
+                    if (mKeyguardBypassController.getBypassEnabled()) {
+                        // When bypassing on the keyguard, let's use the panel bottom.
+                        // this should go away once we unify the stackY position and don't have
+                        // to do this min anymore below.
+                        top = qsPanelBottomY;
+                    } else {
+                        top = (int) Math.min(qsPanelBottomY, notificationTop);
+                    }
+                } else {
+                    top = (int) notificationTop;
+                }
+            }
+            // TODO (b/265193930): remove dependency on NPVC
+            top += mPanelViewControllerLazy.get().getOverStretchAmount();
+            // Correction for instant expansion caused by HUN pull down/
+            float minFraction = mPanelViewControllerLazy.get().getMinFraction();
+            if (minFraction > 0f && minFraction < 1f) {
+                float realFraction = (mShadeExpandedFraction
+                        - minFraction) / (1f - minFraction);
+                top *= MathUtils.saturate(realFraction / minFraction);
+            }
+        }
+        return top;
+    }
+
+    private int calculateBottomClippingBound(int top) {
+        if (mSplitShadeEnabled) {
+            return top + mNotificationStackScrollLayoutController.getHeight()
+                    + mSplitShadeNotificationsScrimMarginBottom;
+        } else {
+            return mPanelView.getBottom();
+        }
+    }
+
+    private int calculateLeftClippingBound() {
+        if (mIsFullWidth) {
+            // left bounds can ignore insets, it should always reach the edge of the screen
+            return 0;
+        } else {
+            return mNotificationStackScrollLayoutController.getLeft()
+                    + mDisplayLeftInset;
+        }
+    }
+
+    private int calculateRightClippingBound() {
+        if (mIsFullWidth) {
+            return mPanelView.getRight()
+                    + mDisplayRightInset;
+        } else {
+            return mNotificationStackScrollLayoutController.getRight()
+                    + mDisplayLeftInset;
+        }
+    }
+
+    private void trackMovement(MotionEvent event) {
+        if (mQsVelocityTracker != null) mQsVelocityTracker.addMovement(event);
+    }
+
+    private void initVelocityTracker() {
+        if (mQsVelocityTracker != null) {
+            mQsVelocityTracker.recycle();
+        }
+        mQsVelocityTracker = VelocityTracker.obtain();
+    }
+
+    private float getCurrentVelocity() {
+        if (mQsVelocityTracker == null) {
+            return 0;
+        }
+        mQsVelocityTracker.computeCurrentVelocity(1000);
+        return mQsVelocityTracker.getYVelocity();
+    }
+
+    boolean updateAndGetTouchAboveFalsingThreshold() {
+        mTouchAboveFalsingThreshold = mFullyExpanded;
+        return mTouchAboveFalsingThreshold;
+    }
+
+    @VisibleForTesting
+    void onHeightChanged() {
+        mMaxExpansionHeight = isQsFragmentCreated() ? mQs.getDesiredHeight() : 0;
+        if (mExpanded && mFullyExpanded) {
+            mExpansionHeight = mMaxExpansionHeight;
+            if (mExpansionHeightSetToMaxListener != null) {
+                mExpansionHeightSetToMaxListener.onExpansionHeightSetToMax(true);
+            }
+        }
+        if (mAccessibilityManager.isEnabled()) {
+            // TODO (b/265193930): remove dependency on NPVC
+            mPanelView.setAccessibilityPaneTitle(
+                    mPanelViewControllerLazy.get().determineAccessibilityPaneTitle());
+        }
+        mNotificationStackScrollLayoutController.setMaxTopPadding(mMaxExpansionHeight);
+    }
+
+    private void collapseOrExpandQs() {
+        if (mSplitShadeEnabled) {
+            return; // QS is always expanded in split shade
+        }
+        onExpansionStarted();
+        if (getExpanded()) {
+            flingQs(0, FLING_COLLAPSE, null, true);
+        } else if (isExpansionEnabled()) {
+            mLockscreenGestureLogger.write(MetricsProto.MetricsEvent.ACTION_SHADE_QS_TAP, 0, 0);
+            flingQs(0, FLING_EXPAND, null, true);
+        }
+    }
+
+    private void onScroll(int scrollY) {
+        mShadeHeaderController.setQsScrollY(scrollY);
+        if (scrollY > 0 && !mFullyExpanded) {
+            // TODO (b/265193930): remove dependency on NPVC
+            // If we are scrolling QS, we should be fully expanded.
+            mPanelViewControllerLazy.get().expandWithQs();
+        }
+    }
+
+    @VisibleForTesting
+    boolean isTrackingBlocked() {
+        return mConflictingExpansionGesture && getExpanded();
+    }
+
+    boolean isExpansionAnimating() {
+        return mExpansionAnimator != null;
+    }
+
+    @VisibleForTesting
+    boolean isConflictingExpansionGesture() {
+        return mConflictingExpansionGesture;
+    }
+
+    /** handles touches in Qs panel area */
+    public boolean handleTouch(MotionEvent event, boolean isFullyCollapsed,
+            boolean isShadeOrQsHeightAnimationRunning) {
+        if (isSplitShadeAndTouchXOutsideQs(event.getX())) {
+            return false;
+        }
+        final int action = event.getActionMasked();
+        boolean collapsedQs = !getExpanded() && !mSplitShadeEnabled;
+        boolean expandedShadeCollapsedQs = mShadeExpandedFraction == 1f
+                && mBarState != KEYGUARD && collapsedQs && isExpansionEnabled();
+        if (action == MotionEvent.ACTION_DOWN && expandedShadeCollapsedQs) {
+            // Down in the empty area while fully expanded - go to QS.
+            mShadeLog.logMotionEvent(event, "handleQsTouch: down action, QS tracking enabled");
+            mTracking = true;
+            traceQsJank(true, false);
+            mConflictingExpansionGesture = true;
+            onExpansionStarted();
+            mInitialHeightOnTouch = mExpansionHeight;
+            mInitialTouchY = event.getY();
+            mInitialTouchX = event.getX();
+        }
+        if (!isFullyCollapsed && !isShadeOrQsHeightAnimationRunning) {
+            handleDown(event);
+        }
+        // defer touches on QQS to shade while shade is collapsing. Added margin for error
+        // as sometimes the qsExpansionFraction can be a tiny value instead of 0 when in QQS.
+        if (!mSplitShadeEnabled && !mLastShadeFlingWasExpanding
+                && computeExpansionFraction() <= 0.01 && mShadeExpandedFraction < 1.0) {
+            mShadeLog.logMotionEvent(event,
+                    "handleQsTouch: shade touched while shade collapsing, QS tracking disabled");
+            mTracking = false;
+        }
+        if (!isExpandImmediate() && mTracking) {
+            onTouch(event);
+            if (!mConflictingExpansionGesture && !mSplitShadeEnabled) {
+                mShadeLog.logMotionEvent(event,
+                        "handleQsTouch: not immediate expand or conflicting gesture");
+                return true;
+            }
+        }
+        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
+            mConflictingExpansionGesture = false;
+        }
+        if (action == MotionEvent.ACTION_DOWN && isFullyCollapsed && isExpansionEnabled()) {
+            mTwoFingerExpandPossible = true;
+        }
+        if (mTwoFingerExpandPossible && isOpenQsEvent(event)
+                && event.getY(event.getActionIndex())
+                < mStatusBarMinHeight) {
+            mMetricsLogger.count(COUNTER_PANEL_OPEN_QS, 1);
+            setExpandImmediate(true);
+            mNotificationStackScrollLayoutController.setShouldShowShelfOnly(!mSplitShadeEnabled);
+            if (mExpansionHeightSetToMaxListener != null) {
+                mExpansionHeightSetToMaxListener.onExpansionHeightSetToMax(false);
+            }
+
+            // Normally, we start listening when the panel is expanded, but here we need to start
+            // earlier so the state is already up to date when dragging down.
+            setListening(true);
+        }
+        return false;
+    }
+
+    private void handleDown(MotionEvent event) {
+        if (event.getActionMasked() == MotionEvent.ACTION_DOWN
+                && shouldQuickSettingsIntercept(event.getX(), event.getY(), -1)) {
+            mFalsingCollector.onQsDown();
+            mShadeLog.logMotionEvent(event, "handleQsDown: down action, QS tracking enabled");
+            mTracking = true;
+            onExpansionStarted();
+            mInitialHeightOnTouch = mExpansionHeight;
+            mInitialTouchY = event.getY();
+            mInitialTouchX = event.getX();
+            // TODO (b/265193930): remove dependency on NPVC
+            // If we interrupt an expansion gesture here, make sure to update the state correctly.
+            mPanelViewControllerLazy.get().notifyExpandingFinished();
+        }
+    }
+
+    private void onTouch(MotionEvent event) {
+        int pointerIndex = event.findPointerIndex(mTrackingPointer);
+        if (pointerIndex < 0) {
+            pointerIndex = 0;
+            mTrackingPointer = event.getPointerId(pointerIndex);
+        }
+        final float y = event.getY(pointerIndex);
+        final float x = event.getX(pointerIndex);
+        final float h = y - mInitialTouchY;
+
+        switch (event.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN:
+                mShadeLog.logMotionEvent(event, "onQsTouch: down action, QS tracking enabled");
+                mTracking = true;
+                traceQsJank(true, false);
+                mInitialTouchY = y;
+                mInitialTouchX = x;
+                onExpansionStarted();
+                mInitialHeightOnTouch = mExpansionHeight;
+                initVelocityTracker();
+                trackMovement(event);
+                break;
+
+            case MotionEvent.ACTION_POINTER_UP:
+                final int upPointer = event.getPointerId(event.getActionIndex());
+                if (mTrackingPointer == upPointer) {
+                    // gesture is ongoing, find a new pointer to track
+                    final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
+                    final float newY = event.getY(newIndex);
+                    final float newX = event.getX(newIndex);
+                    mTrackingPointer = event.getPointerId(newIndex);
+                    mInitialHeightOnTouch = mExpansionHeight;
+                    mInitialTouchY = newY;
+                    mInitialTouchX = newX;
+                }
+                break;
+
+            case MotionEvent.ACTION_MOVE:
+                mShadeLog.logMotionEvent(event, "onQsTouch: move action, setting QS expansion");
+                setExpansionHeight(h + mInitialHeightOnTouch);
+                // TODO (b/265193930): remove dependency on NPVC
+                if (h >= mPanelViewControllerLazy.get().getFalsingThreshold()) {
+                    mTouchAboveFalsingThreshold = true;
+                }
+                trackMovement(event);
+                break;
+
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                mShadeLog.logMotionEvent(event,
+                        "onQsTouch: up/cancel action, QS tracking disabled");
+                mTracking = false;
+                mTrackingPointer = -1;
+                trackMovement(event);
+                float fraction = computeExpansionFraction();
+                if (fraction != 0f || y >= mInitialTouchY) {
+                    flingQsWithCurrentVelocity(y,
+                            event.getActionMasked() == MotionEvent.ACTION_CANCEL);
+                } else {
+                    traceQsJank(false,
+                            event.getActionMasked() == MotionEvent.ACTION_CANCEL);
+                }
+                if (mQsVelocityTracker != null) {
+                    mQsVelocityTracker.recycle();
+                    mQsVelocityTracker = null;
+                }
+                break;
+        }
+    }
+
+    /** intercepts touches on Qs panel area. */
+    public boolean onIntercept(MotionEvent event) {
+        int pointerIndex = event.findPointerIndex(mTrackingPointer);
+        if (pointerIndex < 0) {
+            pointerIndex = 0;
+            mTrackingPointer = event.getPointerId(pointerIndex);
+        }
+        final float x = event.getX(pointerIndex);
+        final float y = event.getY(pointerIndex);
+
+        switch (event.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN:
+                mInitialTouchY = y;
+                mInitialTouchX = x;
+                initVelocityTracker();
+                trackMovement(event);
+                float qsExpansionFraction = computeExpansionFraction();
+                // Intercept the touch if QS is between fully collapsed and fully expanded state
+                if (!mSplitShadeEnabled
+                        && qsExpansionFraction > 0.0 && qsExpansionFraction < 1.0) {
+                    mShadeLog.logMotionEvent(event,
+                            "onQsIntercept: down action, QS partially expanded/collapsed");
+                    return true;
+                }
+                // TODO (b/265193930): remove dependency on NPVC
+                if (mPanelViewControllerLazy.get().getKeyguardShowing()
+                        && shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, 0)) {
+                    // Dragging down on the lockscreen statusbar should prohibit other interactions
+                    // immediately, otherwise we'll wait on the touchslop. This is to allow
+                    // dragging down to expanded quick settings directly on the lockscreen.
+                    mPanelView.getParent().requestDisallowInterceptTouchEvent(true);
+                }
+                if (mExpansionAnimator != null) {
+                    mInitialHeightOnTouch = mExpansionHeight;
+                    mShadeLog.logMotionEvent(event,
+                            "onQsIntercept: down action, QS tracking enabled");
+                    mTracking = true;
+                    traceQsJank(true, false);
+                    mNotificationStackScrollLayoutController.cancelLongPress();
+                }
+                break;
+            case MotionEvent.ACTION_POINTER_UP:
+                final int upPointer = event.getPointerId(event.getActionIndex());
+                if (mTrackingPointer == upPointer) {
+                    // gesture is ongoing, find a new pointer to track
+                    final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
+                    mTrackingPointer = event.getPointerId(newIndex);
+                    mInitialTouchX = event.getX(newIndex);
+                    mInitialTouchY = event.getY(newIndex);
+                }
+                break;
+
+            case MotionEvent.ACTION_MOVE:
+                final float h = y - mInitialTouchY;
+                trackMovement(event);
+                if (mTracking) {
+
+                    // Already tracking because onOverscrolled was called. We need to update here
+                    // so we don't stop for a frame until the next touch event gets handled in
+                    // onTouchEvent.
+                    setExpansionHeight(h + mInitialHeightOnTouch);
+                    trackMovement(event);
+                    return true;
+                } else {
+                    mShadeLog.logMotionEvent(event,
+                            "onQsIntercept: move ignored because qs tracking disabled");
+                }
+                // TODO (b/265193930): remove dependency on NPVC
+                float touchSlop = event.getClassification()
+                        == MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE
+                        ? mTouchSlop * mSlopMultiplier
+                        : mTouchSlop;
+                if ((h > touchSlop || (h < -touchSlop && getExpanded()))
+                        && Math.abs(h) > Math.abs(x - mInitialTouchX)
+                        && shouldQuickSettingsIntercept(
+                        mInitialTouchX, mInitialTouchY, h)) {
+                    mPanelView.getParent().requestDisallowInterceptTouchEvent(true);
+                    mShadeLog.onQsInterceptMoveQsTrackingEnabled(h);
+                    mTracking = true;
+                    traceQsJank(true, false);
+                    onExpansionStarted();
+                    mPanelViewControllerLazy.get().notifyExpandingFinished();
+                    mInitialHeightOnTouch = mExpansionHeight;
+                    mInitialTouchY = y;
+                    mInitialTouchX = x;
+                    mNotificationStackScrollLayoutController.cancelLongPress();
+                    return true;
+                } else {
+                    mShadeLog.logQsTrackingNotStarted(mInitialTouchY, y, h, touchSlop,
+                            getExpanded(), mPanelViewControllerLazy.get().getKeyguardShowing(),
+                            isExpansionEnabled());
+                }
+                break;
+
+            case MotionEvent.ACTION_CANCEL:
+            case MotionEvent.ACTION_UP:
+                trackMovement(event);
+                mShadeLog.logMotionEvent(event, "onQsIntercept: up action, QS tracking disabled");
+                mTracking = false;
+                break;
+        }
+        return false;
+    }
+
+    @VisibleForTesting
+    void onPanelExpansionChanged(ShadeExpansionChangeEvent event) {
+        mShadeExpandedFraction = event.getFraction();
+    }
+
+    /**
+     * Animate QS closing by flinging it.
+     * If QS is expanded, it will collapse into QQS and stop.
+     * If in split shade, it will collapse the whole shade.
+     *
+     * @param animateAway Do not stop when QS becomes QQS. Fling until QS isn't visible anymore.
+     */
+    public void animateCloseQs(boolean animateAway) {
+        if (mExpansionAnimator != null) {
+            if (!mAnimatorExpand) {
+                return;
+            }
+            float height = mExpansionHeight;
+            mExpansionAnimator.cancel();
+            setExpansionHeight(height);
+        }
+        flingQs(0 /* vel */, animateAway ? FLING_HIDE : FLING_COLLAPSE);
+    }
+
+    private void cancelExpansionAnimation() {
+        if (mExpansionAnimator != null) {
+            mExpansionAnimator.cancel();
+        }
+    }
+
+    /** @see #flingQs(float, int, Runnable, boolean) */
+    public void flingQs(float vel, int type) {
+        flingQs(vel, type, null /* onFinishRunnable */, false /* isClick */);
+    }
+
+    /**
+     * Animates QS or QQS as if the user had swiped up or down.
+     *
+     * @param vel              Finger velocity or 0 when not initiated by touch events.
+     * @param type             Either FLING_EXPAND, FLING_COLLAPSE or FLING_HIDE.
+     * @param onFinishRunnable Runnable to be executed at the end of animation.
+     * @param isClick          If originated by click (different interpolator and duration.)
+     */
+    private void flingQs(float vel, int type, final Runnable onFinishRunnable,
+            boolean isClick) {
+        mShadeLog.flingQs(type, isClick);
+        float target;
+        switch (type) {
+            case FLING_EXPAND:
+                target = getMaxExpansionHeight();
+                break;
+            case FLING_COLLAPSE:
+                if (mSplitShadeEnabled) { // TODO:(b/269742565) remove below log
+                    Log.wtfStack(TAG, "FLING_COLLAPSE called in split shade");
+                }
+                target = getMinExpansionHeight();
+                break;
+            case FLING_HIDE:
+            default:
+                if (isQsFragmentCreated()) {
+                    mQs.closeDetail();
+                }
+                target = 0;
+        }
+        if (target == mExpansionHeight) {
+            if (onFinishRunnable != null) {
+                onFinishRunnable.run();
+            }
+            traceQsJank(false, type != FLING_EXPAND);
+            return;
+        }
+
+        // If we move in the opposite direction, reset velocity and use a different duration.
+        boolean oppositeDirection = false;
+        boolean expanding = type == FLING_EXPAND;
+        if (vel > 0 && !expanding || vel < 0 && expanding) {
+            vel = 0;
+            oppositeDirection = true;
+        }
+        ValueAnimator animator = ValueAnimator.ofFloat(
+                mExpansionHeight, target);
+        if (isClick) {
+            animator.setInterpolator(Interpolators.TOUCH_RESPONSE);
+            animator.setDuration(368);
+        } else {
+            if (mFlingQsWithoutClickListener != null) {
+                mFlingQsWithoutClickListener.onFlingQsWithoutClick(animator, mExpansionHeight,
+                        target, vel);
+            }
+        }
+        if (oppositeDirection) {
+            animator.setDuration(350);
+        }
+        animator.addUpdateListener(
+                animation -> setExpansionHeight((Float) animation.getAnimatedValue()));
+        animator.addListener(new AnimatorListenerAdapter() {
+            private boolean mIsCanceled;
+
+            @Override
+            public void onAnimationStart(Animator animation) {
+                mPanelViewControllerLazy.get().notifyExpandingStarted();
+            }
+
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                mIsCanceled = true;
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mAnimatingHiddenFromCollapsed = false;
+                mAnimating = false;
+                mPanelViewControllerLazy.get().notifyExpandingFinished();
+                mNotificationStackScrollLayoutController.resetCheckSnoozeLeavebehind();
+                mExpansionAnimator = null;
+                if (onFinishRunnable != null) {
+                    onFinishRunnable.run();
+                }
+                traceQsJank(false, mIsCanceled);
+            }
+        });
+        // Let's note that we're animating QS. Moving the animator here will cancel it immediately,
+        // so we need a separate flag.
+        mAnimating = true;
+        animator.start();
+        mExpansionAnimator = animator;
+        mAnimatorExpand = expanding;
+        mAnimatingHiddenFromCollapsed =
+                computeExpansionFraction() == 0.0f && target == 0;
+    }
+
+    private void flingQsWithCurrentVelocity(float y, boolean isCancelMotionEvent) {
+        float vel = getCurrentVelocity();
+        // TODO (b/265193930): remove dependency on NPVC
+        boolean expandsQs = mPanelViewControllerLazy.get().flingExpandsQs(vel);
+        if (expandsQs) {
+            if (mFalsingManager.isUnlockingDisabled() || isQsFalseTouch()) {
+                expandsQs = false;
+            } else {
+                logQsSwipeDown(y);
+            }
+        } else if (vel < 0) {
+            mFalsingManager.isFalseTouch(QS_COLLAPSE);
+        }
+
+        int flingType;
+        if (expandsQs && !isCancelMotionEvent) {
+            flingType = FLING_EXPAND;
+        } else if (mSplitShadeEnabled) {
+            flingType = FLING_HIDE;
+        } else {
+            flingType = FLING_COLLAPSE;
+        }
+        flingQs(vel, flingType);
+    }
+
+    private void logQsSwipeDown(float y) {
+        float vel = getCurrentVelocity();
+        final int gesture = mBarState == KEYGUARD ? MetricsProto.MetricsEvent.ACTION_LS_QS
+                : MetricsProto.MetricsEvent.ACTION_SHADE_QS_PULL;
+        // TODO (b/265193930): remove dependency on NPVC
+        float displayDensity = mPanelViewControllerLazy.get().getDisplayDensity();
+        mLockscreenGestureLogger.write(gesture,
+                (int) ((y - getInitialTouchY()) / displayDensity), (int) (vel / displayDensity));
+    }
+
+    /** */
+    public FragmentHostManager.FragmentListener getQsFragmentListener() {
+        return new QsFragmentListener();
+    }
+
+    /** */
+    public final class QsFragmentListener implements FragmentHostManager.FragmentListener {
+        /** */
+        @Override
+        public void onFragmentViewCreated(String tag, Fragment fragment) {
+            mQs = (QS) fragment;
+            mQs.setPanelView(mQsHeightListener);
+            mQs.setCollapseExpandAction(mQsCollapseExpandAction);
+            mQs.setHeaderClickable(isExpansionEnabled());
+            mQs.setOverscrolling(mStackScrollerOverscrolling);
+            mQs.setInSplitShade(mSplitShadeEnabled);
+            mQs.setIsNotificationPanelFullWidth(mIsFullWidth);
+
+            // recompute internal state when qspanel height changes
+            mQs.getView().addOnLayoutChangeListener(
+                    (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
+                        final int height = bottom - top;
+                        final int oldHeight = oldBottom - oldTop;
+                        if (height != oldHeight) {
+                            onHeightChanged();
+                        }
+                    });
+            mQs.setCollapsedMediaVisibilityChangedListener((visible) -> {
+                if (mQs.getHeader().isShown()) {
+                    setAnimateNextNotificationBounds(
+                            StackStateAnimator.ANIMATION_DURATION_STANDARD, 0);
+                    mNotificationStackScrollLayoutController.animateNextTopPaddingChange();
+                }
+            });
+            mLockscreenShadeTransitionController.setQS(mQs);
+            mShadeTransitionController.setQs(mQs);
+            mNotificationStackScrollLayoutController.setQsHeader((ViewGroup) mQs.getHeader());
+            mQs.setScrollListener(mQsScrollListener);
+            updateExpansion();
+        }
+
+        /** */
+        @Override
+        public void onFragmentViewDestroyed(String tag, Fragment fragment) {
+            // Manual handling of fragment lifecycle is only required because this bridges
+            // non-fragment and fragment code. Once we are using a fragment for the notification
+            // panel, mQs will not need to be null cause it will be tied to the same lifecycle.
+            if (fragment == mQs) {
+                mQs = null;
+            }
+        }
+    }
+
+    private final class LockscreenShadeTransitionCallback
+            implements LockscreenShadeTransitionController.Callback {
+        /** Called when pulse expansion has finished and this is going to the full shade. */
+        @Override
+        public void onPulseExpansionFinished() {
+            setAnimateNextNotificationBounds(
+                    StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE, 0);
+            mIsPulseExpansionResettingAnimator = true;
+        }
+
+        @Override
+        public void setTransitionToFullShadeAmount(float pxAmount, boolean animate, long delay) {
+            if (animate && mIsFullWidth) {
+                setAnimateNextNotificationBounds(
+                        StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE, delay);
+                mIsTranslationResettingAnimator = mTranslationForFullShadeTransition > 0.0f;
+            }
+            float endPosition = 0;
+            if (pxAmount > 0.0f) {
+                if (mSplitShadeEnabled) {
+                    float qsHeight = MathUtils.lerp(getMinExpansionHeight(),
+                            getMaxExpansionHeight(),
+                            mLockscreenShadeTransitionController.getQSDragProgress());
+                    setExpansionHeight(qsHeight);
+                }
+                if (mNotificationStackScrollLayoutController.getVisibleNotificationCount() == 0
+                        && !mMediaDataManager.hasActiveMediaOrRecommendation()) {
+                    // No notifications are visible, let's animate to the height of qs instead
+                    if (isQsFragmentCreated()) {
+                        // Let's interpolate to the header height instead of the top padding,
+                        // because the toppadding is way too low because of the large clock.
+                        // we still want to take into account the edgePosition though as that nicely
+                        // overshoots in the stackscroller
+                        endPosition = getEdgePosition()
+                                - mNotificationStackScrollLayoutController.getTopPadding()
+                                + getHeaderHeight();
+                    }
+                } else {
+                    // Interpolating to the new bottom edge position!
+                    endPosition = getEdgePosition() + mNotificationStackScrollLayoutController
+                            .getFullShadeTransitionInset();
+                    if (mBarState == KEYGUARD) {
+                        endPosition -= mLockscreenNotificationPadding;
+                    }
+                }
+            }
+
+            // Calculate the overshoot amount such that we're reaching the target after our desired
+            // distance, but only reach it fully once we drag a full shade length.
+            mTransitioningToFullShadeProgress = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(
+                    MathUtils.saturate(pxAmount / mDistanceForFullShadeTransition));
+
+            int position = (int) MathUtils.lerp((float) 0, endPosition,
+                    mTransitioningToFullShadeProgress);
+            if (mTransitioningToFullShadeProgress > 0.0f) {
+                // we want at least 1 pixel otherwise the panel won't be clipped
+                position = Math.max(1, position);
+            }
+            mTransitionToFullShadePosition = position;
+            updateExpansion();
+        }
+    }
+
+    private final class NsslOverscrollTopChangedListener implements
+            NotificationStackScrollLayout.OnOverscrollTopChangedListener {
+        @Override
+        public void onOverscrollTopChanged(float amount, boolean isRubberbanded) {
+            // When in split shade, overscroll shouldn't carry through to QS
+            if (mSplitShadeEnabled) {
+                return;
+            }
+            cancelExpansionAnimation();
+            if (!isExpansionEnabled()) {
+                amount = 0f;
+            }
+            float rounded = amount >= 1f ? amount : 0f;
+            setOverScrolling(rounded != 0f && isRubberbanded);
+            mExpansionFromOverscroll = rounded != 0f;
+            mLastOverscroll = rounded;
+            updateQsState();
+            setExpansionHeight(getMinExpansionHeight() + rounded);
+        }
+
+        @Override
+        public void flingTopOverscroll(float velocity, boolean open) {
+            // in split shade mode we want to expand/collapse QS only when touch happens within QS
+            if (isSplitShadeAndTouchXOutsideQs(mInitialTouchX)) {
+                return;
+            }
+            mLastOverscroll = 0f;
+            mExpansionFromOverscroll = false;
+            if (open) {
+                // During overscrolling, qsExpansion doesn't actually change that the qs is
+                // becoming expanded. Any layout could therefore reset the position again. Let's
+                // make sure we can expand
+                setOverScrolling(false);
+            }
+            setExpansionHeight(getExpansionHeight());
+            boolean canExpand = isExpansionEnabled();
+            flingQs(!canExpand && open ? 0f : velocity,
+                    open && canExpand ? FLING_EXPAND : FLING_COLLAPSE, () -> {
+                        setOverScrolling(false);
+                        updateQsState();
+                    }, false);
+        }
+    }
+
+    void beginJankMonitoring(boolean isFullyCollapsed) {
+        if (mInteractionJankMonitor == null) {
+            return;
+        }
+        // TODO (b/265193930): remove dependency on NPVC
+        InteractionJankMonitor.Configuration.Builder builder =
+                InteractionJankMonitor.Configuration.Builder.withView(
+                        InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE,
+                        mPanelView).setTag(isFullyCollapsed ? "Expand" : "Collapse");
+        mInteractionJankMonitor.begin(builder);
+    }
+
+    void endJankMonitoring() {
+        if (mInteractionJankMonitor == null) {
+            return;
+        }
+        InteractionJankMonitor.getInstance().end(
+                InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
+    }
+
+    void cancelJankMonitoring() {
+        if (mInteractionJankMonitor == null) {
+            return;
+        }
+        InteractionJankMonitor.getInstance().cancel(
+                InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
+    }
+
+    void traceQsJank(boolean startTracing, boolean wasCancelled) {
+        if (mInteractionJankMonitor == null) {
+            return;
+        }
+        if (startTracing) {
+            mInteractionJankMonitor.begin(mPanelView, CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE);
+        } else {
+            if (wasCancelled) {
+                mInteractionJankMonitor.cancel(CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE);
+            } else {
+                mInteractionJankMonitor.end(CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE);
+            }
+        }
+    }
+
+    interface ExpansionHeightSetToMaxListener {
+        void onExpansionHeightSetToMax(boolean requestPaddingUpdate);
+    }
+
+    interface ExpansionHeightListener {
+        void onQsSetExpansionHeightCalled(boolean qsFullyExpanded);
+    }
+
+    interface QsStateUpdateListener {
+        void onQsStateUpdated(boolean qsExpanded, boolean isStackScrollerOverscrolling);
+    }
+
+    interface ApplyClippingImmediatelyListener {
+        void onQsClippingImmediatelyApplied(boolean clipStatusView, Rect lastQsClipBounds,
+                int top, boolean qsFragmentCreated, boolean qsVisible);
+    }
+
+    interface FlingQsWithoutClickListener {
+        void onFlingQsWithoutClick(ValueAnimator animator, float qsExpansionHeight,
+                float target, float vel);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
index 026673a..c136993 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
@@ -270,8 +270,6 @@
         // Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
         mNotificationPanelViewController.collapsePanel(false, false, 1.0f);
 
-        mNotificationPanelViewController.closeQs();
-
         mExpandedVisible = false;
         notifyVisibilityChanged(false);
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
new file mode 100644
index 0000000..37773e9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
@@ -0,0 +1,533 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shade
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.annotation.IdRes
+import android.app.StatusBarManager
+import android.content.res.Configuration
+import android.os.Bundle
+import android.os.Trace
+import android.os.Trace.TRACE_TAG_APP
+import android.util.Pair
+import android.view.DisplayCutout
+import android.view.View
+import android.view.WindowInsets
+import android.widget.TextView
+import androidx.annotation.VisibleForTesting
+import androidx.constraintlayout.motion.widget.MotionLayout
+import com.android.settingslib.Utils
+import com.android.systemui.Dumpable
+import com.android.systemui.R
+import com.android.systemui.animation.Interpolators
+import com.android.systemui.animation.ShadeInterpolation
+import com.android.systemui.battery.BatteryMeterView
+import com.android.systemui.battery.BatteryMeterViewController
+import com.android.systemui.demomode.DemoMode
+import com.android.systemui.demomode.DemoModeController
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.qs.ChipVisibilityListener
+import com.android.systemui.qs.HeaderPrivacyIconsController
+import com.android.systemui.qs.carrier.QSCarrierGroup
+import com.android.systemui.qs.carrier.QSCarrierGroupController
+import com.android.systemui.shade.ShadeHeaderController.Companion.HEADER_TRANSITION_ID
+import com.android.systemui.shade.ShadeHeaderController.Companion.LARGE_SCREEN_HEADER_CONSTRAINT
+import com.android.systemui.shade.ShadeHeaderController.Companion.LARGE_SCREEN_HEADER_TRANSITION_ID
+import com.android.systemui.shade.ShadeHeaderController.Companion.QQS_HEADER_CONSTRAINT
+import com.android.systemui.shade.ShadeHeaderController.Companion.QS_HEADER_CONSTRAINT
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
+import com.android.systemui.statusbar.phone.StatusBarIconController
+import com.android.systemui.statusbar.phone.StatusBarLocation
+import com.android.systemui.statusbar.phone.StatusIconContainer
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
+import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.SHADE_HEADER
+import com.android.systemui.statusbar.policy.Clock
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.VariableDateView
+import com.android.systemui.statusbar.policy.VariableDateViewController
+import com.android.systemui.util.ViewController
+import java.io.PrintWriter
+import javax.inject.Inject
+import javax.inject.Named
+
+/**
+ * Controller for QS header.
+ *
+ * [header] is a [MotionLayout] that has two transitions:
+ * * [HEADER_TRANSITION_ID]: [QQS_HEADER_CONSTRAINT] <-> [QS_HEADER_CONSTRAINT] for portrait
+ * handheld device configuration.
+ * * [LARGE_SCREEN_HEADER_TRANSITION_ID]: [LARGE_SCREEN_HEADER_CONSTRAINT] for all other
+ * configurations
+ */
+@CentralSurfacesScope
+class ShadeHeaderController
+@Inject
+constructor(
+    @Named(SHADE_HEADER) private val header: MotionLayout,
+    private val statusBarIconController: StatusBarIconController,
+    private val tintedIconManagerFactory: StatusBarIconController.TintedIconManager.Factory,
+    private val privacyIconsController: HeaderPrivacyIconsController,
+    private val insetsProvider: StatusBarContentInsetsProvider,
+    private val configurationController: ConfigurationController,
+    private val variableDateViewControllerFactory: VariableDateViewController.Factory,
+    @Named(SHADE_HEADER) private val batteryMeterViewController: BatteryMeterViewController,
+    private val dumpManager: DumpManager,
+    private val qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder,
+    private val combinedShadeHeadersConstraintManager: CombinedShadeHeadersConstraintManager,
+    private val demoModeController: DemoModeController,
+    private val qsBatteryModeController: QsBatteryModeController,
+) : ViewController<View>(header), Dumpable {
+
+    companion object {
+        /** IDs for transitions and constraints for the [MotionLayout]. */
+        @VisibleForTesting internal val HEADER_TRANSITION_ID = R.id.header_transition
+        @VisibleForTesting
+        internal val LARGE_SCREEN_HEADER_TRANSITION_ID = R.id.large_screen_header_transition
+        @VisibleForTesting internal val QQS_HEADER_CONSTRAINT = R.id.qqs_header_constraint
+        @VisibleForTesting internal val QS_HEADER_CONSTRAINT = R.id.qs_header_constraint
+        @VisibleForTesting
+        internal val LARGE_SCREEN_HEADER_CONSTRAINT = R.id.large_screen_header_constraint
+
+        private fun Int.stateToString() =
+            when (this) {
+                QQS_HEADER_CONSTRAINT -> "QQS Header"
+                QS_HEADER_CONSTRAINT -> "QS Header"
+                LARGE_SCREEN_HEADER_CONSTRAINT -> "Large Screen Header"
+                else -> "Unknown state $this"
+            }
+    }
+
+    private lateinit var iconManager: StatusBarIconController.TintedIconManager
+    private lateinit var carrierIconSlots: List<String>
+    private lateinit var qsCarrierGroupController: QSCarrierGroupController
+
+    private val batteryIcon: BatteryMeterView = header.findViewById(R.id.batteryRemainingIcon)
+    private val clock: Clock = header.findViewById(R.id.clock)
+    private val date: TextView = header.findViewById(R.id.date)
+    private val iconContainer: StatusIconContainer = header.findViewById(R.id.statusIcons)
+    private val qsCarrierGroup: QSCarrierGroup = header.findViewById(R.id.carrier_group)
+
+    private var roundedCorners = 0
+    private var cutout: DisplayCutout? = null
+    private var lastInsets: WindowInsets? = null
+
+    private var qsDisabled = false
+    private var visible = false
+        set(value) {
+            if (field == value) {
+                return
+            }
+            field = value
+            updateListeners()
+        }
+
+    private var customizing = false
+        set(value) {
+            if (field != value) {
+                field = value
+                updateVisibility()
+            }
+        }
+
+    /**
+     * Whether the QQS/QS part of the shade is visible. This is particularly important in
+     * Lockscreen, as the shade is visible but QS is not.
+     */
+    var qsVisible = false
+        set(value) {
+            if (field == value) {
+                return
+            }
+            field = value
+            onShadeExpandedChanged()
+        }
+
+    /**
+     * Whether we are in a configuration with large screen width. In this case, the header is a
+     * single line.
+     */
+    var largeScreenActive = false
+        set(value) {
+            if (field == value) {
+                return
+            }
+            field = value
+            onHeaderStateChanged()
+        }
+
+    /** Expansion fraction of the QQS/QS shade. This is not the expansion between QQS <-> QS. */
+    var shadeExpandedFraction = -1f
+        set(value) {
+            if (qsVisible && field != value) {
+                header.alpha = ShadeInterpolation.getContentAlpha(value)
+                field = value
+            }
+        }
+
+    /** Expansion fraction of the QQS <-> QS animation. */
+    var qsExpandedFraction = -1f
+        set(value) {
+            if (visible && field != value) {
+                field = value
+                updatePosition()
+            }
+        }
+
+    /** Current scroll of QS. */
+    var qsScrollY = 0
+        set(value) {
+            if (field != value) {
+                field = value
+                updateScrollY()
+            }
+        }
+
+    private val insetListener =
+        View.OnApplyWindowInsetsListener { view, insets ->
+            updateConstraintsForInsets(view as MotionLayout, insets)
+            lastInsets = WindowInsets(insets)
+
+            view.onApplyWindowInsets(insets)
+        }
+
+    private val demoModeReceiver =
+        object : DemoMode {
+            override fun demoCommands() = listOf(DemoMode.COMMAND_CLOCK)
+            override fun dispatchDemoCommand(command: String, args: Bundle) =
+                clock.dispatchDemoCommand(command, args)
+            override fun onDemoModeStarted() = clock.onDemoModeStarted()
+            override fun onDemoModeFinished() = clock.onDemoModeFinished()
+        }
+
+    private val chipVisibilityListener: ChipVisibilityListener =
+        object : ChipVisibilityListener {
+            override fun onChipVisibilityRefreshed(visible: Boolean) {
+                // If the privacy chip is visible, we hide the status icons and battery remaining
+                // icon, only in QQS.
+                val update =
+                    combinedShadeHeadersConstraintManager.privacyChipVisibilityConstraints(visible)
+                header.updateAllConstraints(update)
+            }
+        }
+
+    private val configurationControllerListener =
+        object : ConfigurationController.ConfigurationListener {
+            override fun onConfigChanged(newConfig: Configuration?) {
+                val left =
+                    header.resources.getDimensionPixelSize(
+                        R.dimen.large_screen_shade_header_left_padding
+                    )
+                header.setPadding(
+                    left,
+                    header.paddingTop,
+                    header.paddingRight,
+                    header.paddingBottom
+                )
+            }
+
+            override fun onDensityOrFontScaleChanged() {
+                clock.setTextAppearance(R.style.TextAppearance_QS_Status)
+                date.setTextAppearance(R.style.TextAppearance_QS_Status)
+                qsCarrierGroup.updateTextAppearance(R.style.TextAppearance_QS_Status_Carriers)
+                loadConstraints()
+                header.minHeight =
+                    resources.getDimensionPixelSize(R.dimen.large_screen_shade_header_min_height)
+                lastInsets?.let { updateConstraintsForInsets(header, it) }
+                updateResources()
+            }
+        }
+
+    override fun onInit() {
+        variableDateViewControllerFactory.create(date as VariableDateView).init()
+        batteryMeterViewController.init()
+
+        // battery settings same as in QS icons
+        batteryMeterViewController.ignoreTunerUpdates()
+
+        iconManager = tintedIconManagerFactory.create(iconContainer, StatusBarLocation.QS)
+        iconManager.setTint(
+            Utils.getColorAttrDefaultColor(header.context, android.R.attr.textColorPrimary)
+        )
+
+        carrierIconSlots =
+            listOf(header.context.getString(com.android.internal.R.string.status_bar_mobile))
+        qsCarrierGroupController =
+            qsCarrierGroupControllerBuilder.setQSCarrierGroup(qsCarrierGroup).build()
+
+        privacyIconsController.onParentVisible()
+    }
+
+    override fun onViewAttached() {
+        privacyIconsController.chipVisibilityListener = chipVisibilityListener
+        updateVisibility()
+        updateTransition()
+
+        header.setOnApplyWindowInsetsListener(insetListener)
+
+        clock.addOnLayoutChangeListener { v, _, _, _, _, _, _, _, _ ->
+            val newPivot = if (v.isLayoutRtl) v.width.toFloat() else 0f
+            v.pivotX = newPivot
+            v.pivotY = v.height.toFloat() / 2
+
+            qsCarrierGroup.setPaddingRelative((v.width * v.scaleX).toInt(), 0, 0, 0)
+        }
+
+        dumpManager.registerDumpable(this)
+        configurationController.addCallback(configurationControllerListener)
+        demoModeController.addCallback(demoModeReceiver)
+        statusBarIconController.addIconGroup(iconManager)
+    }
+
+    override fun onViewDetached() {
+        privacyIconsController.chipVisibilityListener = null
+        dumpManager.unregisterDumpable(this::class.java.simpleName)
+        configurationController.removeCallback(configurationControllerListener)
+        demoModeController.removeCallback(demoModeReceiver)
+        statusBarIconController.removeIconGroup(iconManager)
+    }
+
+    fun disable(state1: Int, state2: Int, animate: Boolean) {
+        val disabled = state2 and StatusBarManager.DISABLE2_QUICK_SETTINGS != 0
+        if (disabled == qsDisabled) return
+        qsDisabled = disabled
+        updateVisibility()
+    }
+
+    fun startCustomizingAnimation(show: Boolean, duration: Long) {
+        header
+            .animate()
+            .setDuration(duration)
+            .alpha(if (show) 0f else 1f)
+            .setInterpolator(if (show) Interpolators.ALPHA_OUT else Interpolators.ALPHA_IN)
+            .setListener(CustomizerAnimationListener(show))
+            .start()
+    }
+
+    private fun loadConstraints() {
+        // Use resources.getXml instead of passing the resource id due to bug b/205018300
+        header
+            .getConstraintSet(QQS_HEADER_CONSTRAINT)
+            .load(context, resources.getXml(R.xml.qqs_header))
+        header
+            .getConstraintSet(QS_HEADER_CONSTRAINT)
+            .load(context, resources.getXml(R.xml.qs_header))
+        header
+            .getConstraintSet(LARGE_SCREEN_HEADER_CONSTRAINT)
+            .load(context, resources.getXml(R.xml.large_screen_shade_header))
+    }
+
+    private fun updateConstraintsForInsets(view: MotionLayout, insets: WindowInsets) {
+        val cutout = insets.displayCutout.also { this.cutout = it }
+
+        val sbInsets: Pair<Int, Int> = insetsProvider.getStatusBarContentInsetsForCurrentRotation()
+        val cutoutLeft = sbInsets.first
+        val cutoutRight = sbInsets.second
+        val hasCornerCutout: Boolean = insetsProvider.currentRotationHasCornerCutout()
+        updateQQSPaddings()
+        // Set these guides as the left/right limits for content that lives in the top row, using
+        // cutoutLeft and cutoutRight
+        var changes =
+            combinedShadeHeadersConstraintManager.edgesGuidelinesConstraints(
+                if (view.isLayoutRtl) cutoutRight else cutoutLeft,
+                header.paddingStart,
+                if (view.isLayoutRtl) cutoutLeft else cutoutRight,
+                header.paddingEnd
+            )
+
+        if (cutout != null) {
+            val topCutout = cutout.boundingRectTop
+            if (topCutout.isEmpty || hasCornerCutout) {
+                changes += combinedShadeHeadersConstraintManager.emptyCutoutConstraints()
+            } else {
+                changes +=
+                    combinedShadeHeadersConstraintManager.centerCutoutConstraints(
+                        view.isLayoutRtl,
+                        (view.width - view.paddingLeft - view.paddingRight - topCutout.width()) / 2
+                    )
+            }
+        } else {
+            changes += combinedShadeHeadersConstraintManager.emptyCutoutConstraints()
+        }
+
+        view.updateAllConstraints(changes)
+        updateBatteryMode()
+    }
+
+    private fun updateBatteryMode() {
+        qsBatteryModeController.getBatteryMode(cutout, qsExpandedFraction)?.let {
+            batteryIcon.setPercentShowMode(it)
+        }
+    }
+
+    private fun updateScrollY() {
+        if (!largeScreenActive) {
+            header.scrollY = qsScrollY
+        }
+    }
+
+    private fun onShadeExpandedChanged() {
+        if (qsVisible) {
+            privacyIconsController.startListening()
+        } else {
+            privacyIconsController.stopListening()
+        }
+        updateVisibility()
+        updatePosition()
+    }
+
+    private fun onHeaderStateChanged() {
+        updateTransition()
+    }
+
+    /**
+     * If not using [combinedHeaders] this should only be visible on large screen. Else, it should
+     * be visible any time the QQS/QS shade is open.
+     */
+    private fun updateVisibility() {
+        val visibility =
+            if (qsDisabled) {
+                View.GONE
+            } else if (qsVisible && !customizing) {
+                View.VISIBLE
+            } else {
+                View.INVISIBLE
+            }
+        if (header.visibility != visibility) {
+            header.visibility = visibility
+            visible = visibility == View.VISIBLE
+        }
+    }
+
+    private fun updateTransition() {
+        if (largeScreenActive) {
+            logInstantEvent("Large screen constraints set")
+            header.setTransition(LARGE_SCREEN_HEADER_TRANSITION_ID)
+        } else {
+            logInstantEvent("Small screen constraints set")
+            header.setTransition(HEADER_TRANSITION_ID)
+        }
+        header.jumpToState(header.startState)
+        updatePosition()
+        updateScrollY()
+    }
+
+    private fun updatePosition() {
+        if (!largeScreenActive && visible) {
+            logInstantEvent("updatePosition: $qsExpandedFraction")
+            header.progress = qsExpandedFraction
+            updateBatteryMode()
+        }
+    }
+
+    private fun logInstantEvent(message: String) {
+        Trace.instantForTrack(TRACE_TAG_APP, "LargeScreenHeaderController", message)
+    }
+
+    private fun updateListeners() {
+        qsCarrierGroupController.setListening(visible)
+        if (visible) {
+            updateSingleCarrier(qsCarrierGroupController.isSingleCarrier)
+            qsCarrierGroupController.setOnSingleCarrierChangedListener { updateSingleCarrier(it) }
+        } else {
+            qsCarrierGroupController.setOnSingleCarrierChangedListener(null)
+        }
+    }
+
+    private fun updateSingleCarrier(singleCarrier: Boolean) {
+        if (singleCarrier) {
+            iconContainer.removeIgnoredSlots(carrierIconSlots)
+        } else {
+            iconContainer.addIgnoredSlots(carrierIconSlots)
+        }
+    }
+
+    private fun updateResources() {
+        roundedCorners = resources.getDimensionPixelSize(R.dimen.rounded_corner_content_padding)
+        val padding = resources.getDimensionPixelSize(R.dimen.qs_panel_padding)
+        header.setPadding(padding, header.paddingTop, padding, header.paddingBottom)
+        updateQQSPaddings()
+        qsBatteryModeController.updateResources()
+    }
+
+    private fun updateQQSPaddings() {
+        val clockPaddingStart =
+            resources.getDimensionPixelSize(R.dimen.status_bar_left_clock_starting_padding)
+        val clockPaddingEnd =
+            resources.getDimensionPixelSize(R.dimen.status_bar_left_clock_end_padding)
+        clock.setPaddingRelative(
+            clockPaddingStart,
+            clock.paddingTop,
+            clockPaddingEnd,
+            clock.paddingBottom
+        )
+    }
+
+    override fun dump(pw: PrintWriter, args: Array<out String>) {
+        pw.println("visible: $visible")
+        pw.println("shadeExpanded: $qsVisible")
+        pw.println("shadeExpandedFraction: $shadeExpandedFraction")
+        pw.println("active: $largeScreenActive")
+        pw.println("qsExpandedFraction: $qsExpandedFraction")
+        pw.println("qsScrollY: $qsScrollY")
+        pw.println("currentState: ${header.currentState.stateToString()}")
+    }
+
+    private fun MotionLayout.updateConstraints(@IdRes state: Int, update: ConstraintChange) {
+        val constraints = getConstraintSet(state)
+        constraints.update()
+        updateState(state, constraints)
+    }
+
+    /**
+     * Updates the [ConstraintSet] for the case of combined headers.
+     *
+     * Only non-`null` changes are applied to reduce the number of rebuilding in the [MotionLayout].
+     */
+    private fun MotionLayout.updateAllConstraints(updates: ConstraintsChanges) {
+        if (updates.qqsConstraintsChanges != null) {
+            updateConstraints(QQS_HEADER_CONSTRAINT, updates.qqsConstraintsChanges)
+        }
+        if (updates.qsConstraintsChanges != null) {
+            updateConstraints(QS_HEADER_CONSTRAINT, updates.qsConstraintsChanges)
+        }
+        if (updates.largeScreenConstraintsChanges != null) {
+            updateConstraints(LARGE_SCREEN_HEADER_CONSTRAINT, updates.largeScreenConstraintsChanges)
+        }
+    }
+
+    @VisibleForTesting internal fun simulateViewDetached() = this.onViewDetached()
+
+    inner class CustomizerAnimationListener(
+        private val enteringCustomizing: Boolean,
+    ) : AnimatorListenerAdapter() {
+        override fun onAnimationEnd(animation: Animator?) {
+            super.onAnimationEnd(animation)
+            header.animate().setListener(null)
+            if (enteringCustomizing) {
+                customizing = true
+            }
+        }
+
+        override fun onAnimationStart(animation: Animator?) {
+            super.onAnimationStart(animation)
+            if (!enteringCustomizing) {
+                customizing = false
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
index 26c839de..d34e127 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
@@ -20,6 +20,9 @@
 import com.android.systemui.log.dagger.ShadeLog
 import com.android.systemui.plugins.log.LogBuffer
 import com.android.systemui.plugins.log.LogLevel
+import com.android.systemui.shade.NotificationPanelViewController.FLING_COLLAPSE
+import com.android.systemui.shade.NotificationPanelViewController.FLING_EXPAND
+import com.android.systemui.shade.NotificationPanelViewController.FLING_HIDE
 import com.google.errorprone.annotations.CompileTimeConstant
 import javax.inject.Inject
 
@@ -50,7 +53,6 @@
         h: Float,
         touchSlop: Float,
         qsExpanded: Boolean,
-        collapsedOnDown: Boolean,
         keyguardShowing: Boolean,
         qsExpansionEnabled: Boolean
     ) {
@@ -63,13 +65,12 @@
                 long1 = h.toLong()
                 double1 = touchSlop.toDouble()
                 bool1 = qsExpanded
-                bool2 = collapsedOnDown
-                bool3 = keyguardShowing
-                bool4 = qsExpansionEnabled
+                bool2 = keyguardShowing
+                bool3 = qsExpansionEnabled
             },
             {
                 "QsTrackingNotStarted: initTouchY=$int1,y=$int2,h=$long1,slop=$double1,qsExpanded" +
-                    "=$bool1,collapsedDown=$bool2,keyguardShowing=$bool3,qsExpansion=$bool4"
+                    "=$bool1,keyguardShowing=$bool2,qsExpansion=$bool3"
             }
         )
     }
@@ -152,13 +153,23 @@
         )
     }
 
+    fun logQsExpandImmediateChanged(newValue: Boolean) {
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                bool1 = newValue
+            },
+            { "qsExpandImmediate=$bool1" }
+        )
+    }
+
     fun logQsExpansionChanged(
             message: String,
             qsExpanded: Boolean,
             qsMinExpansionHeight: Int,
             qsMaxExpansionHeight: Int,
             stackScrollerOverscrolling: Boolean,
-            dozing: Boolean,
             qsAnimatorExpand: Boolean,
             animatingQs: Boolean
     ) {
@@ -171,14 +182,13 @@
                 int1 = qsMinExpansionHeight
                 int2 = qsMaxExpansionHeight
                 bool2 = stackScrollerOverscrolling
-                bool3 = dozing
-                bool4 = qsAnimatorExpand
+                bool3 = qsAnimatorExpand
                 // 0 = false, 1 = true
                 long1 = animatingQs.compareTo(false).toLong()
             },
             {
                 "$str1 qsExpanded=$bool1,qsMinExpansionHeight=$int1,qsMaxExpansionHeight=$int2," +
-                    "stackScrollerOverscrolling=$bool2,dozing=$bool3,qsAnimatorExpand=$bool4," +
+                    "stackScrollerOverscrolling=$bool2,qsAnimatorExpand=$bool3," +
                     "animatingQs=$long1"
             }
         )
@@ -234,18 +244,40 @@
         )
     }
 
-    fun logLastFlingWasExpanding(
-            expand: Boolean
-    ) {
+    fun logLastFlingWasExpanding(expand: Boolean) {
         buffer.log(
-                TAG,
-                LogLevel.VERBOSE,
-                {
-                    bool1 = expand
-                },
-                {
-                    "NPVC mLastFlingWasExpanding set to: $bool1"
-                }
+            TAG,
+            LogLevel.VERBOSE,
+            { bool1 = expand },
+            { "NPVC mLastFlingWasExpanding set to: $bool1" }
+        )
+    }
+
+    fun flingQs(flingType: Int, isClick: Boolean) {
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                str1 = flingTypeToString(flingType)
+                bool1 = isClick
+            },
+            { "QS fling with type $str1, originated from click: $isClick" }
+        )
+    }
+
+    private fun flingTypeToString(flingType: Int) = when (flingType) {
+        FLING_EXPAND -> "FLING_EXPAND"
+        FLING_COLLAPSE -> "FLING_COLLAPSE"
+        FLING_HIDE -> "FLING_HIDE"
+        else -> "UNKNOWN"
+    }
+
+    fun logSplitShadeChanged(splitShadeEnabled: Boolean) {
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            { bool1 = splitShadeEnabled },
+            { "Split shade state changed: split shade ${if (bool1) "enabled" else "disabled"}" }
         )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
index 07820ec..129d09e 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
@@ -43,8 +43,6 @@
     shadeExpansionStateManager: ShadeExpansionStateManager,
     dumpManager: DumpManager,
     private val context: Context,
-    private val splitShadeOverScrollerFactory: SplitShadeOverScroller.Factory,
-    private val noOpOverScroller: NoOpOverScroller,
     private val scrimShadeTransitionController: ScrimShadeTransitionController,
     private val statusBarStateController: SysuiStatusBarStateController,
 ) {
@@ -57,17 +55,6 @@
     private var currentPanelState: Int? = null
     private var lastShadeExpansionChangeEvent: ShadeExpansionChangeEvent? = null
 
-    private val splitShadeOverScroller by lazy {
-        splitShadeOverScrollerFactory.create({ qs }, { notificationStackScrollLayoutController })
-    }
-    private val shadeOverScroller: ShadeOverScroller
-        get() =
-            if (inSplitShade && isScreenUnlocked() && propertiesInitialized()) {
-                splitShadeOverScroller
-            } else {
-                noOpOverScroller
-            }
-
     init {
         updateResources()
         configurationController.addCallback(
@@ -89,21 +76,14 @@
 
     private fun onPanelStateChanged(@PanelState state: Int) {
         currentPanelState = state
-        shadeOverScroller.onPanelStateChanged(state)
         scrimShadeTransitionController.onPanelStateChanged(state)
     }
 
     private fun onPanelExpansionChanged(event: ShadeExpansionChangeEvent) {
         lastShadeExpansionChangeEvent = event
-        shadeOverScroller.onDragDownAmountChanged(event.dragDownPxAmount)
         scrimShadeTransitionController.onPanelExpansionChanged(event)
     }
 
-    private fun propertiesInitialized() =
-        this::qs.isInitialized &&
-            this::notificationPanelViewController.isInitialized &&
-            this::notificationStackScrollLayoutController.isInitialized
-
     private fun dump(pw: PrintWriter) {
         pw.println(
             """
diff --git a/packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt b/packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt
deleted file mode 100644
index f95125f..0000000
--- a/packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.shade.transition
-
-import android.animation.Animator
-import android.animation.ValueAnimator
-import android.content.Context
-import android.content.res.Configuration
-import android.util.MathUtils
-import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.R
-import com.android.systemui.animation.Interpolators
-import com.android.systemui.dump.DumpManager
-import com.android.systemui.plugins.qs.QS
-import com.android.systemui.shade.PanelState
-import com.android.systemui.shade.STATE_CLOSED
-import com.android.systemui.shade.STATE_OPENING
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
-import com.android.systemui.statusbar.phone.ScrimController
-import com.android.systemui.statusbar.policy.ConfigurationController
-import dagger.assisted.Assisted
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
-import java.io.PrintWriter
-
-class SplitShadeOverScroller
-@AssistedInject
-constructor(
-    configurationController: ConfigurationController,
-    dumpManager: DumpManager,
-    private val context: Context,
-    private val scrimController: ScrimController,
-    @Assisted private val qSProvider: () -> QS,
-    @Assisted private val nsslControllerProvider: () -> NotificationStackScrollLayoutController
-) : ShadeOverScroller {
-
-    private var releaseOverScrollDuration = 0L
-    private var maxOverScrollAmount = 0
-    private var previousOverscrollAmount = 0
-    private var dragDownAmount: Float = 0f
-    @PanelState private var panelState: Int = STATE_CLOSED
-
-    private var releaseOverScrollAnimator: Animator? = null
-
-    private val qS: QS
-        get() = qSProvider()
-
-    private val nsslController: NotificationStackScrollLayoutController
-        get() = nsslControllerProvider()
-
-    init {
-        updateResources()
-        configurationController.addCallback(
-            object : ConfigurationController.ConfigurationListener {
-                override fun onConfigChanged(newConfig: Configuration?) {
-                    updateResources()
-                }
-            })
-        dumpManager.registerCriticalDumpable("SplitShadeOverScroller") { printWriter, _ ->
-            dump(printWriter)
-        }
-    }
-
-    private fun updateResources() {
-        val resources = context.resources
-        maxOverScrollAmount = resources.getDimensionPixelSize(R.dimen.shade_max_over_scroll_amount)
-        releaseOverScrollDuration =
-            resources.getInteger(R.integer.lockscreen_shade_over_scroll_release_duration).toLong()
-    }
-
-    override fun onPanelStateChanged(@PanelState newPanelState: Int) {
-        if (shouldReleaseOverscroll(previousState = panelState, newState = newPanelState)) {
-            releaseOverScroll()
-        }
-        panelState = newPanelState
-    }
-
-    override fun onDragDownAmountChanged(newDragDownAmount: Float) {
-        if (dragDownAmount == newDragDownAmount) {
-            return
-        }
-        dragDownAmount = newDragDownAmount
-        if (shouldOverscroll()) {
-            overScroll(newDragDownAmount)
-        }
-    }
-
-    private fun shouldOverscroll() = panelState == STATE_OPENING
-
-    private fun shouldReleaseOverscroll(@PanelState previousState: Int, @PanelState newState: Int) =
-        previousState == STATE_OPENING && newState != STATE_OPENING
-
-    private fun overScroll(dragDownAmount: Float) {
-        val overscrollAmount: Int = calculateOverscrollAmount(dragDownAmount)
-        applyOverscroll(overscrollAmount)
-        previousOverscrollAmount = overscrollAmount
-    }
-
-    private fun calculateOverscrollAmount(dragDownAmount: Float): Int {
-        val fullHeight: Int = nsslController.height
-        val fullHeightProgress: Float = MathUtils.saturate(dragDownAmount / fullHeight)
-        return (fullHeightProgress * maxOverScrollAmount).toInt()
-    }
-
-    private fun applyOverscroll(overscrollAmount: Int) {
-        qS.setOverScrollAmount(overscrollAmount)
-        scrimController.setNotificationsOverScrollAmount(overscrollAmount)
-        nsslController.setOverScrollAmount(overscrollAmount)
-    }
-
-    private fun releaseOverScroll() {
-        val animator = ValueAnimator.ofInt(previousOverscrollAmount, 0)
-        animator.addUpdateListener {
-            val overScrollAmount = it.animatedValue as Int
-            qS.setOverScrollAmount(overScrollAmount)
-            scrimController.setNotificationsOverScrollAmount(overScrollAmount)
-            nsslController.setOverScrollAmount(overScrollAmount)
-        }
-        animator.interpolator = Interpolators.STANDARD
-        animator.duration = releaseOverScrollDuration
-        animator.start()
-        releaseOverScrollAnimator = animator
-        previousOverscrollAmount = 0
-    }
-
-    @VisibleForTesting
-    internal fun finishAnimations() {
-        releaseOverScrollAnimator?.end()
-        releaseOverScrollAnimator = null
-    }
-
-    private fun dump(pw: PrintWriter) {
-        pw.println(
-            """
-            SplitShadeOverScroller:
-                Resources:
-                    releaseOverScrollDuration: $releaseOverScrollDuration
-                    maxOverScrollAmount: $maxOverScrollAmount
-                State:
-                    previousOverscrollAmount: $previousOverscrollAmount
-                    dragDownAmount: $dragDownAmount
-                    panelState: $panelState
-            """.trimIndent())
-    }
-
-    @AssistedFactory
-    fun interface Factory {
-        fun create(
-            qSProvider: () -> QS,
-            nsslControllerProvider: () -> NotificationStackScrollLayoutController
-        ): SplitShadeOverScroller
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
index 236ba1f..5736a5c 100644
--- a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
@@ -21,6 +21,7 @@
 import android.view.ViewGroup
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.BcSmartspaceDataPlugin
+import com.android.systemui.plugins.BcSmartspaceDataPlugin.UI_SURFACE_DREAM
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.smartspace.dagger.SmartspaceViewComponent.SmartspaceViewModule.PLUGIN
 import dagger.BindsInstance
@@ -57,7 +58,7 @@
                 BcSmartspaceDataPlugin.SmartspaceView {
             val ssView = plugin.getView(parent)
             // Currently, this is only used to provide SmartspaceView on Dream surface.
-            ssView.setIsDreaming(true)
+            ssView.setUiSurface(UI_SURFACE_DREAM)
             ssView.registerDataProvider(plugin)
 
             ssView.setIntentStarter(object : BcSmartspaceDataPlugin.IntentStarter {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BatteryStatusChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BatteryStatusChip.kt
new file mode 100644
index 0000000..37140ec
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BatteryStatusChip.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar
+
+import android.annotation.IntRange
+import android.annotation.SuppressLint
+import android.content.Context
+import android.content.res.Configuration
+import android.util.AttributeSet
+import android.view.View
+import android.widget.FrameLayout
+import android.widget.LinearLayout
+import com.android.settingslib.Utils
+import com.android.systemui.R
+import com.android.systemui.battery.BatteryMeterView
+import com.android.systemui.statusbar.events.BackgroundAnimatableView
+
+class BatteryStatusChip @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
+    FrameLayout(context, attrs), BackgroundAnimatableView {
+
+    private val roundedContainer: LinearLayout
+    private val batteryMeterView: BatteryMeterView
+    override val contentView: View
+        get() = batteryMeterView
+
+    init {
+        inflate(context, R.layout.battery_status_chip, this)
+        roundedContainer = findViewById(R.id.rounded_container)
+        batteryMeterView = findViewById(R.id.battery_meter_view)
+        updateResources()
+    }
+
+    /**
+     * When animating as a chip in the status bar, we want to animate the width for the rounded
+     * container. We have to subtract our own top and left offset because the bounds come to us as
+     * absolute on-screen bounds.
+     */
+    override fun setBoundsForAnimation(l: Int, t: Int, r: Int, b: Int) {
+        roundedContainer.setLeftTopRightBottom(l - left, t - top, r - left, b - top)
+    }
+
+    fun setBatteryLevel(@IntRange(from = 0, to = 100) batteryLevel: Int) {
+        batteryMeterView.setForceShowPercent(true)
+        batteryMeterView.onBatteryLevelChanged(batteryLevel, true)
+    }
+
+    override fun onConfigurationChanged(newConfig: Configuration) {
+        super.onConfigurationChanged(newConfig)
+        updateResources()
+    }
+
+    @SuppressLint("UseCompatLoadingForDrawables")
+    private fun updateResources() {
+        val primaryColor =
+            Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.colorPrimary)
+        val textColorSecondary =
+            Utils.getColorAttrDefaultColor(mContext, android.R.attr.textColorSecondary)
+        batteryMeterView.updateColors(primaryColor, textColorSecondary, primaryColor)
+        roundedContainer.background = mContext.getDrawable(R.drawable.statusbar_chip_bg)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index afa60fb..f0d064b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -187,6 +187,8 @@
 
     private val qsTransitionController = qsTransitionControllerFactory.create { qS }
 
+    private val callbacks = mutableListOf<Callback>()
+
     /** See [LockscreenShadeQsTransitionController.qsTransitionFraction].*/
     @get:FloatRange(from = 0.0, to = 1.0)
     val qSDragProgress: Float
@@ -319,8 +321,8 @@
                                     true /* drag down is always an open */)
                         }
                         notificationPanelController.animateToFullShade(delay)
-                        notificationPanelController.setTransitionToFullShadeAmount(0f,
-                                true /* animated */, delay)
+                        callbacks.forEach { it.setTransitionToFullShadeAmount(0f,
+                                true /* animated */, delay) }
 
                         // Let's reset ourselves, ready for the next animation
 
@@ -424,8 +426,8 @@
 
                     qsTransitionController.dragDownAmount = value
 
-                    notificationPanelController.setTransitionToFullShadeAmount(field,
-                            false /* animate */, 0 /* delay */)
+                    callbacks.forEach { it.setTransitionToFullShadeAmount(field,
+                            false /* animate */, 0 /* delay */) }
 
                     mediaHierarchyManager.setTransitionToFullShadeAmount(field)
                     scrimTransitionController.dragDownAmount = value
@@ -688,7 +690,7 @@
         if (cancelled) {
             setPulseHeight(0f, animate = true)
         } else {
-            notificationPanelController.onPulseExpansionFinished()
+            callbacks.forEach { it.onPulseExpansionFinished() }
             setPulseHeight(0f, animate = false)
         }
     }
@@ -720,6 +722,27 @@
                 "${animationHandlerOnKeyguardDismiss != null}")
         }
     }
+
+
+    fun addCallback(callback: Callback) {
+        if (!callbacks.contains(callback)) {
+            callbacks.add(callback)
+        }
+    }
+
+    /**
+     * Callback for authentication events.
+     */
+    interface Callback {
+        /** TODO: comment here  */
+        fun onPulseExpansionFinished() {}
+
+        /**
+         * Sets the amount of pixels we have currently dragged down if we're transitioning
+         * to the full shade. 0.0f means we're not transitioning yet.
+         */
+        fun setTransitionToFullShadeAmount(pxAmount: Float, animate: Boolean, delay: Long) {}
+    }
 }
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index f4cd985..51c5183 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -213,7 +213,8 @@
             DeviceProvisionedController deviceProvisionedController,
             KeyguardStateController keyguardStateController,
             SecureSettings secureSettings,
-            DumpManager dumpManager) {
+            DumpManager dumpManager,
+            LockPatternUtils lockPatternUtils) {
         mContext = context;
         mMainHandler = mainHandler;
         mDevicePolicyManager = devicePolicyManager;
@@ -225,7 +226,7 @@
         mClickNotifier = clickNotifier;
         mOverviewProxyServiceLazy = overviewProxyServiceLazy;
         statusBarStateController.addCallback(this);
-        mLockPatternUtils = new LockPatternUtils(context);
+        mLockPatternUtils = lockPatternUtils;
         mKeyguardManager = keyguardManager;
         mBroadcastDispatcher = broadcastDispatcher;
         mDeviceProvisionedController = deviceProvisionedController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
index f259284..6a8d5c1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
@@ -16,7 +16,7 @@
 
 package com.android.systemui.statusbar.events
 
-import android.animation.Animator
+import androidx.core.animation.Animator
 import android.annotation.UiThread
 import android.graphics.Point
 import android.graphics.Rect
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusBarEventsModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusBarEventsModule.kt
new file mode 100644
index 0000000..3d6d489
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusBarEventsModule.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.events
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.window.StatusBarWindowController
+import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.time.SystemClock
+import dagger.Module
+import dagger.Provides
+import kotlinx.coroutines.CoroutineScope
+
+@Module
+interface StatusBarEventsModule {
+
+    companion object {
+
+        @Provides
+        @SysUISingleton
+        fun provideSystemStatusAnimationScheduler(
+                featureFlags: FeatureFlags,
+                coordinator: SystemEventCoordinator,
+                chipAnimationController: SystemEventChipAnimationController,
+                statusBarWindowController: StatusBarWindowController,
+                dumpManager: DumpManager,
+                systemClock: SystemClock,
+                @Application coroutineScope: CoroutineScope,
+                @Main executor: DelayableExecutor
+        ): SystemStatusAnimationScheduler {
+            return if (featureFlags.isEnabled(Flags.PLUG_IN_STATUS_BAR_CHIP)) {
+                SystemStatusAnimationSchedulerImpl(
+                        coordinator,
+                        chipAnimationController,
+                        statusBarWindowController,
+                        dumpManager,
+                        systemClock,
+                        coroutineScope
+                )
+            } else {
+                SystemStatusAnimationSchedulerLegacyImpl(
+                        coordinator,
+                        chipAnimationController,
+                        statusBarWindowController,
+                        dumpManager,
+                        systemClock,
+                        executor
+                )
+            }
+        }
+    }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
index 4e1404d..43f78c3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
@@ -16,24 +16,21 @@
 
 package com.android.systemui.statusbar.events
 
+import android.annotation.IntRange
 import android.annotation.SuppressLint
 import android.content.Context
-import android.graphics.Color
-import android.graphics.drawable.ColorDrawable
-import android.view.LayoutInflater
 import android.view.View
 import android.widget.ImageView
-import com.android.settingslib.graph.ThemedBatteryDrawable
-import com.android.systemui.R
 import com.android.systemui.privacy.OngoingPrivacyChip
 import com.android.systemui.privacy.PrivacyItem
+import com.android.systemui.statusbar.BatteryStatusChip
 
 typealias ViewCreator = (context: Context) -> BackgroundAnimatableView
 
 interface StatusEvent {
     val priority: Int
     // Whether or not to force the status bar open and show a dot
-    val forceVisible: Boolean
+    var forceVisible: Boolean
     // Whether or not to show an animation for this event
     val showAnimation: Boolean
     val viewCreator: ViewCreator
@@ -73,17 +70,16 @@
     }
 }
 
-class BatteryEvent : StatusEvent {
+class BatteryEvent(@IntRange(from = 0, to = 100) val batteryLevel: Int) : StatusEvent {
     override val priority = 50
-    override val forceVisible = false
+    override var forceVisible = false
     override val showAnimation = true
     override var contentDescription: String? = ""
 
-    override val viewCreator: (context: Context) -> BGImageView = { context ->
-        val iv = BGImageView(context)
-        iv.setImageDrawable(ThemedBatteryDrawable(context, Color.WHITE))
-        iv.setBackgroundDrawable(ColorDrawable(Color.GREEN))
-        iv
+    override val viewCreator: ViewCreator = { context ->
+        BatteryStatusChip(context).apply {
+            setBatteryLevel(batteryLevel)
+        }
     }
 
     override fun toString(): String {
@@ -94,13 +90,12 @@
 class PrivacyEvent(override val showAnimation: Boolean = true) : StatusEvent {
     override var contentDescription: String? = null
     override val priority = 100
-    override val forceVisible = true
+    override var forceVisible = true
     var privacyItems: List<PrivacyItem> = listOf()
     private var privacyChip: OngoingPrivacyChip? = null
 
     override val viewCreator: ViewCreator = { context ->
-        val v = LayoutInflater.from(context)
-                .inflate(R.layout.ongoing_privacy_chip, null) as OngoingPrivacyChip
+        val v = OngoingPrivacyChip(context)
         v.privacyList = privacyItems
         v.contentDescription = contentDescription
         privacyChip = v
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
index 8405aea..776956a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
@@ -16,10 +16,6 @@
 
 package com.android.systemui.statusbar.events
 
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
-import android.animation.AnimatorSet
-import android.animation.ValueAnimator
 import android.content.Context
 import android.graphics.Rect
 import android.view.ContextThemeWrapper
@@ -30,7 +26,13 @@
 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
 import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
 import android.widget.FrameLayout
+import androidx.core.animation.Animator
+import androidx.core.animation.AnimatorListenerAdapter
+import androidx.core.animation.AnimatorSet
+import androidx.core.animation.ValueAnimator
 import com.android.systemui.R
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import com.android.systemui.util.animation.AnimationUtil.Companion.frames
@@ -43,7 +45,8 @@
 class SystemEventChipAnimationController @Inject constructor(
     private val context: Context,
     private val statusBarWindowController: StatusBarWindowController,
-    private val contentInsetsProvider: StatusBarContentInsetsProvider
+    private val contentInsetsProvider: StatusBarContentInsetsProvider,
+    private val featureFlags: FeatureFlags
 ) : SystemStatusAnimationCallback {
 
     private lateinit var animationWindowView: FrameLayout
@@ -53,12 +56,14 @@
 
     // Left for LTR, Right for RTL
     private var animationDirection = LEFT
-    private var chipRight = 0
-    private var chipLeft = 0
-    private var chipWidth = 0
+    private var chipBounds = Rect()
+    private val chipWidth get() = chipBounds.width()
+    private val chipRight get() = chipBounds.right
+    private val chipLeft get() = chipBounds.left
     private var chipMinWidth = context.resources.getDimensionPixelSize(
             R.dimen.ongoing_appops_chip_min_animation_width)
-    private var dotSize = context.resources.getDimensionPixelSize(
+
+    private val dotSize = context.resources.getDimensionPixelSize(
             R.dimen.ongoing_appops_dot_diameter)
     // Use during animation so that multiple animators can update the drawing rect
     private var animRect = Rect()
@@ -90,21 +95,26 @@
             it.view.measure(
                     View.MeasureSpec.makeMeasureSpec(
                             (animationWindowView.parent as View).width, AT_MOST),
-                    View.MeasureSpec.makeMeasureSpec(animationWindowView.height, AT_MOST))
-            chipWidth = it.chipWidth
-        }
+                    View.MeasureSpec.makeMeasureSpec(
+                            (animationWindowView.parent as View).height, AT_MOST))
 
-        // decide which direction we're animating from, and then set some screen coordinates
-        val contentRect = contentInsetsProvider.getStatusBarContentAreaForCurrentRotation()
-        when (animationDirection) {
-            LEFT -> {
-                chipRight = contentRect.right
-                chipLeft = contentRect.right - chipWidth
+            // decide which direction we're animating from, and then set some screen coordinates
+            val contentRect = contentInsetsProvider.getStatusBarContentAreaForCurrentRotation()
+            val chipTop = ((animationWindowView.parent as View).height - it.view.measuredHeight) / 2
+            val chipBottom = chipTop + it.view.measuredHeight
+            val chipRight: Int
+            val chipLeft: Int
+            when (animationDirection) {
+                LEFT -> {
+                    chipRight = contentRect.right
+                    chipLeft = contentRect.right - it.chipWidth
+                }
+                else /* RIGHT */ -> {
+                    chipLeft = contentRect.left
+                    chipRight = contentRect.left + it.chipWidth
+                }
             }
-            else /* RIGHT */ -> {
-                chipLeft = contentRect.left
-                chipRight = contentRect.left + chipWidth
-            }
+            chipBounds = Rect(chipLeft, chipTop, chipRight, chipBottom)
         }
     }
 
@@ -117,16 +127,21 @@
             interpolator = null
             addUpdateListener { currentAnimatedView?.view?.alpha = animatedValue as Float }
         }
+        currentAnimatedView?.contentView?.alpha = 0f
+        val contentAlphaIn = ValueAnimator.ofFloat(0f, 1f).apply {
+            startDelay = 10.frames
+            duration = 10.frames
+            interpolator = null
+            addUpdateListener { currentAnimatedView?.contentView?.alpha = animatedValue as Float }
+        }
         val moveIn = ValueAnimator.ofInt(chipMinWidth, chipWidth).apply {
             startDelay = 7.frames
             duration = 23.frames
             interpolator = STATUS_BAR_X_MOVE_IN
-            addUpdateListener {
-                updateAnimatedViewBoundsWidth(animatedValue as Int)
-            }
+            addUpdateListener { updateAnimatedViewBoundsWidth(animatedValue as Int) }
         }
         val animSet = AnimatorSet()
-        animSet.playTogether(alphaIn, moveIn)
+        animSet.playTogether(alphaIn, contentAlphaIn, moveIn)
         return animSet
     }
 
@@ -139,7 +154,7 @@
         }
 
         finish.addListener(object : AnimatorListenerAdapter() {
-            override fun onAnimationEnd(animation: Animator?) {
+            override fun onAnimationEnd(animation: Animator) {
                 animationWindowView.removeView(currentAnimatedView!!.view)
             }
         })
@@ -152,7 +167,7 @@
             duration = 9.frames
             interpolator = STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_1
             addUpdateListener {
-                updateAnimatedViewBoundsWidth(it.animatedValue as Int)
+                updateAnimatedViewBoundsWidth(animatedValue as Int)
             }
         }
 
@@ -161,7 +176,7 @@
             duration = 20.frames
             interpolator = STATUS_CHIP_WIDTH_TO_DOT_KEYFRAME_2
             addUpdateListener {
-                updateAnimatedViewBoundsWidth(it.animatedValue as Int)
+                updateAnimatedViewBoundsWidth(animatedValue as Int)
             }
         }
 
@@ -174,7 +189,7 @@
             duration = 6.frames
             interpolator = STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_1
             addUpdateListener {
-                updateAnimatedViewBoundsHeight(it.animatedValue as Int, chipVerticalCenter)
+                updateAnimatedViewBoundsHeight(animatedValue as Int, chipVerticalCenter)
             }
         }
 
@@ -183,7 +198,7 @@
             duration = 15.frames
             interpolator = STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_2
             addUpdateListener {
-                updateAnimatedViewBoundsHeight(it.animatedValue as Int, chipVerticalCenter)
+                updateAnimatedViewBoundsHeight(animatedValue as Int, chipVerticalCenter)
             }
         }
 
@@ -210,15 +225,32 @@
     }
 
     private fun createMoveOutAnimationDefault(): Animator {
+        val alphaOut = ValueAnimator.ofFloat(1f, 0f).apply {
+            startDelay = 6.frames
+            duration = 6.frames
+            interpolator = null
+            addUpdateListener { currentAnimatedView?.view?.alpha = animatedValue as Float }
+        }
+
+        val contentAlphaOut = ValueAnimator.ofFloat(1f, 0f).apply {
+            duration = 5.frames
+            interpolator = null
+            addUpdateListener { currentAnimatedView?.contentView?.alpha = animatedValue as Float }
+        }
+
         val moveOut = ValueAnimator.ofInt(chipWidth, chipMinWidth).apply {
             duration = 23.frames
+            interpolator = STATUS_BAR_X_MOVE_OUT
             addUpdateListener {
                 currentAnimatedView?.apply {
-                    updateAnimatedViewBoundsWidth(it.animatedValue as Int)
+                    updateAnimatedViewBoundsWidth(animatedValue as Int)
                 }
             }
         }
-        return moveOut
+
+        val animSet = AnimatorSet()
+        animSet.playTogether(alphaOut, contentAlphaOut, moveOut)
+        return animSet
     }
 
     private fun init() {
@@ -239,11 +271,15 @@
                 it.marginEnd = marginEnd
             }
 
-    private fun initializeAnimRect() = animRect.set(
-            chipLeft,
-            currentAnimatedView!!.view.top,
-            chipRight,
-            currentAnimatedView!!.view.bottom)
+    private fun initializeAnimRect() = if (featureFlags.isEnabled(Flags.PLUG_IN_STATUS_BAR_CHIP)) {
+        animRect.set(chipBounds)
+    } else {
+        animRect.set(
+                chipLeft,
+                currentAnimatedView!!.view.top,
+                chipRight,
+                currentAnimatedView!!.view.bottom)
+    }
 
     /**
      * To be called during an animation, sets the width and updates the current animated chip view
@@ -296,6 +332,8 @@
 interface BackgroundAnimatableView {
     val view: View // Since this can't extend View, add a view prop
         get() = this as View
+    val contentView: View? // This will be alpha faded during appear and disappear animation
+        get() = null
     val chipWidth: Int
         get() = view.measuredWidth
     fun setBoundsForAnimation(l: Int, t: Int, r: Int, b: Int)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
index fde5d39..26fd230 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
@@ -16,11 +16,14 @@
 
 package com.android.systemui.statusbar.events
 
+import android.annotation.IntRange
 import android.content.Context
 import android.provider.DeviceConfig
 import android.provider.DeviceConfig.NAMESPACE_PRIVACY
 import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.privacy.PrivacyChipBuilder
 import com.android.systemui.privacy.PrivacyItem
 import com.android.systemui.privacy.PrivacyItemController
@@ -37,21 +40,18 @@
     private val systemClock: SystemClock,
     private val batteryController: BatteryController,
     private val privacyController: PrivacyItemController,
-    private val context: Context
+    private val context: Context,
+    private val featureFlags: FeatureFlags
 ) {
     private lateinit var scheduler: SystemStatusAnimationScheduler
 
     fun startObserving() {
-        /* currently unused
         batteryController.addCallback(batteryStateListener)
-        */
         privacyController.addCallback(privacyStateListener)
     }
 
     fun stopObserving() {
-        /* currently unused
         batteryController.removeCallback(batteryStateListener)
-        */
         privacyController.removeCallback(privacyStateListener)
     }
 
@@ -59,12 +59,14 @@
         this.scheduler = s
     }
 
-    fun notifyPluggedIn() {
-        scheduler.onStatusEvent(BatteryEvent())
+    fun notifyPluggedIn(@IntRange(from = 0, to = 100) batteryLevel: Int) {
+        if (featureFlags.isEnabled(Flags.PLUG_IN_STATUS_BAR_CHIP)) {
+            scheduler.onStatusEvent(BatteryEvent(batteryLevel))
+        }
     }
 
     fun notifyPrivacyItemsEmpty() {
-        scheduler.setShouldShowPersistentPrivacyIndicator(false)
+        scheduler.removePersistentDot()
     }
 
     fun notifyPrivacyItemsChanged(showAnimation: Boolean = true) {
@@ -79,25 +81,25 @@
     }
 
     private val batteryStateListener = object : BatteryController.BatteryStateChangeCallback {
-        var plugged = false
-        var stateKnown = false
+        private var plugged = false
+        private var stateKnown = false
         override fun onBatteryLevelChanged(level: Int, pluggedIn: Boolean, charging: Boolean) {
             if (!stateKnown) {
                 stateKnown = true
                 plugged = pluggedIn
-                notifyListeners()
+                notifyListeners(level)
                 return
             }
 
             if (plugged != pluggedIn) {
                 plugged = pluggedIn
-                notifyListeners()
+                notifyListeners(level)
             }
         }
 
-        private fun notifyListeners() {
+        private fun notifyListeners(@IntRange(from = 0, to = 100) batteryLevel: Int) {
             // We only care about the plugged in status
-            if (plugged) notifyPluggedIn()
+            if (plugged) notifyPluggedIn(batteryLevel)
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
index 197cf56..2a18f1f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -16,302 +16,21 @@
 
 package com.android.systemui.statusbar.events
 
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
-import android.animation.AnimatorSet
 import android.annotation.IntDef
-import android.os.Process
-import android.provider.DeviceConfig
-import android.util.Log
-import android.view.animation.PathInterpolator
+import androidx.core.animation.Animator
+import androidx.core.animation.AnimatorSet
+import androidx.core.animation.PathInterpolator
 import com.android.systemui.Dumpable
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.dump.DumpManager
 import com.android.systemui.statusbar.policy.CallbackController
-import com.android.systemui.statusbar.window.StatusBarWindowController
-import com.android.systemui.util.Assert
-import com.android.systemui.util.concurrency.DelayableExecutor
-import com.android.systemui.util.time.SystemClock
-import java.io.PrintWriter
-import javax.inject.Inject
 
-/**
- * Dead-simple scheduler for system status events. Obeys the following principles (all values TBD):
- *      - Avoiding log spam by only allowing 12 events per minute (1event/5s)
- *      - Waits 100ms to schedule any event for debouncing/prioritization
- *      - Simple prioritization: Privacy > Battery > connectivity (encoded in [StatusEvent])
- *      - Only schedules a single event, and throws away lowest priority events
- *
- * There are 4 basic stages of animation at play here:
- *      1. System chrome animation OUT
- *      2. Chip animation IN
- *      3. Chip animation OUT; potentially into a dot
- *      4. System chrome animation IN
- *
- * Thus we can keep all animations synchronized with two separate ValueAnimators, one for system
- * chrome and the other for the chip. These can animate from 0,1 and listeners can parameterize
- * their respective views based on the progress of the animator. Interpolation differences TBD
- */
-@SysUISingleton
-open class SystemStatusAnimationScheduler @Inject constructor(
-    private val coordinator: SystemEventCoordinator,
-    private val chipAnimationController: SystemEventChipAnimationController,
-    private val statusBarWindowController: StatusBarWindowController,
-    private val dumpManager: DumpManager,
-    private val systemClock: SystemClock,
-    @Main private val executor: DelayableExecutor
-) : CallbackController<SystemStatusAnimationCallback>, Dumpable {
+interface SystemStatusAnimationScheduler :
+        CallbackController<SystemStatusAnimationCallback>, Dumpable {
 
-    companion object {
-        private const val PROPERTY_ENABLE_IMMERSIVE_INDICATOR = "enable_immersive_indicator"
-    }
-    public fun isImmersiveIndicatorEnabled(): Boolean {
-        return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
-                PROPERTY_ENABLE_IMMERSIVE_INDICATOR, true)
-    }
+    @SystemAnimationState fun getAnimationState(): Int
 
-    @SystemAnimationState var animationState: Int = IDLE
-        private set
+    fun onStatusEvent(event: StatusEvent)
 
-    /** True if the persistent privacy dot should be active */
-    var hasPersistentDot = false
-        protected set
-
-    private var scheduledEvent: StatusEvent? = null
-    private var cancelExecutionRunnable: Runnable? = null
-    private val listeners = mutableSetOf<SystemStatusAnimationCallback>()
-
-    fun getListeners(): MutableSet<SystemStatusAnimationCallback> {
-        return listeners
-    }
-
-    init {
-        coordinator.attachScheduler(this)
-        dumpManager.registerDumpable(TAG, this)
-    }
-
-    open fun onStatusEvent(event: StatusEvent) {
-        // Ignore any updates until the system is up and running
-        if (isTooEarly() || !isImmersiveIndicatorEnabled()) {
-            return
-        }
-
-        // Don't deal with threading for now (no need let's be honest)
-        Assert.isMainThread()
-        if ((event.priority > scheduledEvent?.priority ?: -1) &&
-                animationState != ANIMATING_OUT &&
-                (animationState != SHOWING_PERSISTENT_DOT && event.forceVisible)) {
-            // events can only be scheduled if a higher priority or no other event is in progress
-            if (DEBUG) {
-                Log.d(TAG, "scheduling event $event")
-            }
-
-            scheduleEvent(event)
-        } else if (scheduledEvent?.shouldUpdateFromEvent(event) == true) {
-            if (DEBUG) {
-                Log.d(TAG, "updating current event from: $event. animationState=$animationState")
-            }
-            scheduledEvent?.updateFromEvent(event)
-            if (event.forceVisible) {
-                hasPersistentDot = true
-                // If we missed the chance to show the persistent dot, do it now
-                if (animationState == IDLE) {
-                    notifyTransitionToPersistentDot()
-                }
-            }
-        } else {
-            if (DEBUG) {
-                Log.d(TAG, "ignoring event $event")
-            }
-        }
-    }
-
-    private fun clearDotIfVisible() {
-        notifyHidePersistentDot()
-    }
-
-    fun setShouldShowPersistentPrivacyIndicator(should: Boolean) {
-        if (hasPersistentDot == should || !isImmersiveIndicatorEnabled()) {
-            return
-        }
-
-        hasPersistentDot = should
-
-        if (!hasPersistentDot) {
-            clearDotIfVisible()
-        }
-    }
-
-    public fun isTooEarly(): Boolean {
-        return systemClock.uptimeMillis() - Process.getStartUptimeMillis() < MIN_UPTIME
-    }
-
-    /**
-     * Clear the scheduled event (if any) and schedule a new one
-     */
-    private fun scheduleEvent(event: StatusEvent) {
-        scheduledEvent = event
-
-        if (event.forceVisible) {
-            hasPersistentDot = true
-        }
-
-        // If animations are turned off, we'll transition directly to the dot
-        if (!event.showAnimation && event.forceVisible) {
-            notifyTransitionToPersistentDot()
-            scheduledEvent = null
-            return
-        }
-
-        chipAnimationController.prepareChipAnimation(scheduledEvent!!.viewCreator)
-        animationState = ANIMATION_QUEUED
-        executor.executeDelayed({
-            runChipAnimation()
-        }, DEBOUNCE_DELAY)
-    }
-
-    /**
-     * 1. Define a total budget for the chip animation (1500ms)
-     * 2. Send out callbacks to listeners so that they can generate animations locally
-     * 3. Update the scheduler state so that clients know where we are
-     * 4. Maybe: provide scaffolding such as: dot location, margins, etc
-     * 5. Maybe: define a maximum animation length and enforce it. Probably only doable if we
-     * collect all of the animators and run them together.
-     */
-    private fun runChipAnimation() {
-        statusBarWindowController.setForceStatusBarVisible(true)
-        animationState = ANIMATING_IN
-
-        val animSet = collectStartAnimations()
-        if (animSet.totalDuration > 500) {
-            throw IllegalStateException("System animation total length exceeds budget. " +
-                    "Expected: 500, actual: ${animSet.totalDuration}")
-        }
-        animSet.addListener(object : AnimatorListenerAdapter() {
-            override fun onAnimationEnd(animation: Animator?) {
-                animationState = RUNNING_CHIP_ANIM
-            }
-        })
-        animSet.start()
-
-        executor.executeDelayed({
-            val animSet2 = collectFinishAnimations()
-            animationState = ANIMATING_OUT
-            animSet2.addListener(object : AnimatorListenerAdapter() {
-                override fun onAnimationEnd(animation: Animator?) {
-                    animationState = if (hasPersistentDot) {
-                        SHOWING_PERSISTENT_DOT
-                    } else {
-                        IDLE
-                    }
-
-                    statusBarWindowController.setForceStatusBarVisible(false)
-                }
-            })
-            animSet2.start()
-            scheduledEvent = null
-        }, DISPLAY_LENGTH)
-    }
-
-    private fun collectStartAnimations(): AnimatorSet {
-        val animators = mutableListOf<Animator>()
-        listeners.forEach { listener ->
-            listener.onSystemEventAnimationBegin()?.let { anim ->
-                animators.add(anim)
-            }
-        }
-        animators.add(chipAnimationController.onSystemEventAnimationBegin())
-        val animSet = AnimatorSet().also {
-            it.playTogether(animators)
-        }
-
-        return animSet
-    }
-
-    private fun collectFinishAnimations(): AnimatorSet {
-        val animators = mutableListOf<Animator>()
-        listeners.forEach { listener ->
-            listener.onSystemEventAnimationFinish(hasPersistentDot)?.let { anim ->
-                animators.add(anim)
-            }
-        }
-        animators.add(chipAnimationController.onSystemEventAnimationFinish(hasPersistentDot))
-        if (hasPersistentDot) {
-            val dotAnim = notifyTransitionToPersistentDot()
-            if (dotAnim != null) {
-                animators.add(dotAnim)
-            }
-        }
-        val animSet = AnimatorSet().also {
-            it.playTogether(animators)
-        }
-
-        return animSet
-    }
-
-    private fun notifyTransitionToPersistentDot(): Animator? {
-        val anims: List<Animator> = listeners.mapNotNull {
-            it.onSystemStatusAnimationTransitionToPersistentDot(scheduledEvent?.contentDescription)
-        }
-        if (anims.isNotEmpty()) {
-            val aSet = AnimatorSet()
-            aSet.playTogether(anims)
-            return aSet
-        }
-
-        return null
-    }
-
-    private fun notifyHidePersistentDot(): Animator? {
-        val anims: List<Animator> = listeners.mapNotNull {
-            it.onHidePersistentDot()
-        }
-
-        if (animationState == SHOWING_PERSISTENT_DOT) {
-            animationState = IDLE
-        }
-
-        if (anims.isNotEmpty()) {
-            val aSet = AnimatorSet()
-            aSet.playTogether(anims)
-            return aSet
-        }
-
-        return null
-    }
-
-    override fun addCallback(listener: SystemStatusAnimationCallback) {
-        Assert.isMainThread()
-
-        if (listeners.isEmpty()) {
-            coordinator.startObserving()
-        }
-        listeners.add(listener)
-    }
-
-    override fun removeCallback(listener: SystemStatusAnimationCallback) {
-        Assert.isMainThread()
-
-        listeners.remove(listener)
-        if (listeners.isEmpty()) {
-            coordinator.stopObserving()
-        }
-    }
-
-    override fun dump(pw: PrintWriter, args: Array<out String>) {
-        pw.println("Scheduled event: $scheduledEvent")
-        pw.println("Has persistent privacy dot: $hasPersistentDot")
-        pw.println("Animation state: $animationState")
-        pw.println("Listeners:")
-        if (listeners.isEmpty()) {
-            pw.println("(none)")
-        } else {
-            listeners.forEach {
-                pw.println("  $it")
-            }
-        }
-    }
+    fun removePersistentDot()
 }
 
 /**
@@ -337,6 +56,7 @@
     @JvmDefault fun onHidePersistentDot(): Animator? { return null }
 }
 
+
 /**
  * Animation state IntDef
  */
@@ -354,7 +74,7 @@
 annotation class SystemAnimationState
 
 /** No animation is in progress */
-const val IDLE = 0
+@SystemAnimationState const val IDLE = 0
 /** An animation is queued, and awaiting the debounce period */
 const val ANIMATION_QUEUED = 1
 /** System is animating out, and chip is animating in */
@@ -379,20 +99,16 @@
 val STATUS_CHIP_HEIGHT_TO_DOT_KEYFRAME_2 = PathInterpolator(0.3f, 0f, 0f, 1f)
 val STATUS_CHIP_MOVE_TO_DOT = PathInterpolator(0f, 0f, 0.05f, 1f)
 
-private const val TAG = "SystemStatusAnimationScheduler"
-private const val DEBOUNCE_DELAY = 100L
+internal const val DEBOUNCE_DELAY = 100L
 
 /**
  * The total time spent on the chip animation is 1500ms, broken up into 3 sections:
- *   - 500ms to animate the chip in (including animating system icons away)
- *   - 500ms holding the chip on screen
- *   - 500ms to animate the chip away (and system icons back)
- *
- *   So DISPLAY_LENGTH should be the sum of the first 2 phases, while the final 500ms accounts for
- *   the actual animation
+ * - 500ms to animate the chip in (including animating system icons away)
+ * - 500ms holding the chip on screen
+ * - 500ms to animate the chip away (and system icons back)
  */
-private const val DISPLAY_LENGTH = 1000L
+internal const val APPEAR_ANIMATION_DURATION = 500L
+internal const val DISPLAY_LENGTH = 3000L
+internal const val DISAPPEAR_ANIMATION_DURATION = 500L
 
-private const val MIN_UPTIME: Long = 5 * 1000
-
-private const val DEBUG = false
+internal const val MIN_UPTIME: Long = 5 * 1000
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt
new file mode 100644
index 0000000..f7a4fea
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt
@@ -0,0 +1,425 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.events
+
+import android.os.Process
+import android.provider.DeviceConfig
+import android.util.Log
+import androidx.core.animation.Animator
+import androidx.core.animation.AnimatorListenerAdapter
+import androidx.core.animation.AnimatorSet
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.window.StatusBarWindowController
+import com.android.systemui.util.Assert
+import com.android.systemui.util.time.SystemClock
+import java.io.PrintWriter
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.FlowPreview
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.debounce
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withTimeout
+
+/**
+ * Scheduler for system status events. Obeys the following principles:
+ * ```
+ *      - Waits 100 ms to schedule any event for debouncing/prioritization
+ *      - Simple prioritization: Privacy > Battery > Connectivity (encoded in [StatusEvent])
+ *      - Only schedules a single event, and throws away lowest priority events
+ * ```
+ *
+ * There are 4 basic stages of animation at play here:
+ * ```
+ *      1. System chrome animation OUT
+ *      2. Chip animation IN
+ *      3. Chip animation OUT; potentially into a dot
+ *      4. System chrome animation IN
+ * ```
+ *
+ * Thus we can keep all animations synchronized with two separate ValueAnimators, one for system
+ * chrome and the other for the chip. These can animate from 0,1 and listeners can parameterize
+ * their respective views based on the progress of the animator.
+ */
+@OptIn(FlowPreview::class)
+open class SystemStatusAnimationSchedulerImpl
+@Inject
+constructor(
+    private val coordinator: SystemEventCoordinator,
+    private val chipAnimationController: SystemEventChipAnimationController,
+    private val statusBarWindowController: StatusBarWindowController,
+    dumpManager: DumpManager,
+    private val systemClock: SystemClock,
+    @Application private val coroutineScope: CoroutineScope
+) : SystemStatusAnimationScheduler {
+
+    companion object {
+        private const val PROPERTY_ENABLE_IMMERSIVE_INDICATOR = "enable_immersive_indicator"
+    }
+
+    /** Contains the StatusEvent that is going to be displayed next. */
+    private var scheduledEvent = MutableStateFlow<StatusEvent?>(null)
+
+    /**
+     * The currently displayed status event. (This is null in all states except ANIMATING_IN and
+     * CHIP_ANIMATION_RUNNING)
+     */
+    private var currentlyDisplayedEvent: StatusEvent? = null
+
+    /** StateFlow holding the current [SystemAnimationState] at any time. */
+    private var animationState = MutableStateFlow(IDLE)
+
+    /** True if the persistent privacy dot should be active */
+    var hasPersistentDot = false
+        protected set
+
+    /** Set of currently registered listeners */
+    protected val listeners = mutableSetOf<SystemStatusAnimationCallback>()
+
+    /** The job that is controlling the animators of the currently displayed status event. */
+    private var currentlyRunningAnimationJob: Job? = null
+
+    /** The job that is controlling the animators when an event is cancelled. */
+    private var eventCancellationJob: Job? = null
+
+    init {
+        coordinator.attachScheduler(this)
+        dumpManager.registerCriticalDumpable(TAG, this)
+
+        coroutineScope.launch {
+            // Wait for animationState to become ANIMATION_QUEUED and scheduledEvent to be non null.
+            // Once this combination is stable for at least DEBOUNCE_DELAY, then start a chip enter
+            // animation
+            animationState
+                .combine(scheduledEvent) { animationState, scheduledEvent ->
+                    Pair(animationState, scheduledEvent)
+                }
+                .debounce(DEBOUNCE_DELAY)
+                .collect { (animationState, event) ->
+                    if (animationState == ANIMATION_QUEUED && event != null) {
+                        startAnimationLifecycle(event)
+                        scheduledEvent.value = null
+                    }
+                }
+        }
+    }
+
+    @SystemAnimationState override fun getAnimationState(): Int = animationState.value
+
+    override fun onStatusEvent(event: StatusEvent) {
+        Assert.isMainThread()
+
+        // Ignore any updates until the system is up and running
+        if (isTooEarly() || !isImmersiveIndicatorEnabled()) {
+            return
+        }
+
+        if (
+            (event.priority > (scheduledEvent.value?.priority ?: -1)) &&
+                (event.priority > (currentlyDisplayedEvent?.priority ?: -1)) &&
+                !hasPersistentDot
+        ) {
+            // a event can only be scheduled if no other event is in progress or it has a higher
+            // priority. If a persistent dot is currently displayed, don't schedule the event.
+            if (DEBUG) {
+                Log.d(TAG, "scheduling event $event")
+            }
+
+            scheduleEvent(event)
+        } else if (currentlyDisplayedEvent?.shouldUpdateFromEvent(event) == true) {
+            if (DEBUG) {
+                Log.d(
+                    TAG,
+                    "updating current event from: $event. animationState=${animationState.value}"
+                )
+            }
+            currentlyDisplayedEvent?.updateFromEvent(event)
+        } else if (scheduledEvent.value?.shouldUpdateFromEvent(event) == true) {
+            if (DEBUG) {
+                Log.d(
+                    TAG,
+                    "updating scheduled event from: $event. animationState=${animationState.value}"
+                )
+            }
+            scheduledEvent.value?.updateFromEvent(event)
+        } else {
+            if (DEBUG) {
+                Log.d(TAG, "ignoring event $event")
+            }
+        }
+    }
+
+    override fun removePersistentDot() {
+        Assert.isMainThread()
+
+        // If there is an event scheduled currently, set its forceVisible flag to false, such that
+        // it will never transform into a persistent dot
+        scheduledEvent.value?.forceVisible = false
+
+        // Nothing else to do if hasPersistentDot is already false
+        if (!hasPersistentDot) return
+        // Set hasPersistentDot to false. If the animationState is anything before ANIMATING_OUT,
+        // the disappear animation will not animate into a dot but remove the chip entirely
+        hasPersistentDot = false
+        // if we are currently showing a persistent dot, hide it
+        if (animationState.value == SHOWING_PERSISTENT_DOT) notifyHidePersistentDot()
+        // if we are currently animating into a dot, wait for the animation to finish and then hide
+        // the dot
+        if (animationState.value == ANIMATING_OUT) {
+            coroutineScope.launch {
+                withTimeout(DISAPPEAR_ANIMATION_DURATION) {
+                    animationState.first { it == SHOWING_PERSISTENT_DOT || it == ANIMATION_QUEUED }
+                    notifyHidePersistentDot()
+                }
+            }
+        }
+    }
+
+    protected fun isTooEarly(): Boolean {
+        return systemClock.uptimeMillis() - Process.getStartUptimeMillis() < MIN_UPTIME
+    }
+
+    protected fun isImmersiveIndicatorEnabled(): Boolean {
+        return DeviceConfig.getBoolean(
+            DeviceConfig.NAMESPACE_PRIVACY,
+            PROPERTY_ENABLE_IMMERSIVE_INDICATOR,
+            true
+        )
+    }
+
+    /** Clear the scheduled event (if any) and schedule a new one */
+    private fun scheduleEvent(event: StatusEvent) {
+        scheduledEvent.value = event
+        if (currentlyDisplayedEvent != null && eventCancellationJob?.isActive != true) {
+            // cancel the currently displayed event. As soon as the event is animated out, the
+            // scheduled event will be displayed.
+            cancelCurrentlyDisplayedEvent()
+            return
+        }
+        if (animationState.value == IDLE) {
+            // If we are in IDLE state, set it to ANIMATION_QUEUED now
+            animationState.value = ANIMATION_QUEUED
+        }
+    }
+
+    /**
+     * Cancels the currently displayed event by animating it out. This function should only be
+     * called if the animationState is ANIMATING_IN or RUNNING_CHIP_ANIM, or in other words whenever
+     * currentlyRunningEvent is not null
+     */
+    private fun cancelCurrentlyDisplayedEvent() {
+        eventCancellationJob =
+            coroutineScope.launch {
+                withTimeout(APPEAR_ANIMATION_DURATION) {
+                    // wait for animationState to become RUNNING_CHIP_ANIM, then cancel the running
+                    // animation job and run the disappear animation immediately
+                    animationState.first { it == RUNNING_CHIP_ANIM }
+                    currentlyRunningAnimationJob?.cancel()
+                    runChipDisappearAnimation()
+                }
+            }
+    }
+
+    /**
+     * Takes the currently scheduled Event and (using the coroutineScope) animates it in and out
+     * again after displaying it for DISPLAY_LENGTH ms. This function should only be called if there
+     * is an event scheduled (and currentlyDisplayedEvent is null)
+     */
+    private fun startAnimationLifecycle(event: StatusEvent) {
+        Assert.isMainThread()
+        hasPersistentDot = event.forceVisible
+
+        if (!event.showAnimation && event.forceVisible) {
+            // If animations are turned off, we'll transition directly to the dot
+            animationState.value = SHOWING_PERSISTENT_DOT
+            notifyTransitionToPersistentDot()
+            return
+        }
+
+        currentlyDisplayedEvent = event
+
+        chipAnimationController.prepareChipAnimation(event.viewCreator)
+        currentlyRunningAnimationJob =
+            coroutineScope.launch {
+                runChipAppearAnimation()
+                delay(APPEAR_ANIMATION_DURATION + DISPLAY_LENGTH)
+                runChipDisappearAnimation()
+            }
+    }
+
+    /**
+     * 1. Define a total budget for the chip animation (1500ms)
+     * 2. Send out callbacks to listeners so that they can generate animations locally
+     * 3. Update the scheduler state so that clients know where we are
+     * 4. Maybe: provide scaffolding such as: dot location, margins, etc
+     * 5. Maybe: define a maximum animation length and enforce it. Probably only doable if we
+     *    collect all of the animators and run them together.
+     */
+    private fun runChipAppearAnimation() {
+        Assert.isMainThread()
+        if (hasPersistentDot) {
+            statusBarWindowController.setForceStatusBarVisible(true)
+        }
+        animationState.value = ANIMATING_IN
+
+        val animSet = collectStartAnimations()
+        if (animSet.totalDuration > 500) {
+            throw IllegalStateException(
+                "System animation total length exceeds budget. " +
+                    "Expected: 500, actual: ${animSet.totalDuration}"
+            )
+        }
+        animSet.addListener(
+            object : AnimatorListenerAdapter() {
+                override fun onAnimationEnd(animation: Animator) {
+                    animationState.value = RUNNING_CHIP_ANIM
+                }
+            }
+        )
+        animSet.start()
+    }
+
+    private fun runChipDisappearAnimation() {
+        Assert.isMainThread()
+        val animSet2 = collectFinishAnimations()
+        animationState.value = ANIMATING_OUT
+        animSet2.addListener(
+            object : AnimatorListenerAdapter() {
+                override fun onAnimationEnd(animation: Animator) {
+                    animationState.value =
+                        when {
+                            hasPersistentDot -> SHOWING_PERSISTENT_DOT
+                            scheduledEvent.value != null -> ANIMATION_QUEUED
+                            else -> IDLE
+                        }
+                    statusBarWindowController.setForceStatusBarVisible(false)
+                }
+            }
+        )
+        animSet2.start()
+
+        // currentlyDisplayedEvent is set to null before the animation has ended such that new
+        // events can be scheduled during the disappear animation. We don't want to miss e.g. a new
+        // privacy event being scheduled during the disappear animation, otherwise we could end up
+        // with e.g. an active microphone but no privacy dot being displayed.
+        currentlyDisplayedEvent = null
+    }
+
+    private fun collectStartAnimations(): AnimatorSet {
+        val animators = mutableListOf<Animator>()
+        listeners.forEach { listener ->
+            listener.onSystemEventAnimationBegin()?.let { anim -> animators.add(anim) }
+        }
+        animators.add(chipAnimationController.onSystemEventAnimationBegin())
+
+        return AnimatorSet().also { it.playTogether(animators) }
+    }
+
+    private fun collectFinishAnimations(): AnimatorSet {
+        val animators = mutableListOf<Animator>()
+        listeners.forEach { listener ->
+            listener.onSystemEventAnimationFinish(hasPersistentDot)?.let { anim ->
+                animators.add(anim)
+            }
+        }
+        animators.add(chipAnimationController.onSystemEventAnimationFinish(hasPersistentDot))
+        if (hasPersistentDot) {
+            val dotAnim = notifyTransitionToPersistentDot()
+            if (dotAnim != null) {
+                animators.add(dotAnim)
+            }
+        }
+
+        return AnimatorSet().also { it.playTogether(animators) }
+    }
+
+    private fun notifyTransitionToPersistentDot(): Animator? {
+        val anims: List<Animator> =
+            listeners.mapNotNull {
+                it.onSystemStatusAnimationTransitionToPersistentDot(
+                    currentlyDisplayedEvent?.contentDescription
+                )
+            }
+        if (anims.isNotEmpty()) {
+            val aSet = AnimatorSet()
+            aSet.playTogether(anims)
+            return aSet
+        }
+
+        return null
+    }
+
+    private fun notifyHidePersistentDot(): Animator? {
+        Assert.isMainThread()
+        val anims: List<Animator> = listeners.mapNotNull { it.onHidePersistentDot() }
+
+        if (animationState.value == SHOWING_PERSISTENT_DOT) {
+            if (scheduledEvent.value != null) {
+                animationState.value = ANIMATION_QUEUED
+            } else {
+                animationState.value = IDLE
+            }
+        }
+
+        if (anims.isNotEmpty()) {
+            val aSet = AnimatorSet()
+            aSet.playTogether(anims)
+            return aSet
+        }
+
+        return null
+    }
+
+    override fun addCallback(listener: SystemStatusAnimationCallback) {
+        Assert.isMainThread()
+
+        if (listeners.isEmpty()) {
+            coordinator.startObserving()
+        }
+        listeners.add(listener)
+    }
+
+    override fun removeCallback(listener: SystemStatusAnimationCallback) {
+        Assert.isMainThread()
+
+        listeners.remove(listener)
+        if (listeners.isEmpty()) {
+            coordinator.stopObserving()
+        }
+    }
+
+    override fun dump(pw: PrintWriter, args: Array<out String>) {
+        pw.println("Scheduled event: ${scheduledEvent.value}")
+        pw.println("Currently displayed event: $currentlyDisplayedEvent")
+        pw.println("Has persistent privacy dot: $hasPersistentDot")
+        pw.println("Animation state: ${animationState.value}")
+        pw.println("Listeners:")
+        if (listeners.isEmpty()) {
+            pw.println("(none)")
+        } else {
+            listeners.forEach { pw.println("  $it") }
+        }
+    }
+}
+
+private const val DEBUG = false
+private const val TAG = "SystemStatusAnimationSchedulerImpl"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerLegacyImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerLegacyImpl.kt
new file mode 100644
index 0000000..64b7ac9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerLegacyImpl.kt
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.events
+
+import android.os.Process
+import android.provider.DeviceConfig
+import android.util.Log
+import androidx.core.animation.Animator
+import androidx.core.animation.AnimatorListenerAdapter
+import androidx.core.animation.AnimatorSet
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.window.StatusBarWindowController
+import com.android.systemui.util.Assert
+import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.time.SystemClock
+import java.io.PrintWriter
+import javax.inject.Inject
+
+/**
+ * Dead-simple scheduler for system status events. Obeys the following principles (all values TBD):
+ * ```
+ *      - Avoiding log spam by only allowing 12 events per minute (1event/5s)
+ *      - Waits 100ms to schedule any event for debouncing/prioritization
+ *      - Simple prioritization: Privacy > Battery > connectivity (encoded in [StatusEvent])
+ *      - Only schedules a single event, and throws away lowest priority events
+ * ```
+ * There are 4 basic stages of animation at play here:
+ * ```
+ *      1. System chrome animation OUT
+ *      2. Chip animation IN
+ *      3. Chip animation OUT; potentially into a dot
+ *      4. System chrome animation IN
+ * ```
+ * Thus we can keep all animations synchronized with two separate ValueAnimators, one for system
+ * chrome and the other for the chip. These can animate from 0,1 and listeners can parameterize
+ * their respective views based on the progress of the animator. Interpolation differences TBD
+ */
+open class SystemStatusAnimationSchedulerLegacyImpl
+@Inject
+constructor(
+    private val coordinator: SystemEventCoordinator,
+    private val chipAnimationController: SystemEventChipAnimationController,
+    private val statusBarWindowController: StatusBarWindowController,
+    private val dumpManager: DumpManager,
+    private val systemClock: SystemClock,
+    @Main private val executor: DelayableExecutor
+) : SystemStatusAnimationScheduler {
+
+    companion object {
+        private const val PROPERTY_ENABLE_IMMERSIVE_INDICATOR = "enable_immersive_indicator"
+    }
+
+    fun isImmersiveIndicatorEnabled(): Boolean {
+        return DeviceConfig.getBoolean(
+            DeviceConfig.NAMESPACE_PRIVACY,
+            PROPERTY_ENABLE_IMMERSIVE_INDICATOR,
+            true
+        )
+    }
+
+    @SystemAnimationState private var animationState: Int = IDLE
+
+    /** True if the persistent privacy dot should be active */
+    var hasPersistentDot = false
+        protected set
+
+    private var scheduledEvent: StatusEvent? = null
+
+    val listeners = mutableSetOf<SystemStatusAnimationCallback>()
+
+    init {
+        coordinator.attachScheduler(this)
+        dumpManager.registerDumpable(TAG, this)
+    }
+
+    @SystemAnimationState override fun getAnimationState() = animationState
+
+    override fun onStatusEvent(event: StatusEvent) {
+        // Ignore any updates until the system is up and running
+        if (isTooEarly() || !isImmersiveIndicatorEnabled()) {
+            return
+        }
+
+        // Don't deal with threading for now (no need let's be honest)
+        Assert.isMainThread()
+        if (
+            (event.priority > (scheduledEvent?.priority ?: -1)) &&
+                animationState != ANIMATING_OUT &&
+                animationState != SHOWING_PERSISTENT_DOT
+        ) {
+            // events can only be scheduled if a higher priority or no other event is in progress
+            if (DEBUG) {
+                Log.d(TAG, "scheduling event $event")
+            }
+
+            scheduleEvent(event)
+        } else if (scheduledEvent?.shouldUpdateFromEvent(event) == true) {
+            if (DEBUG) {
+                Log.d(TAG, "updating current event from: $event. animationState=$animationState")
+            }
+            scheduledEvent?.updateFromEvent(event)
+            if (event.forceVisible) {
+                hasPersistentDot = true
+                // If we missed the chance to show the persistent dot, do it now
+                if (animationState == IDLE) {
+                    notifyTransitionToPersistentDot()
+                }
+            }
+        } else {
+            if (DEBUG) {
+                Log.d(TAG, "ignoring event $event")
+            }
+        }
+    }
+
+    override fun removePersistentDot() {
+        if (!hasPersistentDot || !isImmersiveIndicatorEnabled()) {
+            return
+        }
+
+        hasPersistentDot = false
+        notifyHidePersistentDot()
+        return
+    }
+
+    fun isTooEarly(): Boolean {
+        return systemClock.uptimeMillis() - Process.getStartUptimeMillis() < MIN_UPTIME
+    }
+
+    /** Clear the scheduled event (if any) and schedule a new one */
+    private fun scheduleEvent(event: StatusEvent) {
+        scheduledEvent = event
+
+        if (event.forceVisible) {
+            hasPersistentDot = true
+        }
+
+        // If animations are turned off, we'll transition directly to the dot
+        if (!event.showAnimation && event.forceVisible) {
+            notifyTransitionToPersistentDot()
+            scheduledEvent = null
+            return
+        }
+
+        chipAnimationController.prepareChipAnimation(scheduledEvent!!.viewCreator)
+        animationState = ANIMATION_QUEUED
+        executor.executeDelayed({ runChipAnimation() }, DEBOUNCE_DELAY)
+    }
+
+    /**
+     * 1. Define a total budget for the chip animation (1500ms)
+     * 2. Send out callbacks to listeners so that they can generate animations locally
+     * 3. Update the scheduler state so that clients know where we are
+     * 4. Maybe: provide scaffolding such as: dot location, margins, etc
+     * 5. Maybe: define a maximum animation length and enforce it. Probably only doable if we
+     * collect all of the animators and run them together.
+     */
+    private fun runChipAnimation() {
+        statusBarWindowController.setForceStatusBarVisible(true)
+        animationState = ANIMATING_IN
+
+        val animSet = collectStartAnimations()
+        if (animSet.totalDuration > 500) {
+            throw IllegalStateException(
+                "System animation total length exceeds budget. " +
+                    "Expected: 500, actual: ${animSet.totalDuration}"
+            )
+        }
+        animSet.addListener(
+            object : AnimatorListenerAdapter() {
+                override fun onAnimationEnd(animation: Animator) {
+                    animationState = RUNNING_CHIP_ANIM
+                }
+            }
+        )
+        animSet.start()
+
+        executor.executeDelayed(
+            {
+                val animSet2 = collectFinishAnimations()
+                animationState = ANIMATING_OUT
+                animSet2.addListener(
+                    object : AnimatorListenerAdapter() {
+                        override fun onAnimationEnd(animation: Animator) {
+                            animationState =
+                                if (hasPersistentDot) {
+                                    SHOWING_PERSISTENT_DOT
+                                } else {
+                                    IDLE
+                                }
+
+                            statusBarWindowController.setForceStatusBarVisible(false)
+                        }
+                    }
+                )
+                animSet2.start()
+                scheduledEvent = null
+            },
+            DISPLAY_LENGTH
+        )
+    }
+
+    private fun collectStartAnimations(): AnimatorSet {
+        val animators = mutableListOf<Animator>()
+        listeners.forEach { listener ->
+            listener.onSystemEventAnimationBegin()?.let { anim -> animators.add(anim) }
+        }
+        animators.add(chipAnimationController.onSystemEventAnimationBegin())
+        val animSet = AnimatorSet().also { it.playTogether(animators) }
+
+        return animSet
+    }
+
+    private fun collectFinishAnimations(): AnimatorSet {
+        val animators = mutableListOf<Animator>()
+        listeners.forEach { listener ->
+            listener.onSystemEventAnimationFinish(hasPersistentDot)?.let { anim ->
+                animators.add(anim)
+            }
+        }
+        animators.add(chipAnimationController.onSystemEventAnimationFinish(hasPersistentDot))
+        if (hasPersistentDot) {
+            val dotAnim = notifyTransitionToPersistentDot()
+            if (dotAnim != null) {
+                animators.add(dotAnim)
+            }
+        }
+        val animSet = AnimatorSet().also { it.playTogether(animators) }
+
+        return animSet
+    }
+
+    private fun notifyTransitionToPersistentDot(): Animator? {
+        val anims: List<Animator> =
+            listeners.mapNotNull {
+                it.onSystemStatusAnimationTransitionToPersistentDot(
+                    scheduledEvent?.contentDescription
+                )
+            }
+        if (anims.isNotEmpty()) {
+            val aSet = AnimatorSet()
+            aSet.playTogether(anims)
+            return aSet
+        }
+
+        return null
+    }
+
+    private fun notifyHidePersistentDot(): Animator? {
+        val anims: List<Animator> = listeners.mapNotNull { it.onHidePersistentDot() }
+
+        if (animationState == SHOWING_PERSISTENT_DOT) {
+            animationState = IDLE
+        }
+
+        if (anims.isNotEmpty()) {
+            val aSet = AnimatorSet()
+            aSet.playTogether(anims)
+            return aSet
+        }
+
+        return null
+    }
+
+    override fun addCallback(listener: SystemStatusAnimationCallback) {
+        Assert.isMainThread()
+
+        if (listeners.isEmpty()) {
+            coordinator.startObserving()
+        }
+        listeners.add(listener)
+    }
+
+    override fun removeCallback(listener: SystemStatusAnimationCallback) {
+        Assert.isMainThread()
+
+        listeners.remove(listener)
+        if (listeners.isEmpty()) {
+            coordinator.stopObserving()
+        }
+    }
+
+    override fun dump(pw: PrintWriter, args: Array<out String>) {
+        pw.println("Scheduled event: $scheduledEvent")
+        pw.println("Has persistent privacy dot: $hasPersistentDot")
+        pw.println("Animation state: $animationState")
+        pw.println("Listeners:")
+        if (listeners.isEmpty()) {
+            pw.println("(none)")
+        } else {
+            listeners.forEach { pw.println("  $it") }
+        }
+    }
+}
+
+private const val DEBUG = false
+private const val TAG = "SystemStatusAnimationSchedulerLegacyImpl"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
index 6ef6165..29510d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -52,18 +52,19 @@
 import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener
 import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceView
 import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.plugins.WeatherData
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.shared.regionsampling.RegionSampler
 import com.android.systemui.shared.regionsampling.UpdateColorCallback
 import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DATE_SMARTSPACE_DATA_PLUGIN
 import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.WEATHER_SMARTSPACE_DATA_PLUGIN
-import com.android.systemui.plugins.Weather
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
 import com.android.systemui.util.concurrency.Execution
 import com.android.systemui.util.settings.SecureSettings
+import com.android.systemui.util.time.SystemClock
 import java.io.PrintWriter
 import java.time.Instant
 import java.util.Optional
@@ -81,6 +82,7 @@
         private val smartspaceManager: SmartspaceManager,
         private val activityStarter: ActivityStarter,
         private val falsingManager: FalsingManager,
+        private val systemClock: SystemClock,
         private val secureSettings: SecureSettings,
         private val userTracker: UserTracker,
         private val contentResolver: ContentResolver,
@@ -152,6 +154,18 @@
 
         // The weather data plugin takes unfiltered targets and performs the filtering internally.
         weatherPlugin?.onTargetsAvailable(targets)
+        val now = Instant.ofEpochMilli(systemClock.currentTimeMillis())
+        val weatherTarget = targets.find { t ->
+            t.featureType == SmartspaceTarget.FEATURE_WEATHER &&
+                    now.isAfter(Instant.ofEpochMilli(t.creationTimeMillis)) &&
+                    now.isBefore(Instant.ofEpochMilli(t.expiryTimeMillis))
+        }
+        if (weatherTarget != null) {
+            val weatherData = WeatherData.fromBundle(weatherTarget.baseAction.extras)
+            if (weatherData != null) {
+                keyguardUpdateMonitor.sendWeatherData(weatherData)
+            }
+        }
 
         val filteredTargets = targets.filter(::filterSmartspaceTarget)
         plugin?.onTargetsAvailable(filteredTargets)
@@ -173,17 +187,6 @@
             }
             isContentUpdatedOnce = true
         }
-
-        val now = Instant.now()
-        val weatherTarget = targets.find { t ->
-            t.featureType == SmartspaceTarget.FEATURE_WEATHER &&
-                    now.isAfter(Instant.ofEpochMilli(t.creationTimeMillis)) &&
-                    now.isBefore(Instant.ofEpochMilli(t.expiryTimeMillis))
-        }
-        if (weatherTarget != null) {
-            val weatherData = Weather.fromBundle(weatherTarget.baseAction.extras)
-            keyguardUpdateMonitor.sendWeatherData(weatherData)
-        }
     }
 
     private val userTrackerCallback = object : UserTracker.Callback {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt
index 4464531..88d9ffc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt
@@ -13,7 +13,7 @@
 
 package com.android.systemui.statusbar.notification
 
-import com.android.systemui.log.dagger.NotificationLog
+import com.android.systemui.log.dagger.NotificationLockscreenLog
 import com.android.systemui.plugins.log.LogBuffer
 import com.android.systemui.plugins.log.LogLevel.DEBUG
 import com.android.systemui.statusbar.StatusBarState
@@ -21,7 +21,12 @@
 
 class NotificationWakeUpCoordinatorLogger
 @Inject
-constructor(@NotificationLog private val buffer: LogBuffer) {
+constructor(@NotificationLockscreenLog private val buffer: LogBuffer) {
+    private var lastSetDozeAmountLogWasFractional = false
+    private var lastSetDozeAmountLogState = -1
+    private var lastSetDozeAmountLogSource = "undefined"
+    private var lastOnDozeAmountChangedLogWasFractional = false
+
     fun logSetDozeAmount(
         linear: Float,
         eased: Float,
@@ -29,6 +34,20 @@
         state: Int,
         changed: Boolean,
     ) {
+        // Avoid logging on every frame of the animation if important values are not changing
+        val isFractional = linear != 1f && linear != 0f
+        if (
+            lastSetDozeAmountLogWasFractional &&
+                isFractional &&
+                lastSetDozeAmountLogState == state &&
+                lastSetDozeAmountLogSource == source
+        ) {
+            return
+        }
+        lastSetDozeAmountLogWasFractional = isFractional
+        lastSetDozeAmountLogState = state
+        lastSetDozeAmountLogSource = source
+
         buffer.log(
             TAG,
             DEBUG,
@@ -66,6 +85,10 @@
     }
 
     fun logOnDozeAmountChanged(linear: Float, eased: Float) {
+        // Avoid logging on every frame of the animation when values are fractional
+        val isFractional = linear != 1f && linear != 0f
+        if (lastOnDozeAmountChangedLogWasFractional && isFractional) return
+        lastOnDozeAmountChangedLogWasFractional = isFractional
         buffer.log(
             TAG,
             DEBUG,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
index df35c9e..aa9a6c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
@@ -164,6 +164,11 @@
 
 
     private Queue<NotifEvent> mEventQueue = new ArrayDeque<>();
+    private final Runnable mRebuildListRunnable = () -> {
+        if (mBuildListener != null) {
+            mBuildListener.onBuildList(mReadOnlyNotificationSet, "asynchronousUpdate");
+        }
+    };
 
     private boolean mAttached = false;
     private boolean mAmDispatchingToOtherCode;
@@ -458,7 +463,7 @@
             int modificationType) {
         Assert.isMainThread();
         mEventQueue.add(new ChannelChangedEvent(pkgName, user, channel, modificationType));
-        dispatchEventsAndRebuildList("onNotificationChannelModified");
+        dispatchEventsAndAsynchronouslyRebuildList();
     }
 
     private void onNotificationsInitialized() {
@@ -613,15 +618,39 @@
 
     private void dispatchEventsAndRebuildList(String reason) {
         Trace.beginSection("NotifCollection.dispatchEventsAndRebuildList");
+        if (mMainHandler.hasCallbacks(mRebuildListRunnable)) {
+            mMainHandler.removeCallbacks(mRebuildListRunnable);
+        }
+
+        dispatchEvents();
+
+        if (mBuildListener != null) {
+            mBuildListener.onBuildList(mReadOnlyNotificationSet, reason);
+        }
+        Trace.endSection();
+    }
+
+    private void dispatchEventsAndAsynchronouslyRebuildList() {
+        Trace.beginSection("NotifCollection.dispatchEventsAndAsynchronouslyRebuildList");
+
+        dispatchEvents();
+
+        if (!mMainHandler.hasCallbacks(mRebuildListRunnable)) {
+            mMainHandler.postDelayed(mRebuildListRunnable, 1000L);
+        }
+
+        Trace.endSection();
+    }
+
+    private void dispatchEvents() {
+        Trace.beginSection("NotifCollection.dispatchEvents");
+
         mAmDispatchingToOtherCode = true;
         while (!mEventQueue.isEmpty()) {
             mEventQueue.remove().dispatchTo(mNotifCollectionListeners);
         }
         mAmDispatchingToOtherCode = false;
 
-        if (mBuildListener != null) {
-            mBuildListener.onBuildList(mReadOnlyNotificationSet, reason);
-        }
         Trace.endSection();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLogger.kt
index cc1103d..abe0670 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLogger.kt
@@ -20,6 +20,7 @@
 import android.app.StatsManager
 import android.util.Log
 import android.util.StatsEvent
+import androidx.annotation.VisibleForTesting
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
@@ -143,67 +144,70 @@
         runBlocking(mainDispatcher) {
             traceSection("NML#getNotifications") { notificationPipeline.allNotifs }
         }
-
-    /** Aggregates memory usage data by package and style, returning sums. */
-    private fun aggregateMemoryUsageData(
-        notificationMemoryUse: List<NotificationMemoryUsage>
-    ): Map<Pair<String, Int>, NotificationMemoryUseAtomBuilder> {
-        return notificationMemoryUse
-            .groupingBy { Pair(it.packageName, it.objectUsage.style) }
-            .aggregate {
-                _,
-                accumulator: NotificationMemoryUseAtomBuilder?,
-                element: NotificationMemoryUsage,
-                first ->
-                val use =
-                    if (first) {
-                        NotificationMemoryUseAtomBuilder(element.uid, element.objectUsage.style)
-                    } else {
-                        accumulator!!
-                    }
-
-                use.count++
-                // If the views of the notification weren't inflated, the list of memory usage
-                // parameters will be empty.
-                if (element.viewUsage.isNotEmpty()) {
-                    use.countWithInflatedViews++
-                }
-
-                use.smallIconObject += element.objectUsage.smallIcon
-                if (element.objectUsage.smallIcon > 0) {
-                    use.smallIconBitmapCount++
-                }
-
-                use.largeIconObject += element.objectUsage.largeIcon
-                if (element.objectUsage.largeIcon > 0) {
-                    use.largeIconBitmapCount++
-                }
-
-                use.bigPictureObject += element.objectUsage.bigPicture
-                if (element.objectUsage.bigPicture > 0) {
-                    use.bigPictureBitmapCount++
-                }
-
-                use.extras += element.objectUsage.extras
-                use.extenders += element.objectUsage.extender
-
-                // Use totals count which are more accurate when aggregated
-                // in this manner.
-                element.viewUsage
-                    .firstOrNull { vu -> vu.viewType == ViewType.TOTAL }
-                    ?.let {
-                        use.smallIconViews += it.smallIcon
-                        use.largeIconViews += it.largeIcon
-                        use.systemIconViews += it.systemIcons
-                        use.styleViews += it.style
-                        use.customViews += it.style
-                        use.softwareBitmaps += it.softwareBitmapsPenalty
-                    }
-
-                return@aggregate use
-            }
-    }
-
-    /** Rounds the passed value to the nearest KB - e.g. 700B rounds to 1KB. */
-    private fun toKb(value: Int): Int = (value.toFloat() / 1024f).roundToInt()
 }
+
+/** Aggregates memory usage data by package and style, returning sums. */
+@VisibleForTesting
+internal fun aggregateMemoryUsageData(
+    notificationMemoryUse: List<NotificationMemoryUsage>
+): Map<Pair<String, Int>, NotificationMemoryLogger.NotificationMemoryUseAtomBuilder> {
+    return notificationMemoryUse
+        .groupingBy { Pair(it.packageName, it.objectUsage.style) }
+        .aggregate {
+            _,
+            accumulator: NotificationMemoryLogger.NotificationMemoryUseAtomBuilder?,
+            element: NotificationMemoryUsage,
+            first ->
+            val use =
+                if (first) {
+                    NotificationMemoryLogger.NotificationMemoryUseAtomBuilder(
+                        element.uid,
+                        element.objectUsage.style
+                    )
+                } else {
+                    accumulator!!
+                }
+
+            use.count++
+            // If the views of the notification weren't inflated, the list of memory usage
+            // parameters will be empty.
+            if (element.viewUsage.isNotEmpty()) {
+                use.countWithInflatedViews++
+            }
+
+            use.smallIconObject += element.objectUsage.smallIcon
+            if (element.objectUsage.smallIcon > 0) {
+                use.smallIconBitmapCount++
+            }
+
+            use.largeIconObject += element.objectUsage.largeIcon
+            if (element.objectUsage.largeIcon > 0) {
+                use.largeIconBitmapCount++
+            }
+
+            use.bigPictureObject += element.objectUsage.bigPicture
+            if (element.objectUsage.bigPicture > 0) {
+                use.bigPictureBitmapCount++
+            }
+
+            use.extras += element.objectUsage.extras
+            use.extenders += element.objectUsage.extender
+
+            // Use totals count which are more accurate when aggregated
+            // in this manner.
+            element.viewUsage
+                .firstOrNull { vu -> vu.viewType == ViewType.TOTAL }
+                ?.let {
+                    use.smallIconViews += it.smallIcon
+                    use.largeIconViews += it.largeIcon
+                    use.systemIconViews += it.systemIcons
+                    use.styleViews += it.style
+                    use.customViews += it.customViews
+                    use.softwareBitmaps += it.softwareBitmapsPenalty
+                }
+
+            return@aggregate use
+        }
+}
+/** Rounds the passed value to the nearest KB - e.g. 700B rounds to 1KB. */
+private fun toKb(value: Int): Int = (value.toFloat() / 1024f).roundToInt()
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 9275e2b..64c1a59 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
@@ -1196,6 +1196,22 @@
         return getShowingLayout().getVisibleWrapper();
     }
 
+    /**
+     * @return whether the notification row is long clickable or not.
+     */
+    public boolean isNotificationRowLongClickable() {
+        if (mLongPressListener == null) {
+            return false;
+        }
+
+        if (!areGutsExposed()) { // guts is not opened
+            return true;
+        }
+
+        // if it is leave behind, it shouldn't be long clickable.
+        return !isGutsLeaveBehind();
+    }
+
     public void setLongPressListener(LongPressListener longPressListener) {
         mLongPressListener = longPressListener;
     }
@@ -2947,6 +2963,10 @@
         return (mGuts != null && mGuts.isExposed());
     }
 
+    private boolean isGutsLeaveBehind() {
+        return (mGuts != null && mGuts.isLeavebehind());
+    }
+
     @Override
     public boolean isContentExpandable() {
         if (mIsSummaryWithChildren && !shouldShowPublic()) {
@@ -3394,7 +3414,12 @@
     @Override
     public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfoInternal(info);
-        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK);
+        final boolean isLongClickable = isNotificationRowLongClickable();
+        if (isLongClickable) {
+            info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK);
+        }
+        info.setLongClickable(isLongClickable);
+
         if (canViewBeDismissed() && !mIsSnoozed) {
             info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
index 21f4cb5..49f17b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
@@ -88,6 +88,7 @@
         mSeenNotifsFooterTextView = findViewById(R.id.unlock_prompt_footer);
         updateResources();
         updateText();
+        updateColors();
     }
 
     public void setFooterLabelTextAndIcon(@StringRes int text, @DrawableRes int icon) {
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 37ff11d..06d4080 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
@@ -586,7 +586,9 @@
         }
 
         final ExpandableNotificationRow row = (ExpandableNotificationRow) view;
-        view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+        if (row.isNotificationRowLongClickable()) {
+            view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+        }
         if (row.areGutsExposed()) {
             closeAndSaveGuts(false /* removeLeavebehind */, false /* force */,
                     true /* removeControls */, -1 /* x */, -1 /* y */,
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 1fb7eb5..d2087ba6 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
@@ -16,7 +16,7 @@
 
 package com.android.systemui.statusbar.notification.stack;
 
-import static android.os.Trace.TRACE_TAG_ALWAYS;
+import static android.os.Trace.TRACE_TAG_APP;
 
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_SCROLL_FLING;
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_SHADE_CLEAR_ALL;
@@ -1121,7 +1121,7 @@
 
     @Override
     public void requestLayout() {
-        Trace.instant(TRACE_TAG_ALWAYS, "NotificationStackScrollLayout#requestLayout");
+        Trace.instant(TRACE_TAG_APP, "NotificationStackScrollLayout#requestLayout");
         super.requestLayout();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
index aaf9300..c6f56d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
@@ -251,13 +251,13 @@
                 || (isFastNonDismissGesture && isAbleToShowMenu);
         int menuSnapTarget = menuRow.getMenuSnapTarget();
         boolean isNonFalseMenuRevealingGesture =
-                !isFalseGesture() && isMenuRevealingGestureAwayFromMenu;
+                isMenuRevealingGestureAwayFromMenu && !isFalseGesture();
         if ((isNonDismissGestureTowardsMenu || isNonFalseMenuRevealingGesture)
                 && menuSnapTarget != 0) {
             // Menu has not been snapped to previously and this is menu revealing gesture
             snapOpen(animView, menuSnapTarget, velocity);
             menuRow.onSnapOpen();
-        } else if (isDismissGesture(ev) && !gestureTowardsMenu) {
+        } else if (isDismissGesture && !gestureTowardsMenu) {
             dismiss(animView, velocity);
             menuRow.onDismiss();
         } else {
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 3170f34..a425792 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
@@ -894,20 +894,19 @@
         ExpandableViewState childViewState = child.getViewState();
         float baseZ = ambientState.getBaseZHeight();
 
-        // Handles HUN shadow when Shade is opened
-
         if (child.mustStayOnScreen() && !childViewState.headsUpIsVisible
                 && !ambientState.isDozingAndNotPulsing(child)
                 && childViewState.getYTranslation() < ambientState.getTopPadding()
                 + ambientState.getStackTranslation()) {
-            // Handles HUN shadow when Shade is opened, and AmbientState.mScrollY > 0
-            // Calculate the HUN's z-value based on its overlapping fraction with QQS Panel.
-            // When scrolling down shade to make HUN back to in-position in Notification Panel,
-            // The over-lapping fraction goes to 0, and shadows hides gradually.
+
             if (childrenOnTop != 0.0f) {
-                // To elevate the later HUN over previous HUN
+                // To elevate the later HUN over previous HUN when multiple HUNs exist
                 childrenOnTop++;
             } else {
+                // Handles HUN shadow when Shade is opened, and AmbientState.mScrollY > 0
+                // Calculate the HUN's z-value based on its overlapping fraction with QQS Panel.
+                // When scrolling down shade to make HUN back to in-position in Notification Panel,
+                // The overlapping fraction goes to 0, and shadows hides gradually.
                 float overlap = ambientState.getTopPadding()
                         + ambientState.getStackTranslation() - childViewState.getYTranslation();
                 // To prevent over-shadow during HUN entry
@@ -915,7 +914,6 @@
                         1.0f,
                         overlap / childViewState.height
                 );
-                MathUtils.saturate(childrenOnTop);
             }
             childViewState.setZTranslation(baseZ
                     + childrenOnTop * mPinnedZTranslationExtra);
@@ -945,7 +943,6 @@
             childViewState.setZTranslation(baseZ);
         }
 
-        // Handles HUN shadow when shade is closed.
         // While HUN is showing and Shade is closed: headerVisibleAmount stays 0, shadow stays.
         // During HUN-to-Shade (eg. dragging down HUN to open Shade): headerVisibleAmount goes
         // gradually from 0 to 1, shadow hides gradually.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 576df7a..f6d53b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -31,7 +31,7 @@
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.qs.AutoAddTracker;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.ReduceBrightColorsController;
 import com.android.systemui.qs.SettingObserver;
 import com.android.systemui.qs.external.CustomTile;
@@ -75,7 +75,7 @@
     private final String mSafetySpec;
 
     protected final Context mContext;
-    protected final QSTileHost mHost;
+    protected final QSHost mHost;
     protected final Handler mHandler;
     protected final SecureSettings mSecureSettings;
     protected final AutoAddTracker mAutoTracker;
@@ -92,7 +92,7 @@
     private final ArrayList<AutoAddSetting> mAutoAddSettingList = new ArrayList<>();
 
     public AutoTileManager(Context context, AutoAddTracker.Builder autoAddTrackerBuilder,
-            QSTileHost host,
+            QSHost host,
             @Background Handler handler,
             SecureSettings secureSettings,
             HotspotController hotspotController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index 4d0ad40..311728f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -372,8 +372,6 @@
     void fadeKeyguardAfterLaunchTransition(Runnable beforeFading,
             Runnable endRunnable, Runnable cancelRunnable);
 
-    void animateKeyguardUnoccluding();
-
     void startLaunchTransitionTimeout();
 
     boolean hideKeyguardImpl(boolean forceStateChange);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
index ccde3c2..df850ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -53,10 +53,12 @@
 import com.android.systemui.dagger.qualifiers.DisplayId;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.QSPanelController;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.CameraLauncher;
 import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.QuickSettingsController;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DisableFlagsLogger;
@@ -104,6 +106,8 @@
     private final VibrationEffect mCameraLaunchGestureVibrationEffect;
     private final SystemBarAttributesListener mSystemBarAttributesListener;
     private final Lazy<CameraLauncher> mCameraLauncherLazy;
+    private final QuickSettingsController mQsController;
+    private final QSHost mQSHost;
 
     private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES =
             VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK);
@@ -111,6 +115,7 @@
     @Inject
     CentralSurfacesCommandQueueCallbacks(
             CentralSurfaces centralSurfaces,
+            QuickSettingsController quickSettingsController,
             Context context,
             @Main Resources resources,
             ShadeController shadeController,
@@ -135,8 +140,10 @@
             @DisplayId int displayId,
             SystemBarAttributesListener systemBarAttributesListener,
             Lazy<CameraLauncher> cameraLauncherLazy,
-            UserTracker userTracker) {
+            UserTracker userTracker,
+            QSHost qsHost) {
         mCentralSurfaces = centralSurfaces;
+        mQsController = quickSettingsController;
         mContext = context;
         mShadeController = shadeController;
         mCommandQueue = commandQueue;
@@ -160,6 +167,7 @@
         mDisplayId = displayId;
         mCameraLauncherLazy = cameraLauncherLazy;
         mUserTracker = userTracker;
+        mQSHost = qsHost;
 
         mVibrateOnOpening = resources.getBoolean(R.bool.config_vibrateOnIconAnimation);
         mCameraLaunchGestureVibrationEffect = getCameraGestureVibrationEffect(
@@ -180,22 +188,17 @@
 
     @Override
     public void addQsTile(ComponentName tile) {
-        QSPanelController qsPanelController = mCentralSurfaces.getQSPanelController();
-        if (qsPanelController != null && qsPanelController.getHost() != null) {
-            qsPanelController.getHost().addTile(tile);
-        }
+        mQSHost.addTile(tile);
     }
 
     @Override
     public void remQsTile(ComponentName tile) {
-        QSPanelController qsPanelController = mCentralSurfaces.getQSPanelController();
-        if (qsPanelController != null && qsPanelController.getHost() != null) {
-            qsPanelController.getHost().removeTileByUser(tile);
-        }
+        mQSHost.removeTileByUser(tile);
     }
 
     @Override
     public void clickTile(ComponentName tile) {
+        // Can't inject this because it changes with the QS fragment
         QSPanelController qsPanelController = mCentralSurfaces.getQSPanelController();
         if (qsPanelController != null) {
             qsPanelController.clickTile(tile);
@@ -334,9 +337,9 @@
                 mNotificationStackScrollLayoutController.setWillExpand(true);
                 mHeadsUpManager.unpinAll(true /* userUnpinned */);
                 mMetricsLogger.count("panel_open", 1);
-            } else if (!mNotificationPanelViewController.isInSettings()
+            } else if (!mQsController.getExpanded()
                     && !mNotificationPanelViewController.isExpanding()) {
-                mNotificationPanelViewController.flingSettings(0 /* velocity */,
+                mQsController.flingQs(0 /* velocity */,
                         NotificationPanelViewController.FLING_EXPAND);
                 mMetricsLogger.count("panel_open_qs", 1);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 85399ca..f0891f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -185,6 +185,7 @@
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.shade.NotificationShadeWindowViewController;
+import com.android.systemui.shade.QuickSettingsController;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.shade.ShadeExpansionChangeEvent;
 import com.android.systemui.shade.ShadeExpansionStateManager;
@@ -488,6 +489,8 @@
 
     // settings
     private QSPanelController mQSPanelController;
+    @VisibleForTesting
+    QuickSettingsController mQsController;
 
     KeyguardIndicationController mKeyguardIndicationController;
 
@@ -1419,7 +1422,7 @@
                 || isOccluded()
                 || !mKeyguardStateController.canDismissLockScreen()
                 || mKeyguardViewMediator.isAnySimPinSecure()
-                || (mNotificationPanelViewController.isQsExpanded() && trackingTouch)
+                || (mQsController.getExpanded() && trackingTouch)
                 || mNotificationPanelViewController.getBarState() == StatusBarState.SHADE_LOCKED) {
             return;
         }
@@ -1580,6 +1583,7 @@
         mCentralSurfacesComponent.getLockIconViewController().init();
         mStackScrollerController =
                 mCentralSurfacesComponent.getNotificationStackScrollLayoutController();
+        mQsController = mCentralSurfacesComponent.getQuickSettingsController();
         mStackScroller = mStackScrollerController.getView();
         mNotifListContainer = mCentralSurfacesComponent.getNotificationListContainer();
         mPresenter = mCentralSurfacesComponent.getNotificationPresenter();
@@ -1699,7 +1703,7 @@
                 && !isShadeDisabled()
                 && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0)
                 && !mDozing;
-        mNotificationPanelViewController.setQsExpansionEnabledPolicy(expandEnabled);
+        mQsController.setExpansionEnabledPolicy(expandEnabled);
         Log.d(TAG, "updateQsExpansionEnabled - QS Expand enabled: " + expandEnabled);
     }
 
@@ -2980,16 +2984,6 @@
     }
 
     /**
-     * Plays the animation when an activity that was occluding Keyguard goes away.
-     */
-    @Override
-    public void animateKeyguardUnoccluding() {
-        mNotificationPanelViewController.setExpandedFraction(0f);
-        mCommandQueueCallbacks.animateExpandNotificationsPanel();
-        mScrimController.setUnocclusionAnimationRunning(true);
-    }
-
-    /**
      * Starts the timeout when we try to start the affordances on Keyguard. We usually rely that
      * Keyguard goes away via fadeKeyguardAfterLaunchTransition, however, that might not happen
      * because the launched app crashed or something else went wrong.
@@ -3234,12 +3228,12 @@
             mStatusBarKeyguardViewManager.onBackPressed();
             return true;
         }
-        if (mNotificationPanelViewController.isQsCustomizing()) {
-            mNotificationPanelViewController.closeQsCustomizer();
+        if (mQsController.isCustomizing()) {
+            mQsController.closeQsCustomizer();
             return true;
         }
-        if (mNotificationPanelViewController.isQsExpanded()) {
-                mNotificationPanelViewController.animateCloseQs(false /* animateAway */);
+        if (mQsController.getExpanded()) {
+            mNotificationPanelViewController.animateCloseQs(false);
             return true;
         }
         if (mNotificationPanelViewController.closeUserSwitcherIfOpen()) {
@@ -3600,7 +3594,7 @@
             mFalsingCollector.onScreenOff();
             mScrimController.onScreenTurnedOff();
             if (mCloseQsBeforeScreenOff) {
-                mNotificationPanelViewController.closeQs();
+                mQsController.closeQs();
                 mCloseQsBeforeScreenOff = false;
             }
             updateIsKeyguard();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index cba0897..753032c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -21,9 +21,6 @@
 
 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
@@ -36,13 +33,16 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
+import androidx.core.animation.Animator;
+import androidx.core.animation.AnimatorListenerAdapter;
+import androidx.core.animation.ValueAnimator;
 
 import com.android.keyguard.CarrierTextController;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.logging.KeyguardLogger;
 import com.android.systemui.R;
-import com.android.systemui.animation.Interpolators;
+import com.android.systemui.animation.InterpolatorsAndroidX;
 import com.android.systemui.battery.BatteryMeterViewController;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.log.LogLevel;
@@ -166,7 +166,8 @@
 
     private final ValueAnimator.AnimatorUpdateListener mAnimatorUpdateListener =
             animation -> {
-                mKeyguardStatusBarAnimateAlpha = (float) animation.getAnimatedValue();
+                mKeyguardStatusBarAnimateAlpha =
+                        (float) ((ValueAnimator) animation).getAnimatedValue();
                 updateViewState();
             };
 
@@ -434,7 +435,7 @@
         ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
         anim.addUpdateListener(mAnimatorUpdateListener);
         anim.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
-        anim.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
+        anim.setInterpolator(InterpolatorsAndroidX.LINEAR_OUT_SLOW_IN);
         anim.start();
     }
 
@@ -445,7 +446,7 @@
         anim.addUpdateListener(mAnimatorUpdateListener);
         anim.setStartDelay(startDelay);
         anim.setDuration(duration);
-        anim.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
+        anim.setInterpolator(InterpolatorsAndroidX.LINEAR_OUT_SLOW_IN);
         anim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
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 80093a3..8e0ec284 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -138,26 +138,12 @@
     private boolean mTransitioningToFullShade;
 
     /**
-     * Is there currently an unocclusion animation running. Used to avoid bright flickers
-     * of the notification scrim.
-     */
-    private boolean mUnOcclusionAnimationRunning;
-
-    /**
      * The percentage of the bouncer which is hidden. If 1, the bouncer is completely hidden. If
      * 0, the bouncer is visible.
      */
     @FloatRange(from = 0, to = 1)
     private float mBouncerHiddenFraction = KeyguardBouncerConstants.EXPANSION_HIDDEN;
 
-    /**
-     * Set whether an unocclusion animation is currently running on the notification panel. Used
-     * to avoid bright flickers of the notification scrim.
-     */
-    public void setUnocclusionAnimationRunning(boolean unocclusionAnimationRunning) {
-        mUnOcclusionAnimationRunning = unocclusionAnimationRunning;
-    }
-
     @IntDef(prefix = {"VISIBILITY_"}, value = {
             TRANSPARENT,
             SEMI_TRANSPARENT,
@@ -532,10 +518,6 @@
         }
     }
 
-    public void onExpandingFinished() {
-        setUnocclusionAnimationRunning(false);
-    }
-
     @VisibleForTesting
     protected void onHideWallpaperTimeout() {
         if (mState != ScrimState.AOD && mState != ScrimState.PULSING) {
@@ -875,13 +857,6 @@
             if (mKeyguardOccluded || hideNotificationScrim) {
                 mNotificationsAlpha = 0;
             }
-            if (mUnOcclusionAnimationRunning && mState == ScrimState.KEYGUARD) {
-                // We're unoccluding the keyguard and don't want to have a bright flash.
-                mNotificationsAlpha = ScrimState.KEYGUARD.getNotifAlpha();
-                mNotificationsTint = ScrimState.KEYGUARD.getNotifTint();
-                mBehindAlpha = ScrimState.KEYGUARD.getBehindAlpha();
-                mBehindTint = ScrimState.KEYGUARD.getBehindTint();
-            }
         }
         if (mState != ScrimState.UNLOCKED) {
             mAnimatingPanelExpansionOnUnlock = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 39281da..3c32131 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -66,6 +66,7 @@
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
 import com.android.systemui.navigationbar.NavigationBarView;
 import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.TaskbarDelegate;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.ShadeController;
@@ -279,7 +280,6 @@
     private boolean mLastScreenOffAnimationPlaying;
     private float mQsExpansion;
     final Set<KeyguardViewManagerCallback> mCallbacks = new HashSet<>();
-    private boolean mIsUnoccludeTransitionFlagEnabled;
     private boolean mIsModernAlternateBouncerEnabled;
     private boolean mIsBackAnimationEnabled;
 
@@ -300,6 +300,7 @@
     @Nullable private KeyguardBypassController mBypassController;
     @Nullable private OccludingAppBiometricUI mOccludingAppBiometricUI;
 
+    @Nullable private TaskbarDelegate mTaskbarDelegate;
     private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
             new KeyguardUpdateMonitorCallback() {
         @Override
@@ -357,7 +358,6 @@
         mPrimaryBouncerView = primaryBouncerView;
         mFoldAodAnimationController = sysUIUnfoldComponent
                 .map(SysUIUnfoldComponent::getFoldAodAnimationController).orElse(null);
-        mIsUnoccludeTransitionFlagEnabled = featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION);
         mIsModernAlternateBouncerEnabled = featureFlags.isEnabled(Flags.MODERN_ALTERNATE_BOUNCER);
         mAlternateBouncerInteractor = alternateBouncerInteractor;
         mIsBackAnimationEnabled =
@@ -564,6 +564,10 @@
         updateStates();
     }
 
+    public void setTaskbarDelegate(TaskbarDelegate taskbarDelegate) {
+        mTaskbarDelegate = taskbarDelegate;
+    }
+
     /**
      * Show the keyguard.  Will handle creating and attaching to the view manager
      * lazily.
@@ -790,7 +794,7 @@
 
     @Override
     public void onFinishedGoingToSleep() {
-        mPrimaryBouncerInteractor.onScreenTurnedOff();
+        mPrimaryBouncerInteractor.hide();
     }
 
     @Override
@@ -874,11 +878,6 @@
             // by a FLAG_DISMISS_KEYGUARD_ACTIVITY.
             reset(isOccluding /* hideBouncerWhenShowing*/);
         }
-        if (!mIsUnoccludeTransitionFlagEnabled) {
-            if (animate && !isOccluded && isShowing && !primaryBouncerIsShowing()) {
-                mCentralSurfaces.animateKeyguardUnoccluding();
-            }
-        }
     }
 
     @Override
@@ -1194,7 +1193,8 @@
      * Updates the visibility of the nav bar window (which will cause insets changes).
      */
     protected void updateNavigationBarVisibility(boolean navBarVisible) {
-        if (mCentralSurfaces.getNavigationBarView() != null) {
+        if (mCentralSurfaces.getNavigationBarView() != null
+                || (mTaskbarDelegate != null && mTaskbarDelegate.isInitialized())) {
             if (navBarVisible) {
                 long delay = getNavBarShowDelay();
                 if (delay == 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index da1c361..4eed487 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -40,6 +40,7 @@
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.NotificationShadeWindowView;
+import com.android.systemui.shade.QuickSettingsController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
@@ -102,6 +103,7 @@
     private final IStatusBarService mBarService;
     private final DynamicPrivacyController mDynamicPrivacyController;
     private final NotificationListContainer mNotifListContainer;
+    private final QuickSettingsController mQsController;
 
     protected boolean mVrMode;
 
@@ -109,6 +111,7 @@
     StatusBarNotificationPresenter(
             Context context,
             NotificationPanelViewController panel,
+            QuickSettingsController quickSettingsController,
             HeadsUpManagerPhone headsUp,
             NotificationShadeWindowView statusBarWindow,
             ActivityStarter activityStarter,
@@ -136,6 +139,7 @@
         mActivityStarter = activityStarter;
         mKeyguardStateController = keyguardStateController;
         mNotificationPanel = panel;
+        mQsController = quickSettingsController;
         mHeadsUpManager = headsUp;
         mDynamicPrivacyController = dynamicPrivacyController;
         mKeyguardIndicationController = keyguardIndicationController;
@@ -191,7 +195,7 @@
     private void maybeClosePanelForShadeEmptied() {
         if (CLOSE_PANEL_WHEN_EMPTIED
                 && !mNotificationPanel.isTracking()
-                && !mNotificationPanel.isQsExpanded()
+                && !mQsController.getExpanded()
                 && mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED
                 && !isCollapsing()) {
             mStatusBarStateController.setState(StatusBarState.KEYGUARD);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
index 64b04e9..8e59a8b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
@@ -22,10 +22,11 @@
 
 import com.android.keyguard.LockIconViewController;
 import com.android.systemui.biometrics.AuthRippleController;
-import com.android.systemui.shade.LargeScreenShadeHeaderController;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.shade.NotificationShadeWindowViewController;
+import com.android.systemui.shade.QuickSettingsController;
+import com.android.systemui.shade.ShadeHeaderController;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationShelfController;
 import com.android.systemui.statusbar.core.StatusBarInitializer;
@@ -113,6 +114,9 @@
      */
     NotificationPanelViewController getNotificationPanelViewController();
 
+    /** Creates a QuickSettingsController. */
+    QuickSettingsController getQuickSettingsController();
+
     /**
      * Creates a LockIconViewController. Must be init after creation.
      */
@@ -134,9 +138,9 @@
     CentralSurfacesCommandQueueCallbacks getCentralSurfacesCommandQueueCallbacks();
 
     /**
-     * Creates a {@link LargeScreenShadeHeaderController}.
+     * Creates a {@link ShadeHeaderController}.
      */
-    LargeScreenShadeHeaderController getLargeScreenShadeHeaderController();
+    ShadeHeaderController getLargeScreenShadeHeaderController();
 
     /**
      * Creates a new {@link CollapsedStatusBarFragment} each time it's called. See
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
index c1c6c88..0929233 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
@@ -20,9 +20,10 @@
 import android.content.ContentResolver;
 import android.os.Handler;
 import android.view.LayoutInflater;
-import android.view.View;
 import android.view.ViewStub;
 
+import androidx.constraintlayout.motion.widget.MotionLayout;
+
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.LockIconView;
 import com.android.systemui.R;
@@ -32,7 +33,6 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.privacy.OngoingPrivacyChip;
 import com.android.systemui.settings.UserTracker;
@@ -85,9 +85,7 @@
 @Module(subcomponents = StatusBarFragmentComponent.class)
 public abstract class StatusBarViewModule {
 
-    public static final String LARGE_SCREEN_SHADE_HEADER = "large_screen_shade_header";
-    private static final String SPLIT_SHADE_BATTERY_VIEW = "split_shade_battery_view";
-    public static final String LARGE_SCREEN_BATTERY_CONTROLLER = "split_shade_battery_controller";
+    public static final String SHADE_HEADER = "large_screen_shade_header";
     public static final String STATUS_BAR_FRAGMENT = "status_bar_fragment";
 
     /** */
@@ -171,17 +169,15 @@
 
     /** */
     @Provides
-    @Named(LARGE_SCREEN_SHADE_HEADER)
+    @Named(SHADE_HEADER)
     @CentralSurfacesComponent.CentralSurfacesScope
-    public static View getLargeScreenShadeHeaderBarView(
+    public static MotionLayout getLargeScreenShadeHeaderBarView(
             NotificationShadeWindowView notificationShadeWindowView,
             FeatureFlags featureFlags) {
         ViewStub stub = notificationShadeWindowView.findViewById(R.id.qs_header_stub);
-        int layoutId = featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)
-                ? R.layout.combined_qs_header
-                : R.layout.large_screen_shade_header;
+        int layoutId = R.layout.combined_qs_header;
         stub.setLayoutResource(layoutId);
-        View v = stub.inflate();
+        MotionLayout v = (MotionLayout) stub.inflate();
         return v;
     }
 
@@ -197,7 +193,7 @@
     @Provides
     @CentralSurfacesComponent.CentralSurfacesScope
     public static OngoingPrivacyChip getSplitShadeOngoingPrivacyChip(
-            @Named(LARGE_SCREEN_SHADE_HEADER) View header) {
+            @Named(SHADE_HEADER) MotionLayout header) {
         return header.findViewById(R.id.privacy_chip);
     }
 
@@ -205,23 +201,23 @@
     @Provides
     @CentralSurfacesComponent.CentralSurfacesScope
     static StatusIconContainer providesStatusIconContainer(
-            @Named(LARGE_SCREEN_SHADE_HEADER) View header) {
+            @Named(SHADE_HEADER) MotionLayout header) {
         return header.findViewById(R.id.statusIcons);
     }
 
     /** */
     @Provides
     @CentralSurfacesComponent.CentralSurfacesScope
-    @Named(SPLIT_SHADE_BATTERY_VIEW)
-    static BatteryMeterView getBatteryMeterView(@Named(LARGE_SCREEN_SHADE_HEADER) View view) {
+    @Named(SHADE_HEADER)
+    static BatteryMeterView getBatteryMeterView(@Named(SHADE_HEADER) MotionLayout view) {
         return view.findViewById(R.id.batteryRemainingIcon);
     }
 
     @Provides
     @CentralSurfacesComponent.CentralSurfacesScope
-    @Named(LARGE_SCREEN_BATTERY_CONTROLLER)
+    @Named(SHADE_HEADER)
     static BatteryMeterViewController getBatteryMeterViewController(
-            @Named(SPLIT_SHADE_BATTERY_VIEW) BatteryMeterView batteryMeterView,
+            @Named(SHADE_HEADER) BatteryMeterView batteryMeterView,
             UserTracker userTracker,
             ConfigurationController configurationController,
             TunerService tunerService,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index 00fd4ef..2fe7145 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -23,7 +23,6 @@
 import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.IDLE;
 import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.SHOWING_PERSISTENT_DOT;
 
-import android.animation.Animator;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.app.Fragment;
@@ -43,6 +42,7 @@
 import android.widget.LinearLayout;
 
 import androidx.annotation.VisibleForTesting;
+import androidx.core.animation.Animator;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.Dumpable;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
index fe69f75..c04ea36 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
@@ -16,9 +16,9 @@
 
 package com.android.systemui.statusbar.phone.fragment
 
-import android.animation.Animator
-import android.animation.AnimatorSet
-import android.animation.ValueAnimator
+import androidx.core.animation.Animator
+import androidx.core.animation.AnimatorSet
+import androidx.core.animation.ValueAnimator
 import android.content.res.Resources
 import android.view.View
 import com.android.systemui.R
@@ -46,15 +46,19 @@
             R.dimen.ongoing_appops_chip_animation_out_status_bar_translation_x)
 
     override fun onSystemEventAnimationBegin(): Animator {
-        val moveOut = ValueAnimator.ofFloat(0f, 1f).setDuration(23.frames)
-        moveOut.interpolator = STATUS_BAR_X_MOVE_OUT
-        moveOut.addUpdateListener { animation: ValueAnimator ->
-            animatedView.translationX = -(translationXIn * animation.animatedValue as Float)
+        val moveOut = ValueAnimator.ofFloat(0f, 1f).apply {
+            duration = 23.frames
+            interpolator = STATUS_BAR_X_MOVE_OUT
+            addUpdateListener {
+                animatedView.translationX = -(translationXIn * animatedValue as Float)
+            }
         }
-        val alphaOut = ValueAnimator.ofFloat(1f, 0f).setDuration(8.frames)
-        alphaOut.interpolator = null
-        alphaOut.addUpdateListener { animation: ValueAnimator ->
-            animatedView.alpha = animation.animatedValue as Float
+        val alphaOut = ValueAnimator.ofFloat(1f, 0f).apply {
+            duration = 8.frames
+            interpolator = null
+            addUpdateListener {
+                animatedView.alpha = animatedValue as Float
+            }
         }
 
         val animSet = AnimatorSet()
@@ -64,17 +68,21 @@
 
     override fun onSystemEventAnimationFinish(hasPersistentDot: Boolean): Animator {
         animatedView.translationX = translationXOut.toFloat()
-        val moveIn = ValueAnimator.ofFloat(1f, 0f).setDuration(28.frames)
-        moveIn.startDelay = 2.frames
-        moveIn.interpolator = STATUS_BAR_X_MOVE_IN
-        moveIn.addUpdateListener { animation: ValueAnimator ->
-            animatedView.translationX = translationXOut * animation.animatedValue as Float
+        val moveIn = ValueAnimator.ofFloat(1f, 0f).apply {
+            duration = 23.frames
+            startDelay = 7.frames
+            interpolator = STATUS_BAR_X_MOVE_IN
+            addUpdateListener {
+                animatedView.translationX = translationXOut * animatedValue as Float
+            }
         }
-        val alphaIn = ValueAnimator.ofFloat(0f, 1f).setDuration(10.frames)
-        alphaIn.startDelay = 4.frames
-        alphaIn.interpolator = null
-        alphaIn.addUpdateListener { animation: ValueAnimator ->
-            animatedView.alpha = animation.animatedValue as Float
+        val alphaIn = ValueAnimator.ofFloat(0f, 1f).apply {
+            duration = 5.frames
+            startDelay = 11.frames
+            interpolator = null
+            addUpdateListener {
+                animatedView.alpha = animatedValue as Float
+            }
         }
 
         val animatorSet = AnimatorSet()
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index b23d870..8cfe2ea 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -42,7 +42,7 @@
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.demomode.DemoModeController;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
@@ -68,7 +68,7 @@
     // Things that use the tunable infrastructure but are now real user settings and
     // shouldn't be reset with tuner settings.
     private static final String[] RESET_EXCEPTION_LIST = new String[] {
-            QSTileHost.TILES_SETTING,
+            QSHost.TILES_SETTING,
             Settings.Secure.DOZE_ALWAYS_ON,
             Settings.Secure.MEDIA_CONTROLS_RESUME,
             Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
index 82200c6..360fc90 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
@@ -53,6 +53,7 @@
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.events.StatusBarEventsModule;
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
 import com.android.systemui.statusbar.phone.DozeServiceHost;
@@ -93,6 +94,7 @@
                 PowerModule.class,
                 QSModule.class,
                 ReferenceScreenshotModule.class,
+                StatusBarEventsModule.class,
                 VolumeModule.class,
         }
 )
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/FoldStateLoggingProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/unfold/FoldStateLoggingProviderImpl.kt
index 2683971..981f429 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/FoldStateLoggingProviderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/FoldStateLoggingProviderImpl.kt
@@ -61,8 +61,6 @@
         foldStateProvider.stop()
     }
 
-    override fun onHingeAngleUpdate(angle: Float) {}
-
     override fun onFoldUpdate(@FoldUpdate update: Int) {
         val now = clock.elapsedRealtime()
         when (update) {
@@ -77,6 +75,10 @@
         }
     }
 
+    override fun onUnfoldedScreenAvailable() {
+        Log.d(TAG, "Unfolded screen available")
+    }
+
     private fun dispatchState(@LoggedFoldedStates current: Int) {
         val now = clock.elapsedRealtime()
         val previous = lastState
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 52eef42..b847d67 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -1398,6 +1398,7 @@
             @Override
             public void onAnimationCancel(@NonNull Animator animation) {
                 mInteractionJankMonitor.cancel(CUJ_VOLUME_CONTROL);
+                Log.d(TAG, "onAnimationCancel");
             }
 
             @Override
@@ -1471,6 +1472,7 @@
         mHandler.removeMessages(H.DISMISS);
         mHandler.removeMessages(H.SHOW);
         if (mIsAnimatingDismiss) {
+            Log.d(TAG, "dismissH: isAnimatingDismiss");
             return;
         }
         mIsAnimatingDismiss = true;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
index badeb27..e84a975 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
@@ -31,6 +31,7 @@
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_WAKE
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS
+import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
@@ -51,6 +52,7 @@
 
 @SmallTest
 class ActiveUnlockConfigTest : SysuiTestCase() {
+
     private lateinit var secureSettings: FakeSettings
     @Mock
     private lateinit var contentResolver: ContentResolver
@@ -71,7 +73,6 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-
         currentUser = KeyguardUpdateMonitor.getCurrentUser()
         secureSettings = FakeSettings()
         activeUnlockConfig = ActiveUnlockConfig(
@@ -313,10 +314,6 @@
                 assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason))
             }
         }
-        assertTrue(activeUnlockConfig.isWakeupConsideredUnlockIntent(PowerManager.WAKE_REASON_LIFT))
-        assertTrue(activeUnlockConfig.isWakeupConsideredUnlockIntent(PowerManager.WAKE_REASON_TAP))
-        assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(
-            PowerManager.WAKE_REASON_UNFOLD_DEVICE))
     }
 
     @Test
@@ -330,11 +327,70 @@
         for (wakeReason in 0..WAKE_REASON_BIOMETRIC) {
             assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason))
         }
-        assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(
-            PowerManager.WAKE_REASON_LIFT))
-        assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(PowerManager.WAKE_REASON_TAP))
-        assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(
-            PowerManager.WAKE_REASON_UNFOLD_DEVICE))
+    }
+
+    @Test
+    fun isWakeupForceDismissKeyguard_singleValue() {
+        verifyRegisterSettingObserver()
+
+        // GIVEN lift is considered an unlock intent
+        secureSettings.putStringForUser(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD,
+            PowerManager.WAKE_REASON_LIFT.toString(), currentUser)
+        updateSetting(secureSettings.getUriFor(
+            ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD
+        ))
+
+        // THEN only WAKE_REASON_LIFT is considered an unlock intent
+        for (wakeReason in 0..WAKE_REASON_BIOMETRIC) {
+            if (wakeReason == PowerManager.WAKE_REASON_LIFT) {
+                assertTrue(activeUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason))
+            } else {
+                assertFalse(activeUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason))
+            }
+        }
+    }
+
+    @Test
+    fun isWakeupForceDismissKeyguard_emptyValues() {
+        verifyRegisterSettingObserver()
+
+        // GIVEN lift and tap are considered an unlock intent
+        secureSettings.putStringForUser(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD,
+            " ", currentUser)
+        updateSetting(secureSettings.getUriFor(
+            ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD
+        ))
+
+        // THEN no wake up gestures are considered an unlock intent
+        for (wakeReason in 0..WAKE_REASON_BIOMETRIC) {
+            assertFalse(activeUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason))
+        }
+    }
+
+    @Test
+    fun isWakeupForceDismissKeyguard_multiValue() {
+        verifyRegisterSettingObserver()
+
+        // GIVEN lift and tap are considered an unlock intent
+        secureSettings.putStringForUser(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD,
+            PowerManager.WAKE_REASON_LIFT.toString() +
+                    "|" +
+                    PowerManager.WAKE_REASON_TAP.toString(),
+            currentUser
+        )
+        updateSetting(secureSettings.getUriFor(
+            ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD
+        ))
+
+        // THEN WAKE_REASON_LIFT and WAKE_REASON TAP are considered an unlock intent
+        for (wakeReason in 0..WAKE_REASON_BIOMETRIC) {
+            if (wakeReason == PowerManager.WAKE_REASON_LIFT ||
+                wakeReason == PowerManager.WAKE_REASON_TAP) {
+                assertTrue(activeUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason))
+            } else {
+                assertFalse(activeUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason))
+            }
+        }
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/EmergencyButtonControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/EmergencyButtonControllerTest.kt
new file mode 100644
index 0000000..30fed0b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/EmergencyButtonControllerTest.kt
@@ -0,0 +1,112 @@
+/*
+ * 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.keyguard
+
+import android.app.ActivityTaskManager
+import android.content.pm.PackageManager
+import android.os.PowerManager
+import android.telecom.TelecomManager
+import android.telephony.TelephonyManager
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.shade.ShadeController
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.time.FakeSystemClock
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class EmergencyButtonControllerTest : SysuiTestCase() {
+    lateinit var underTest: EmergencyButtonController
+    @Mock lateinit var emergencyButton: EmergencyButton
+    @Mock lateinit var configurationController: ConfigurationController
+    @Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+    @Mock lateinit var telephonyManager: TelephonyManager
+    @Mock lateinit var powerManager: PowerManager
+    @Mock lateinit var activityTaskManager: ActivityTaskManager
+    @Mock lateinit var shadeController: ShadeController
+    @Mock lateinit var telecomManager: TelecomManager
+    @Mock lateinit var metricsLogger: MetricsLogger
+    @Mock lateinit var lockPatternUtils: LockPatternUtils
+    @Mock lateinit var packageManager: PackageManager
+    val fakeSystemClock = FakeSystemClock()
+    val mainExecutor = FakeExecutor(fakeSystemClock)
+    val backgroundExecutor = FakeExecutor(fakeSystemClock)
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        underTest =
+            EmergencyButtonController(
+                emergencyButton,
+                configurationController,
+                keyguardUpdateMonitor,
+                telephonyManager,
+                powerManager,
+                activityTaskManager,
+                shadeController,
+                telecomManager,
+                metricsLogger,
+                lockPatternUtils,
+                mainExecutor,
+                backgroundExecutor
+            )
+        context.setMockPackageManager(packageManager)
+        Mockito.`when`(emergencyButton.context).thenReturn(context)
+    }
+
+    @Test
+    fun testUpdateEmergencyButton() {
+        Mockito.`when`(telecomManager.isInCall).thenReturn(true)
+        Mockito.`when`(lockPatternUtils.isSecure(anyInt())).thenReturn(true)
+        Mockito.`when`(packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY))
+            .thenReturn(true)
+        underTest.updateEmergencyCallButton()
+        backgroundExecutor.runAllReady()
+        verify(emergencyButton, never())
+            .updateEmergencyCallButton(
+                /* isInCall= */ any(),
+                /* hasTelephonyRadio= */ any(),
+                /* simLocked= */ any(),
+                /* isSecure= */ any()
+            )
+        mainExecutor.runAllReady()
+        verify(emergencyButton)
+            .updateEmergencyCallButton(
+                /* isInCall= */ eq(true),
+                /* hasTelephonyRadio= */ eq(true),
+                /* simLocked= */ any(),
+                /* isSecure= */ eq(true)
+            )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java
deleted file mode 100644
index 4021652..0000000
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewControllerTest.java
+++ /dev/null
@@ -1,186 +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.keyguard;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.media.AudioManager;
-import android.telephony.TelephonyManager;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableResources;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class KeyguardHostViewControllerTest extends SysuiTestCase {
-    @Mock
-    private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-
-    private KeyguardHostView mKeyguardHostView;
-    @Mock
-    private AudioManager mAudioManager;
-    @Mock
-    private TelephonyManager mTelephonyManager;
-    @Mock
-    private ViewMediatorCallback mViewMediatorCallback;
-    @Mock
-    KeyguardSecurityContainerController.Factory mKeyguardSecurityContainerControllerFactory;
-    @Mock
-    private KeyguardSecurityContainerController mKeyguardSecurityContainerController;
-
-    @Rule
-    public MockitoRule mMockitoRule = MockitoJUnit.rule();
-
-    private TestableResources mTestableResources;
-    private KeyguardHostViewController mKeyguardHostViewController;
-
-    @Before
-    public void setup() {
-        mTestableResources = mContext.getOrCreateTestableResources();
-
-        mKeyguardHostView = new KeyguardHostView(mContext);
-
-        // Explicitly disable one handed keyguard.
-        mTestableResources.addOverride(
-                R.bool.can_use_one_handed_bouncer, false);
-
-        when(mKeyguardSecurityContainerControllerFactory.create(any(
-                KeyguardSecurityContainer.SecurityCallback.class)))
-                .thenReturn(mKeyguardSecurityContainerController);
-        mKeyguardHostViewController = new KeyguardHostViewController(
-                mKeyguardHostView, mKeyguardUpdateMonitor, mAudioManager, mTelephonyManager,
-                mViewMediatorCallback, mKeyguardSecurityContainerControllerFactory);
-    }
-
-    @Test
-    public void testHasDismissActions() {
-        assertFalse("Action not set yet", mKeyguardHostViewController.hasDismissActions());
-        mKeyguardHostViewController.setOnDismissAction(mock(OnDismissAction.class),
-                null /* cancelAction */);
-        assertTrue("Action should exist", mKeyguardHostViewController.hasDismissActions());
-    }
-
-    @Test
-    public void testOnStartingToHide() {
-        mKeyguardHostViewController.onStartingToHide();
-        verify(mKeyguardSecurityContainerController).onStartingToHide();
-    }
-
-    @Test
-    public void onBouncerVisible_propagatesToKeyguardSecurityContainerController() {
-        mKeyguardHostViewController.onBouncerVisibilityChanged(ViewGroup.VISIBLE);
-        mKeyguardHostViewController.onBouncerVisibilityChanged(ViewGroup.INVISIBLE);
-
-        InOrder order = inOrder(mKeyguardSecurityContainerController);
-        order.verify(mKeyguardSecurityContainerController).onBouncerVisibilityChanged(View.VISIBLE);
-        order.verify(mKeyguardSecurityContainerController).onBouncerVisibilityChanged(
-                View.INVISIBLE);
-    }
-
-    @Test
-    public void testGravityReappliedOnConfigurationChange() {
-        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT);
-        mKeyguardHostView.setLayoutParams(lp);
-
-        // Set initial gravity
-        mTestableResources.addOverride(R.integer.keyguard_host_view_gravity,
-                Gravity.CENTER);
-
-        // Kick off the initial pass...
-        mKeyguardHostViewController.init();
-        assertEquals(
-                ((FrameLayout.LayoutParams) mKeyguardHostView.getLayoutParams()).gravity,
-                Gravity.CENTER);
-
-        // Now simulate a config change
-        mTestableResources.addOverride(R.integer.keyguard_host_view_gravity,
-                Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
-
-        mKeyguardHostViewController.updateResources();
-        assertEquals(
-                ((FrameLayout.LayoutParams) mKeyguardHostView.getLayoutParams()).gravity,
-                Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
-    }
-
-    @Test
-    public void testGravityUsesOneHandGravityWhenApplicable() {
-        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT);
-        mKeyguardHostView.setLayoutParams(lp);
-
-        mTestableResources.addOverride(
-                R.integer.keyguard_host_view_gravity,
-                Gravity.CENTER);
-        mTestableResources.addOverride(
-                R.integer.keyguard_host_view_one_handed_gravity,
-                Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
-
-        // Start disabled.
-        mTestableResources.addOverride(
-                R.bool.can_use_one_handed_bouncer, false);
-
-        mKeyguardHostViewController.init();
-        assertEquals(
-                ((FrameLayout.LayoutParams) mKeyguardHostView.getLayoutParams()).gravity,
-                Gravity.CENTER);
-
-        // And enable
-        mTestableResources.addOverride(
-                R.bool.can_use_one_handed_bouncer, true);
-
-        mKeyguardHostViewController.updateResources();
-        assertEquals(
-                ((FrameLayout.LayoutParams) mKeyguardHostView.getLayoutParams()).gravity,
-                Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
-    }
-
-    @Test
-    public void testUpdateKeyguardPositionDelegatesToSecurityContainer() {
-        mKeyguardHostViewController.updateKeyguardPosition(1.0f);
-
-        verify(mKeyguardSecurityContainerController).updateKeyguardPosition(1.0f);
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index 4a1c1cf..bbc7bc9 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -23,15 +23,18 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -39,13 +42,16 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.hardware.biometrics.BiometricOverlayConstants;
-import android.hardware.biometrics.BiometricSourceType;
+import android.media.AudioManager;
+import android.telephony.TelephonyManager;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.testing.TestableResources;
+import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
-import android.view.View;
 import android.view.WindowInsetsController;
+import android.widget.FrameLayout;
 
 import androidx.test.filters.SmallTest;
 
@@ -61,6 +67,7 @@
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.log.SessionTracker;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -72,6 +79,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatcher;
 import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnit;
@@ -84,10 +92,8 @@
 @TestableLooper.RunWithLooper()
 public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
     private static final int TARGET_USER_ID = 100;
-
     @Rule
     public MockitoRule mRule = MockitoJUnit.rule();
-
     @Mock
     private KeyguardSecurityContainer mView;
     @Mock
@@ -109,8 +115,6 @@
     @Mock
     private KeyguardInputViewController mInputViewController;
     @Mock
-    private KeyguardSecurityContainer.SecurityCallback mSecurityCallback;
-    @Mock
     private WindowInsetsController mWindowInsetsController;
     @Mock
     private KeyguardSecurityViewFlipper mSecurityViewFlipper;
@@ -127,8 +131,6 @@
     @Mock
     private EmergencyButtonController mEmergencyButtonController;
     @Mock
-    private Resources mResources;
-    @Mock
     private FalsingCollector mFalsingCollector;
     @Mock
     private FalsingManager mFalsingManager;
@@ -148,6 +150,12 @@
     private KeyguardPasswordViewController mKeyguardPasswordViewControllerMock;
     @Mock
     private FalsingA11yDelegate mFalsingA11yDelegate;
+    @Mock
+    private TelephonyManager mTelephonyManager;
+    @Mock
+    private ViewMediatorCallback mViewMediatorCallback;
+    @Mock
+    private AudioManager mAudioManager;
 
     @Captor
     private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallback;
@@ -159,18 +167,25 @@
     private KeyguardSecurityContainerController mKeyguardSecurityContainerController;
     private KeyguardPasswordViewController mKeyguardPasswordViewController;
     private KeyguardPasswordView mKeyguardPasswordView;
+    private TestableResources mTestableResources;
 
     @Before
     public void setup() {
         mConfiguration = new Configuration();
         mConfiguration.setToDefaults(); // Defaults to ORIENTATION_UNDEFINED.
+        mTestableResources = mContext.getOrCreateTestableResources();
 
-        when(mResources.getConfiguration()).thenReturn(mConfiguration);
         when(mView.getContext()).thenReturn(mContext);
-        when(mView.getResources()).thenReturn(mResources);
+        when(mView.getResources()).thenReturn(mContext.getResources());
+        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(/* width=  */ 0, /* height= */
+                0);
+        lp.gravity = 0;
+        when(mView.getLayoutParams()).thenReturn(lp);
         when(mAdminSecondaryLockScreenControllerFactory.create(any(KeyguardSecurityCallback.class)))
                 .thenReturn(mAdminSecondaryLockScreenController);
         when(mSecurityViewFlipper.getWindowInsetsController()).thenReturn(mWindowInsetsController);
+        when(mKeyguardSecurityViewFlipperController.getSecurityView(any(SecurityMode.class),
+                any(KeyguardSecurityCallback.class))).thenReturn(mInputViewController);
         mKeyguardPasswordView = spy((KeyguardPasswordView) LayoutInflater.from(mContext).inflate(
                 R.layout.keyguard_password_view, null));
         when(mKeyguardPasswordView.getRootView()).thenReturn(mSecurityViewFlipper);
@@ -179,20 +194,21 @@
         when(mKeyguardMessageAreaControllerFactory.create(any(KeyguardMessageArea.class)))
                 .thenReturn(mKeyguardMessageAreaController);
         when(mKeyguardPasswordView.getWindowInsetsController()).thenReturn(mWindowInsetsController);
+        when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(SecurityMode.PIN);
         mKeyguardPasswordViewController = new KeyguardPasswordViewController(
                 (KeyguardPasswordView) mKeyguardPasswordView, mKeyguardUpdateMonitor,
                 SecurityMode.Password, mLockPatternUtils, null,
                 mKeyguardMessageAreaControllerFactory, null, null, mEmergencyButtonController,
                 null, mock(Resources.class), null, mKeyguardViewController);
 
-        mKeyguardSecurityContainerController = new KeyguardSecurityContainerController.Factory(
+        mKeyguardSecurityContainerController = new KeyguardSecurityContainerController(
                 mView, mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils,
                 mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger,
                 mKeyguardStateController, mKeyguardSecurityViewFlipperController,
                 mConfigurationController, mFalsingCollector, mFalsingManager,
                 mUserSwitcherController, mFeatureFlags, mGlobalSettings,
-                mSessionTracker, Optional.of(mSideFpsController), mFalsingA11yDelegate).create(
-                mSecurityCallback);
+                mSessionTracker, Optional.of(mSideFpsController), mFalsingA11yDelegate,
+                mTelephonyManager, mViewMediatorCallback, mAudioManager);
     }
 
     @Test
@@ -244,7 +260,8 @@
                 eq(mFalsingA11yDelegate));
 
         // Update rotation. Should trigger update
-        mConfiguration.orientation = Configuration.ORIENTATION_LANDSCAPE;
+        mTestableResources.getResources().getConfiguration().orientation =
+                Configuration.ORIENTATION_LANDSCAPE;
 
         mKeyguardSecurityContainerController.updateResources();
         verify(mView).initMode(eq(MODE_DEFAULT), eq(mGlobalSettings), eq(mFalsingManager),
@@ -278,7 +295,7 @@
 
     @Test
     public void showSecurityScreen_oneHandedMode_flagDisabled_noOneHandedMode() {
-        when(mResources.getBoolean(R.bool.can_use_one_handed_bouncer)).thenReturn(false);
+        mTestableResources.addOverride(R.bool.can_use_one_handed_bouncer, false);
         when(mKeyguardSecurityViewFlipperController.getSecurityView(
                 eq(SecurityMode.Pattern), any(KeyguardSecurityCallback.class)))
                 .thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController);
@@ -292,7 +309,7 @@
 
     @Test
     public void showSecurityScreen_oneHandedMode_flagEnabled_oneHandedMode() {
-        when(mResources.getBoolean(R.bool.can_use_one_handed_bouncer)).thenReturn(true);
+        mTestableResources.addOverride(R.bool.can_use_one_handed_bouncer, true);
         when(mKeyguardSecurityViewFlipperController.getSecurityView(
                 eq(SecurityMode.Pattern), any(KeyguardSecurityCallback.class)))
                 .thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController);
@@ -306,7 +323,7 @@
 
     @Test
     public void showSecurityScreen_twoHandedMode_flagEnabled_noOneHandedMode() {
-        when(mResources.getBoolean(R.bool.can_use_one_handed_bouncer)).thenReturn(true);
+        mTestableResources.addOverride(R.bool.can_use_one_handed_bouncer, true);
         setupGetSecurityView();
 
         mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Password);
@@ -345,134 +362,12 @@
     }
 
     @Test
-    public void onBouncerVisibilityChanged_allConditionsGood_sideFpsHintShown() {
-        setupConditionsToEnableSideFpsHint();
-        reset(mSideFpsController);
-
-        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
-
-        verify(mSideFpsController).show(SideFpsUiRequestSource.PRIMARY_BOUNCER,
-                BiometricOverlayConstants.REASON_AUTH_KEYGUARD);
-        verify(mSideFpsController, never()).hide(any());
-    }
-
-    @Test
-    public void onBouncerVisibilityChanged_fpsSensorNotRunning_sideFpsHintHidden() {
-        setupConditionsToEnableSideFpsHint();
-        setFingerprintDetectionRunning(false);
-        reset(mSideFpsController);
-
-        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
-
-        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
-        verify(mSideFpsController, never()).show(any(), anyInt());
-    }
-
-    @Test
-    public void onBouncerVisibilityChanged_withoutSidedSecurity_sideFpsHintHidden() {
-        setupConditionsToEnableSideFpsHint();
-        setSideFpsHintEnabledFromResources(false);
-        reset(mSideFpsController);
-
-        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
-
-        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
-        verify(mSideFpsController, never()).show(any(), anyInt());
-    }
-
-    @Test
-    public void onBouncerVisibilityChanged_unlockingWithFingerprintNotAllowed_sideFpsHintHidden() {
-        setupConditionsToEnableSideFpsHint();
-        setUnlockingWithFingerprintAllowed(false);
-        reset(mSideFpsController);
-
-        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
-
-        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
-        verify(mSideFpsController, never()).show(any(), anyInt());
-    }
-
-    @Test
-    public void onBouncerVisibilityChanged_sideFpsHintShown_sideFpsHintHidden() {
-        setupGetSecurityView();
-        setupConditionsToEnableSideFpsHint();
-        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
-        verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER,
-                BiometricOverlayConstants.REASON_AUTH_KEYGUARD);
-        reset(mSideFpsController);
-
-        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.INVISIBLE);
-
-        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
-        verify(mSideFpsController, never()).show(any(), anyInt());
-    }
-
-    @Test
     public void onBouncerVisibilityChanged_resetsScale() {
-        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.INVISIBLE);
-
+        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(false);
         verify(mView).resetScale();
     }
 
     @Test
-    public void onStartingToHide_sideFpsHintShown_sideFpsHintHidden() {
-        setupGetSecurityView();
-        setupConditionsToEnableSideFpsHint();
-        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
-        verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER,
-                BiometricOverlayConstants.REASON_AUTH_KEYGUARD);
-        reset(mSideFpsController);
-
-        mKeyguardSecurityContainerController.onStartingToHide();
-
-        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
-        verify(mSideFpsController, never()).show(any(), anyInt());
-    }
-
-    @Test
-    public void onPause_sideFpsHintShown_sideFpsHintHidden() {
-        setupGetSecurityView();
-        setupConditionsToEnableSideFpsHint();
-        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
-        verify(mSideFpsController, atLeastOnce()).show(SideFpsUiRequestSource.PRIMARY_BOUNCER,
-                BiometricOverlayConstants.REASON_AUTH_KEYGUARD);
-        reset(mSideFpsController);
-
-        mKeyguardSecurityContainerController.onPause();
-
-        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
-        verify(mSideFpsController, never()).show(any(), anyInt());
-    }
-
-    @Test
-    public void onResume_sideFpsHintShouldBeShown_sideFpsHintShown() {
-        setupGetSecurityView();
-        setupConditionsToEnableSideFpsHint();
-        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
-        reset(mSideFpsController);
-
-        mKeyguardSecurityContainerController.onResume(0);
-
-        verify(mSideFpsController).show(SideFpsUiRequestSource.PRIMARY_BOUNCER,
-                BiometricOverlayConstants.REASON_AUTH_KEYGUARD);
-        verify(mSideFpsController, never()).hide(any());
-    }
-
-    @Test
-    public void onResume_sideFpsHintShouldNotBeShown_sideFpsHintHidden() {
-        setupGetSecurityView();
-        setupConditionsToEnableSideFpsHint();
-        setSideFpsHintEnabledFromResources(false);
-        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
-        reset(mSideFpsController);
-
-        mKeyguardSecurityContainerController.onResume(0);
-
-        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
-        verify(mSideFpsController, never()).show(any(), anyInt());
-    }
-
-    @Test
     public void showNextSecurityScreenOrFinish_setsSecurityScreenToPinAfterSimPinUnlock() {
         // GIVEN the current security method is SimPin
         when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(false);
@@ -488,7 +383,9 @@
                 SecurityMode.SimPin);
 
         // THEN the next security method of PIN is set, and the keyguard is not marked as done
-        verify(mSecurityCallback, never()).finish(anyBoolean(), anyInt());
+
+        verify(mViewMediatorCallback, never()).keyguardDonePending(anyBoolean(), anyInt());
+        verify(mViewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt());
         assertThat(mKeyguardSecurityContainerController.getCurrentSecurityMode())
                 .isEqualTo(SecurityMode.PIN);
     }
@@ -562,17 +459,19 @@
     }
 
     @Test
-    public void onDensityorFontScaleChanged() {
+    public void onDensityOrFontScaleChanged() {
         ArgumentCaptor<ConfigurationController.ConfigurationListener>
                 configurationListenerArgumentCaptor = ArgumentCaptor.forClass(
                 ConfigurationController.ConfigurationListener.class);
         mKeyguardSecurityContainerController.onViewAttached();
         verify(mConfigurationController).addCallback(configurationListenerArgumentCaptor.capture());
+        clearInvocations(mKeyguardSecurityViewFlipperController);
+
         configurationListenerArgumentCaptor.getValue().onDensityOrFontScaleChanged();
 
         verify(mView).onDensityOrFontScaleChanged();
         verify(mKeyguardSecurityViewFlipperController).clearViews();
-        verify(mKeyguardSecurityViewFlipperController).getSecurityView(any(SecurityMode.class),
+        verify(mKeyguardSecurityViewFlipperController).getSecurityView(eq(SecurityMode.PIN),
                 any(KeyguardSecurityCallback.class));
     }
 
@@ -583,11 +482,13 @@
                 ConfigurationController.ConfigurationListener.class);
         mKeyguardSecurityContainerController.onViewAttached();
         verify(mConfigurationController).addCallback(configurationListenerArgumentCaptor.capture());
+        clearInvocations(mKeyguardSecurityViewFlipperController);
+
         configurationListenerArgumentCaptor.getValue().onThemeChanged();
 
         verify(mView).reloadColors();
         verify(mKeyguardSecurityViewFlipperController).clearViews();
-        verify(mKeyguardSecurityViewFlipperController).getSecurityView(any(SecurityMode.class),
+        verify(mKeyguardSecurityViewFlipperController).getSecurityView(eq(SecurityMode.PIN),
                 any(KeyguardSecurityCallback.class));
     }
 
@@ -598,15 +499,91 @@
                 ConfigurationController.ConfigurationListener.class);
         mKeyguardSecurityContainerController.onViewAttached();
         verify(mConfigurationController).addCallback(configurationListenerArgumentCaptor.capture());
+        clearInvocations(mKeyguardSecurityViewFlipperController);
+
         configurationListenerArgumentCaptor.getValue().onUiModeChanged();
 
         verify(mView).reloadColors();
         verify(mKeyguardSecurityViewFlipperController).clearViews();
-        verify(mKeyguardSecurityViewFlipperController).getSecurityView(any(SecurityMode.class),
+        verify(mKeyguardSecurityViewFlipperController).getSecurityView(eq(SecurityMode.PIN),
                 any(KeyguardSecurityCallback.class));
     }
 
     @Test
+    public void testHasDismissActions() {
+        assertFalse("Action not set yet", mKeyguardSecurityContainerController.hasDismissActions());
+        mKeyguardSecurityContainerController.setOnDismissAction(mock(
+                        ActivityStarter.OnDismissAction.class),
+                null /* cancelAction */);
+        assertTrue("Action should exist", mKeyguardSecurityContainerController.hasDismissActions());
+    }
+
+    @Test
+    public void testOnStartingToHide() {
+        mKeyguardSecurityContainerController.onStartingToHide();
+        verify(mInputViewController).onStartingToHide();
+    }
+
+    @Test
+    public void testGravityReappliedOnConfigurationChange() {
+        // Set initial gravity
+        mTestableResources.addOverride(R.integer.keyguard_host_view_gravity,
+                Gravity.CENTER);
+
+        // Kick off the initial pass...
+        mKeyguardSecurityContainerController.onInit();
+        verify(mView).setLayoutParams(argThat(
+                (ArgumentMatcher<FrameLayout.LayoutParams>) argument ->
+                        argument.gravity == Gravity.CENTER));
+        clearInvocations(mView);
+
+        // Now simulate a config change
+        mTestableResources.addOverride(R.integer.keyguard_host_view_gravity,
+                Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
+
+        mKeyguardSecurityContainerController.updateResources();
+        verify(mView).setLayoutParams(argThat(
+                (ArgumentMatcher<FrameLayout.LayoutParams>) argument ->
+                        argument.gravity == (Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM)));
+    }
+
+    @Test
+    public void testGravityUsesOneHandGravityWhenApplicable() {
+        mTestableResources.addOverride(
+                R.integer.keyguard_host_view_gravity,
+                Gravity.CENTER);
+        mTestableResources.addOverride(
+                R.integer.keyguard_host_view_one_handed_gravity,
+                Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
+
+        // Start disabled.
+        mTestableResources.addOverride(
+                R.bool.can_use_one_handed_bouncer, false);
+
+        mKeyguardSecurityContainerController.onInit();
+        verify(mView).setLayoutParams(argThat(
+                (ArgumentMatcher<FrameLayout.LayoutParams>) argument ->
+                        argument.gravity == Gravity.CENTER));
+        clearInvocations(mView);
+
+        // And enable
+        mTestableResources.addOverride(
+                R.bool.can_use_one_handed_bouncer, true);
+
+        mKeyguardSecurityContainerController.updateResources();
+        verify(mView).setLayoutParams(argThat(
+                (ArgumentMatcher<FrameLayout.LayoutParams>) argument ->
+                        argument.gravity == (Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM)));
+    }
+
+    @Test
+    public void testUpdateKeyguardPositionDelegatesToSecurityContainer() {
+        mKeyguardSecurityContainerController.updateKeyguardPosition(1.0f);
+        verify(mView).updatePositionByTouchX(1.0f);
+    }
+
+
+    @Test
     public void testReinflateViewFlipper() {
         mKeyguardSecurityContainerController.reinflateViewFlipper();
         verify(mKeyguardSecurityViewFlipperController).clearViews();
@@ -614,39 +591,31 @@
                 any(KeyguardSecurityCallback.class));
     }
 
+    @Test
+    public void testSideFpsControllerShow() {
+        mKeyguardSecurityContainerController.updateSideFpsVisibility(/* isVisible= */ true);
+        verify(mSideFpsController).show(
+                SideFpsUiRequestSource.PRIMARY_BOUNCER,
+                BiometricOverlayConstants.REASON_AUTH_KEYGUARD);
+    }
+
+    @Test
+    public void testSideFpsControllerHide() {
+        mKeyguardSecurityContainerController.updateSideFpsVisibility(/* isVisible= */ false);
+        verify(mSideFpsController).hide(SideFpsUiRequestSource.PRIMARY_BOUNCER);
+    }
+
     private KeyguardSecurityContainer.SwipeListener getRegisteredSwipeListener() {
         mKeyguardSecurityContainerController.onViewAttached();
         verify(mView).setSwipeListener(mSwipeListenerArgumentCaptor.capture());
         return mSwipeListenerArgumentCaptor.getValue();
     }
 
-    private void setupConditionsToEnableSideFpsHint() {
-        attachView();
-        setSideFpsHintEnabledFromResources(true);
-        setFingerprintDetectionRunning(true);
-        setUnlockingWithFingerprintAllowed(true);
-    }
-
     private void attachView() {
         mKeyguardSecurityContainerController.onViewAttached();
         verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallback.capture());
     }
 
-    private void setFingerprintDetectionRunning(boolean running) {
-        when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(running);
-        mKeyguardUpdateMonitorCallback.getValue().onBiometricRunningStateChanged(running,
-                BiometricSourceType.FINGERPRINT);
-    }
-
-    private void setSideFpsHintEnabledFromResources(boolean enabled) {
-        when(mResources.getBoolean(R.bool.config_show_sidefps_hint_on_bouncer)).thenReturn(
-                enabled);
-    }
-
-    private void setUnlockingWithFingerprintAllowed(boolean allowed) {
-        when(mKeyguardUpdateMonitor.isUnlockingWithFingerprintAllowed()).thenReturn(allowed);
-    }
-
     private void setupGetSecurityView() {
         when(mKeyguardSecurityViewFlipperController.getSecurityView(
                 any(), any(KeyguardSecurityCallback.class)))
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
index dfad15d..7144914 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
@@ -26,7 +26,6 @@
 
 import com.android.keyguard.logging.KeyguardLogger;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.plugins.ClockAnimations;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
@@ -61,8 +60,6 @@
     @Mock
     DozeParameters mDozeParameters;
     @Mock
-    FeatureFlags mFeatureFlags;
-    @Mock
     ScreenOffAnimationController mScreenOffAnimationController;
     @Captor
     private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor;
@@ -83,7 +80,6 @@
                 mKeyguardUpdateMonitor,
                 mConfigurationController,
                 mDozeParameters,
-                mFeatureFlags,
                 mScreenOffAnimationController,
                 mKeyguardLogger);
     }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 1c16634..250f221 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -17,6 +17,7 @@
 package com.android.keyguard;
 
 import static android.app.StatusBarManager.SESSION_KEYGUARD;
+import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_TIMED;
 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT;
 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
 import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_POWER_BUTTON;
@@ -28,6 +29,7 @@
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
 import static com.android.keyguard.FaceAuthApiRequestReason.NOTIFICATION_PANEL_CLICKED;
 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_AVAILABLE;
+import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_STATE_CANCELLING;
 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_STATE_CANCELLING_RESTARTING;
 import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_TIMEOUT;
 import static com.android.keyguard.KeyguardUpdateMonitor.HAL_POWER_PRESS_TIMEOUT;
@@ -595,9 +597,8 @@
         mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */);
         mTestableLooper.processAllMessages();
 
-        verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
-                anyInt());
-        verify(mFingerprintManager, never()).detectFingerprint(any(), any(), anyInt());
+        verifyFingerprintAuthenticateCall();
+        verifyFingerprintDetectNeverCalled();
     }
 
     @Test
@@ -607,9 +608,8 @@
         mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */);
         mTestableLooper.processAllMessages();
 
-        verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
-                anyInt(), anyInt());
-        verify(mFingerprintManager, never()).detectFingerprint(any(), any(), anyInt());
+        verifyFingerprintAuthenticateNeverCalled();
+        verifyFingerprintDetectNeverCalled();
     }
 
     @Test
@@ -623,8 +623,8 @@
         mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */);
         mTestableLooper.processAllMessages();
 
-        verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt());
-        verify(mFingerprintManager).detectFingerprint(any(), any(), anyInt());
+        verifyFingerprintAuthenticateNeverCalled();
+        verifyFingerprintDetectCall();
     }
 
     @Test
@@ -713,7 +713,7 @@
     public void testTriesToAuthenticate_whenBouncer() {
         setKeyguardBouncerVisibility(true);
 
-        verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
+        verifyFaceAuthenticateCall();
         verify(mFaceManager).isHardwareDetected();
         verify(mFaceManager).hasEnrolledTemplates(anyInt());
     }
@@ -723,8 +723,7 @@
         mKeyguardUpdateMonitor.sendPrimaryBouncerChanged(
                 /* bouncerIsOrWillBeShowing */ true, /* bouncerFullyShown */ false);
 
-        verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
-                anyBoolean());
+        verifyFaceAuthenticateNeverCalled();
     }
 
     @Test
@@ -732,7 +731,8 @@
         keyguardIsVisible();
         mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
         mTestableLooper.processAllMessages();
-        verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
+
+        verifyFaceAuthenticateCall();
         verify(mUiEventLogger).logWithInstanceIdAndPosition(
                 eq(FaceAuthUiEvent.FACE_AUTH_UPDATED_STARTED_WAKING_UP),
                 eq(0),
@@ -748,8 +748,7 @@
         mTestableLooper.processAllMessages();
 
         keyguardIsVisible();
-        verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
-                anyBoolean());
+        verifyFaceAuthenticateNeverCalled();
     }
 
     @Test
@@ -760,8 +759,7 @@
         mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
         mTestableLooper.processAllMessages();
         keyguardIsVisible();
-        verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
-                anyBoolean());
+        verifyFaceAuthenticateNeverCalled();
     }
 
     @Test
@@ -785,9 +783,8 @@
         mTestableLooper.processAllMessages();
 
         // THEN face detect and authenticate are NOT triggered
-        verify(mFaceManager, never()).detectFace(any(), any(), anyInt());
-        verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
-                anyBoolean());
+        verifyFaceDetectNeverCalled();
+        verifyFaceAuthenticateNeverCalled();
 
         // THEN biometric help message sent to callback
         verify(keyguardUpdateMonitorCallback).onBiometricHelp(
@@ -808,9 +805,8 @@
         mTestableLooper.processAllMessages();
 
         // FACE detect is triggered, not authenticate
-        verify(mFaceManager).detectFace(any(), any(), anyInt());
-        verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
-                anyBoolean());
+        verifyFaceDetectCall();
+        verifyFaceAuthenticateNeverCalled();
 
         // WHEN bouncer becomes visible
         setKeyguardBouncerVisibility(true);
@@ -818,9 +814,41 @@
 
         // THEN face scanning is not run
         mKeyguardUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.UDFPS_POINTER_DOWN);
-        verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
-                anyBoolean());
-        verify(mFaceManager, never()).detectFace(any(), any(), anyInt());
+        verifyFaceAuthenticateNeverCalled();
+        verifyFaceDetectNeverCalled();
+    }
+
+    @Test
+    public void noFaceRun_whenFpLockout() {
+        // GIVEN bypass is enabled, face detection is supported and strong auth is required
+        lockscreenBypassIsAllowed();
+        supportsFaceDetection();
+        strongAuthRequiredEncrypted();
+        keyguardIsVisible();
+        // fingerprint is NOT running, UDFPS is NOT supported
+
+        // GIVEN fp is locked out
+        when(mFingerprintManager.getLockoutModeForUser(eq(FINGERPRINT_SENSOR_ID), anyInt()))
+                .thenReturn(BIOMETRIC_LOCKOUT_TIMED);
+        mKeyguardUpdateMonitor.handleUserSwitchComplete(0);
+        assertThat(mKeyguardUpdateMonitor.isFingerprintLockedOut()).isEqualTo(true);
+
+        // WHEN the device wakes up
+        mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
+        mTestableLooper.processAllMessages();
+
+        // FACE detect is NOT triggered and face authenticate is NOT triggered
+        verifyFaceDetectNeverCalled();
+        verifyFaceAuthenticateNeverCalled();
+
+        // WHEN bouncer becomes visible
+        setKeyguardBouncerVisibility(true);
+        clearInvocations(mFaceManager);
+
+        // THEN face scanning is not run
+        mKeyguardUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.UDFPS_POINTER_DOWN);
+        verifyFaceAuthenticateNeverCalled();
+        verifyFaceDetectNeverCalled();
     }
 
     @Test
@@ -835,9 +863,8 @@
         mTestableLooper.processAllMessages();
 
         // FACE detect and authenticate are NOT triggered
-        verify(mFaceManager, never()).detectFace(any(), any(), anyInt());
-        verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
-                anyBoolean());
+        verifyFaceDetectNeverCalled();
+        verifyFaceAuthenticateNeverCalled();
     }
 
     @Test
@@ -875,7 +902,7 @@
         mKeyguardUpdateMonitor.setKeyguardShowing(true, true);
         mKeyguardUpdateMonitor.setAssistantVisible(true);
 
-        verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
+        verifyFaceAuthenticateCall();
     }
 
     @Test
@@ -883,12 +910,7 @@
         mKeyguardUpdateMonitor.setKeyguardShowing(false, true);
         mKeyguardUpdateMonitor.setAssistantVisible(true);
 
-        verify(mFaceManager, never()).authenticate(any(),
-                any(),
-                any(),
-                any(),
-                anyInt(),
-                anyBoolean());
+        verifyFaceAuthenticateNeverCalled();
     }
 
     @Test
@@ -899,15 +921,12 @@
 
         // THEN fingerprint shouldn't listen
         assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isFalse();
-        verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
-                anyInt(), anyInt());
-
+        verifyFingerprintAuthenticateNeverCalled();
         // WHEN alternate bouncer is shown
         mKeyguardUpdateMonitor.setAlternateBouncerShowing(true);
 
         // THEN make sure FP listening begins
-        verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
-                anyInt());
+        verifyFingerprintAuthenticateCall();
     }
 
     @Test
@@ -919,7 +938,7 @@
                 KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */,
                 new ArrayList<>());
         keyguardIsVisible();
-        verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
+        verifyFaceAuthenticateCall();
     }
 
     @Test
@@ -927,7 +946,7 @@
         mKeyguardUpdateMonitor.setKeyguardShowing(true, true);
         mKeyguardUpdateMonitor.setAssistantVisible(true);
 
-        verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
+        verifyFaceAuthenticateCall();
         mTestableLooper.processAllMessages();
         clearInvocations(mFaceManager);
 
@@ -940,12 +959,7 @@
         mKeyguardUpdateMonitor.handleKeyguardReset();
 
         assertThat(mKeyguardUpdateMonitor.isFaceDetectionRunning()).isFalse();
-        verify(mFaceManager, never()).authenticate(any(),
-                any(),
-                any(),
-                any(),
-                anyInt(),
-                anyBoolean());
+        verifyFaceAuthenticateNeverCalled();
     }
 
     @Test
@@ -955,8 +969,7 @@
         mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */, true /* newlyUnlocked */,
                 KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */, new ArrayList<>());
         keyguardIsVisible();
-        verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
-                anyBoolean());
+        verifyFaceAuthenticateNeverCalled();
     }
 
     @Test
@@ -968,9 +981,8 @@
         keyguardIsVisible();
         mTestableLooper.processAllMessages();
 
-        verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
-                anyBoolean());
-        verify(mFaceManager, never()).detectFace(any(), any(), anyInt());
+        verifyFaceAuthenticateNeverCalled();
+        verifyFaceDetectNeverCalled();
     }
 
     @Test
@@ -979,16 +991,14 @@
                 .onAuthenticationError(FingerprintManager.BIOMETRIC_ERROR_POWER_PRESSED, "");
 
         // THEN doesn't authenticate immediately
-        verify(mFingerprintManager, never()).authenticate(any(),
-                any(), any(), any(), anyInt(), anyInt(), anyInt());
+        verifyFingerprintAuthenticateNeverCalled();
 
         // WHEN all messages (with delays) are processed
         mTestableLooper.moveTimeForward(HAL_POWER_PRESS_TIMEOUT);
         mTestableLooper.processAllMessages();
 
         // THEN fingerprint manager attempts to authenticate again
-        verify(mFingerprintManager).authenticate(any(),
-                any(), any(), any(), anyInt(), anyInt(), anyInt());
+        verifyFingerprintAuthenticateCall();
     }
 
     @Test
@@ -1000,8 +1010,7 @@
         setKeyguardBouncerVisibility(true);
         mTestableLooper.processAllMessages();
 
-        verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
-                anyBoolean());
+        verifyFaceAuthenticateNeverCalled();
     }
 
     @Test
@@ -1118,9 +1127,8 @@
         mTestableLooper.processAllMessages();
         keyguardIsVisible();
 
-        verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
-        verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
-                anyInt());
+        verifyFaceAuthenticateCall();
+        verifyFingerprintAuthenticateCall();
 
         when(mFingerprintManager.getLockoutModeForUser(eq(FINGERPRINT_SENSOR_ID), eq(newUser)))
                 .thenReturn(fingerprintLockoutMode);
@@ -1148,10 +1156,11 @@
         assertThat(mKeyguardUpdateMonitor.isFingerprintLockedOut()).isEqualTo(fpLocked);
         assertThat(mKeyguardUpdateMonitor.isFaceLockedOut()).isEqualTo(faceLocked);
 
-        // Fingerprint should be restarted once its cancelled bc on lockout, the device
-        // can still detectFingerprint (and if it's not locked out, fingerprint can listen)
+        // Fingerprint should be cancelled on lockout if going to lockout state, else
+        // restarted if it's not
         assertThat(mKeyguardUpdateMonitor.mFingerprintRunningState)
-                .isEqualTo(BIOMETRIC_STATE_CANCELLING_RESTARTING);
+                .isEqualTo(fpLocked
+                        ? BIOMETRIC_STATE_CANCELLING : BIOMETRIC_STATE_CANCELLING_RESTARTING);
     }
 
     @Test
@@ -1567,10 +1576,7 @@
     public void testFaceDoesNotAuth_afterPinAttempt() {
         mTestableLooper.processAllMessages();
         mKeyguardUpdateMonitor.setCredentialAttempted();
-        verify(mFingerprintManager, never()).authenticate(any(), any(), any(),
-                any(), anyInt());
-        verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
-                anyBoolean());
+        verifyFaceAuthenticateNeverCalled();
     }
 
     @Test
@@ -1945,9 +1951,8 @@
         mTestableLooper.processAllMessages();
         keyguardIsVisible();
 
-        verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
-        verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
-                anyInt());
+        verifyFaceAuthenticateCall();
+        verifyFingerprintAuthenticateCall();
 
         mKeyguardUpdateMonitor.onFaceAuthenticated(0, false);
         // Make sure keyguard is going away after face auth attempt, and that it calls
@@ -1973,8 +1978,7 @@
         mKeyguardUpdateMonitor.dispatchDreamingStopped();
         mTestableLooper.processAllMessages();
 
-        verify(mFaceManager, never()).authenticate(
-                any(), any(), any(), any(), anyInt(), anyBoolean());
+        verifyFaceAuthenticateNeverCalled();
     }
 
     @Test
@@ -1987,15 +1991,14 @@
         mTestableLooper.processAllMessages();
 
         // THEN face auth isn't triggered
-        verify(mFaceManager, never()).authenticate(
-                any(), any(), any(), any(), anyInt(), anyBoolean());
+        verifyFaceAuthenticateNeverCalled();
 
         // WHEN device wakes up from the power button
         mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
         mTestableLooper.processAllMessages();
 
         // THEN face auth is triggered
-        verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
+        verifyFaceAuthenticateCall();
     }
 
 
@@ -2166,7 +2169,7 @@
         mTestableLooper.processAllMessages();
         keyguardIsVisible();
 
-        verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
+        verifyFaceAuthenticateCall();
         verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
                 anyInt());
 
@@ -2199,7 +2202,7 @@
         mTestableLooper.processAllMessages();
         keyguardIsVisible();
 
-        verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
+        verifyFaceAuthenticateCall();
 
         final CancellationSignal faceCancel = spy(mKeyguardUpdateMonitor.mFaceCancelSignal);
         mKeyguardUpdateMonitor.mFaceCancelSignal = faceCancel;
@@ -2375,6 +2378,91 @@
         assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
     }
 
+    @Test
+    public void unfoldWakeup_requestActiveUnlock_forceDismissKeyguard()
+            throws RemoteException {
+        // GIVEN shouldTriggerActiveUnlock
+        keyguardIsVisible();
+        when(mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())).thenReturn(true);
+
+        // GIVEN active unlock triggers on wakeup
+        when(mActiveUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE))
+                .thenReturn(true);
+
+        // GIVEN an unfold should force dismiss the keyguard
+        when(mActiveUnlockConfig.shouldWakeupForceDismissKeyguard(
+                PowerManager.WAKE_REASON_UNFOLD_DEVICE)).thenReturn(true);
+
+        // WHEN device wakes up from an unfold
+        mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNFOLD_DEVICE);
+        mTestableLooper.processAllMessages();
+
+        // THEN request unlock with a keyguard dismissal
+        verify(mTrustManager).reportUserRequestedUnlock(eq(KeyguardUpdateMonitor.getCurrentUser()),
+                eq(true));
+    }
+
+    @Test
+    public void unfoldWakeup_requestActiveUnlock_noDismissKeyguard()
+            throws RemoteException {
+        // GIVEN shouldTriggerActiveUnlock on wake from UNFOLD_DEVICE
+        keyguardIsVisible();
+        when(mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())).thenReturn(true);
+
+        // GIVEN active unlock triggers on wakeup
+        when(mActiveUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE))
+                .thenReturn(true);
+
+        // GIVEN an unfold should NOT force dismiss the keyguard
+        when(mActiveUnlockConfig.shouldWakeupForceDismissKeyguard(
+                PowerManager.WAKE_REASON_UNFOLD_DEVICE)).thenReturn(false);
+
+        // WHEN device wakes up from an unfold
+        mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNFOLD_DEVICE);
+        mTestableLooper.processAllMessages();
+
+        // THEN request unlock WITHOUT a keyguard dismissal
+        verify(mTrustManager).reportUserRequestedUnlock(eq(KeyguardUpdateMonitor.getCurrentUser()),
+                eq(false));
+    }
+
+    private void verifyFingerprintAuthenticateNeverCalled() {
+        verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
+                anyInt(), anyInt());
+    }
+
+    private void verifyFingerprintAuthenticateCall() {
+        verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
+                anyInt());
+    }
+
+    private void verifyFingerprintDetectNeverCalled() {
+        verify(mFingerprintManager, never()).detectFingerprint(any(), any(), anyInt());
+    }
+
+    private void verifyFingerprintDetectCall() {
+        verify(mFingerprintManager).detectFingerprint(any(), any(), anyInt());
+    }
+
+    private void verifyFaceAuthenticateNeverCalled() {
+        verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
+                anyBoolean());
+    }
+
+    private void verifyFaceAuthenticateCall() {
+        verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
+    }
+
+    private void verifyFaceDetectNeverCalled() {
+        verify(mFaceManager, never()).detectFace(any(), any(), anyInt());
+    }
+
+    private void verifyFaceDetectCall() {
+        verify(mFaceManager).detectFace(any(), any(), anyInt());
+    }
+
     private void userDeviceLockDown() {
         when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
         when(mStrongAuthTracker.getStrongAuthForUser(mCurrentUserId))
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
index e9a2789..9fe32f1 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
@@ -32,6 +32,7 @@
 import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito.`when`
+import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 import java.util.Optional
@@ -83,6 +84,33 @@
     }
 
     @Test
+    fun testTasksReady_onScreenTurningOnAndTurnedOnEventsCalledTogether_callsDrawnCallback() {
+        screenOnCoordinator.onScreenTurningOn(runnable)
+        screenOnCoordinator.onScreenTurnedOn()
+
+        onUnfoldOverlayReady()
+        onFoldAodReady()
+        waitHandlerIdle(testHandler)
+
+        // Should be called when both unfold overlay and keyguard drawn ready
+        verify(runnable).run()
+    }
+
+    @Test
+    fun testTasksReady_onScreenTurnedOnAndTurnedOffBeforeCompletion_doesNotCallDrawnCallback() {
+        screenOnCoordinator.onScreenTurningOn(runnable)
+        screenOnCoordinator.onScreenTurnedOn()
+        screenOnCoordinator.onScreenTurnedOff()
+
+        onUnfoldOverlayReady()
+        onFoldAodReady()
+        waitHandlerIdle(testHandler)
+
+        // Should not be called because this screen turning on call is not valid anymore
+        verify(runnable, never()).run()
+    }
+
+    @Test
     fun testUnfoldTransitionDisabledDrawnTasksReady_onScreenTurningOn_callsDrawnCallback() {
         // Recreate with empty unfoldComponent
         screenOnCoordinator = ScreenOnCoordinator(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt
index 777dd4e..ca6f426 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt
@@ -19,7 +19,7 @@
 import android.provider.Settings
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
-import android.widget.ImageView
+import android.view.ViewGroup
 import android.widget.SeekBar
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
@@ -68,14 +68,14 @@
     fun progressIsZero_clickIconEnd_seekBarProgressIncreaseOne_fontSizeScaled() {
         fontScalingDialog.show()
 
-        val iconEnd: ImageView = fontScalingDialog.findViewById(R.id.icon_end)!!
+        val iconEndFrame: ViewGroup = fontScalingDialog.findViewById(R.id.icon_end_frame)!!
         val seekBarWithIconButtonsView: SeekBarWithIconButtonsView =
             fontScalingDialog.findViewById(R.id.font_scaling_slider)!!
         val seekBar: SeekBar = fontScalingDialog.findViewById(R.id.seekbar)!!
 
         seekBarWithIconButtonsView.setProgress(0)
 
-        iconEnd.performClick()
+        iconEndFrame.performClick()
 
         val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def = */ 1.0f)
         assertThat(seekBar.getProgress()).isEqualTo(1)
@@ -88,14 +88,14 @@
     fun progressIsMax_clickIconStart_seekBarProgressDecreaseOne_fontSizeScaled() {
         fontScalingDialog.show()
 
-        val iconStart: ImageView = fontScalingDialog.findViewById(R.id.icon_start)!!
+        val iconStartFrame: ViewGroup = fontScalingDialog.findViewById(R.id.icon_start_frame)!!
         val seekBarWithIconButtonsView: SeekBarWithIconButtonsView =
             fontScalingDialog.findViewById(R.id.font_scaling_slider)!!
         val seekBar: SeekBar = fontScalingDialog.findViewById(R.id.seekbar)!!
 
         seekBarWithIconButtonsView.setProgress(fontSizeValueArray.size - 1)
 
-        iconStart.performClick()
+        iconStartFrame.performClick()
 
         val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def = */ 1.0f)
         assertThat(seekBar.getProgress()).isEqualTo(fontSizeValueArray.size - 2)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
index bce98cf..0574838 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
@@ -15,27 +15,49 @@
  */
 package com.android.systemui.biometrics
 
+import android.content.Context
 import android.hardware.biometrics.BiometricAuthenticator
+import android.hardware.biometrics.SensorLocationInternal
+import android.hardware.biometrics.SensorProperties
+import android.hardware.display.DisplayManagerGlobal
+import android.hardware.fingerprint.FingerprintManager
+import android.hardware.fingerprint.FingerprintSensorProperties
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
 import android.os.Bundle
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.testing.TestableLooper.RunWithLooper
+import android.view.Display
+import android.view.DisplayAdjustments
+import android.view.DisplayInfo
+import android.view.Surface
 import android.view.View
+import android.view.ViewGroup
 import androidx.test.filters.SmallTest
+import com.airbnb.lottie.LottieAnimationView
 import com.android.systemui.R
+import com.android.systemui.biometrics.AuthBiometricView.STATE_AUTHENTICATING_ANIMATING_IN
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.SysuiTestableContext
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers
 import org.mockito.ArgumentMatchers.eq
 import org.mockito.Mock
+import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
+import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
+import org.mockito.Mockito.`when` as whenEver
+
+private const val DISPLAY_ID = 2
+private const val SENSOR_ID = 1
 
 @RunWith(AndroidTestingRunner::class)
 @RunWithLooper(setAsMainLooper = true)
@@ -50,9 +72,22 @@
     private lateinit var callback: AuthBiometricView.Callback
 
     @Mock
+    private lateinit var fingerprintManager: FingerprintManager
+
+    @Mock
+    private lateinit var iconView: LottieAnimationView
+
+    @Mock
+    private lateinit var iconViewOverlay: LottieAnimationView
+
+    @Mock
+    private lateinit var iconLayoutParamSize: Pair<Int, Int>
+
+    @Mock
     private lateinit var panelController: AuthPanelController
 
     private lateinit var biometricView: AuthBiometricView
+    private lateinit var iconController: AuthBiometricFingerprintIconController
 
     private fun createView(allowDeviceCredential: Boolean = false): AuthBiometricFingerprintView {
         val view: AuthBiometricFingerprintView =
@@ -277,5 +312,186 @@
         verify(callback).onAction(AuthBiometricView.Callback.ACTION_USE_DEVICE_CREDENTIAL)
     }
 
+    private fun testWithSfpsDisplay(
+        isReverseDefaultRotation: Boolean = false,
+        inRearDisplayMode: Boolean = false,
+        isFolded: Boolean = false,
+        initInfo: DisplayInfo.() -> Unit = {},
+        block: () -> Unit
+    ) {
+        val displayInfo = DisplayInfo()
+        displayInfo.initInfo()
+
+        val dmGlobal = mock(DisplayManagerGlobal::class.java)
+        val display = Display(dmGlobal, DISPLAY_ID, displayInfo,
+            DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS)
+
+        whenEver(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo)
+
+        val iconControllerContext = context.createDisplayContext(display) as SysuiTestableContext
+        iconControllerContext.orCreateTestableResources.addOverride(
+            com.android.internal.R.bool.config_reverseDefaultRotation,
+            isReverseDefaultRotation
+        )
+
+        val rearDisplayDeviceStates = if (inRearDisplayMode) intArrayOf(3) else intArrayOf()
+        iconControllerContext.orCreateTestableResources.addOverride(
+            com.android.internal.R.array.config_rearDisplayDeviceStates,
+            rearDisplayDeviceStates
+        )
+
+        val layoutParams = mock(ViewGroup.LayoutParams::class.java)
+        whenEver(iconView.layoutParams).thenReturn(layoutParams)
+        whenEver(iconViewOverlay.layoutParams).thenReturn(layoutParams)
+
+        var locations = listOf(SensorLocationInternal("", 2500, 0, 0))
+        whenEver(fingerprintManager.sensorPropertiesInternal)
+            .thenReturn(
+                listOf(
+                    FingerprintSensorPropertiesInternal(
+                        SENSOR_ID,
+                        SensorProperties.STRENGTH_STRONG,
+                        5 /* maxEnrollmentsPerUser */,
+                        listOf() /* componentInfo */,
+                        FingerprintSensorProperties.TYPE_POWER_BUTTON,
+                        true /* halControlsIllumination */,
+                        true /* resetLockoutRequiresHardwareAuthToken */,
+                        locations
+                    )
+                )
+            )
+        iconControllerContext.addMockSystemService(Context.FINGERPRINT_SERVICE, fingerprintManager)
+
+        iconController = AuthBiometricFingerprintIconController(
+            iconControllerContext,
+            iconView,
+            iconViewOverlay
+        )
+        iconController.onFoldUpdated(isFolded)
+
+        biometricView.mIconController = iconController
+        block()
+    }
+
+    @Test
+    fun sfpsRearDisplay_showsCorrectAnimationAssetsAcrossRotations() {
+        testWithSfpsDisplay(
+            isReverseDefaultRotation = false,
+            inRearDisplayMode = true,
+            isFolded = false,
+            { rotation = Surface.ROTATION_0 }
+        ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
+        testWithSfpsDisplay(
+            isReverseDefaultRotation = false,
+            inRearDisplayMode = true,
+            isFolded = false,
+            { rotation = Surface.ROTATION_90 }
+        ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
+        testWithSfpsDisplay(
+            isReverseDefaultRotation = false,
+            inRearDisplayMode = true,
+            isFolded = false,
+            { rotation = Surface.ROTATION_180 }
+        ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
+        testWithSfpsDisplay(
+            isReverseDefaultRotation = false,
+            inRearDisplayMode = true,
+            isFolded = false,
+            { rotation = Surface.ROTATION_270 }
+        ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
+        val expectedLottieAssetOrder: List<Int> = listOf(
+            R.raw.biometricprompt_rear_landscape_base,
+            R.raw.biometricprompt_rear_portrait_reverse_base,
+            R.raw.biometricprompt_rear_landscape_base,
+            R.raw.biometricprompt_rear_portrait_base,
+        )
+
+        val lottieAssetCaptor: ArgumentCaptor<Int> = ArgumentCaptor.forClass(Int::class.java)
+        verify(iconView, times(4)).setAnimation(lottieAssetCaptor.capture())
+        val observedLottieAssetOrder: List<Int> = lottieAssetCaptor.getAllValues()
+        assertThat(observedLottieAssetOrder).containsExactlyElementsIn(expectedLottieAssetOrder)
+                .inOrder()
+    }
+
+    @Test
+    fun sfpsDefaultDisplayFolded_showsAnimationsAssetsCorrectlyAcrossRotations() {
+        testWithSfpsDisplay(
+            isReverseDefaultRotation = false,
+            inRearDisplayMode = false,
+            isFolded = true,
+            { rotation = Surface.ROTATION_0 }
+        ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
+            testWithSfpsDisplay(
+            isReverseDefaultRotation = false,
+            inRearDisplayMode = false,
+            isFolded = true,
+            { rotation = Surface.ROTATION_90 }
+        ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN); }
+            testWithSfpsDisplay(
+            isReverseDefaultRotation = false,
+            inRearDisplayMode = false,
+            isFolded = true,
+            { rotation = Surface.ROTATION_180 }
+        ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN); }
+            testWithSfpsDisplay(
+            isReverseDefaultRotation = false,
+            inRearDisplayMode = false,
+            isFolded = true,
+            { rotation = Surface.ROTATION_270 }
+        ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN); }
+        val expectedLottieAssetOrder: List<Int> = listOf(
+            R.raw.biometricprompt_folded_base_default,
+            R.raw.biometricprompt_folded_base_topleft,
+            R.raw.biometricprompt_folded_base_default,
+            R.raw.biometricprompt_folded_base_bottomright,
+        )
+
+        val lottieAssetCaptor: ArgumentCaptor<Int> = ArgumentCaptor.forClass(Int::class.java)
+        verify(iconView, times(4)).setAnimation(lottieAssetCaptor.capture())
+        val observedLottieAssetOrder: List<Int> = lottieAssetCaptor.getAllValues()
+        assertThat(observedLottieAssetOrder).containsExactlyElementsIn(expectedLottieAssetOrder)
+                .inOrder()
+    }
+
+    @Test
+    fun sfpsDefaultDisplayUnfolded_showsAnimationsAssetsCorrectlyAcrossRotations() {
+        testWithSfpsDisplay(
+            isReverseDefaultRotation = false,
+            inRearDisplayMode = false,
+            isFolded = false,
+            { rotation = Surface.ROTATION_0 }
+        ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
+        testWithSfpsDisplay(
+            isReverseDefaultRotation = false,
+            inRearDisplayMode = false,
+            isFolded = false,
+            { rotation = Surface.ROTATION_90 }
+        ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
+        testWithSfpsDisplay(
+            isReverseDefaultRotation = false,
+            inRearDisplayMode = false,
+            isFolded = false,
+            { rotation = Surface.ROTATION_180 }
+        ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
+        testWithSfpsDisplay(
+            isReverseDefaultRotation = false,
+            inRearDisplayMode = false,
+            isFolded = false,
+            { rotation = Surface.ROTATION_270 }
+        ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
+        val expectedLottieAssetOrder: List<Int> = listOf(
+            R.raw.biometricprompt_landscape_base,
+            R.raw.biometricprompt_portrait_base_topleft,
+            R.raw.biometricprompt_landscape_base,
+            R.raw.biometricprompt_portrait_base_bottomright,
+        )
+
+        val lottieAssetCaptor: ArgumentCaptor<Int> = ArgumentCaptor.forClass(Int::class.java)
+        verify(iconView, times(4)).setAnimation(lottieAssetCaptor.capture())
+        val observedLottieAssetOrder: List<Int> = lottieAssetCaptor.getAllValues()
+        assertThat(observedLottieAssetOrder).containsExactlyElementsIn(expectedLottieAssetOrder)
+                .inOrder()
+    }
+
     override fun waitForIdleSync() = TestableLooper.get(this).processAllMessages()
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index ace0ccb..489efd71 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -25,6 +25,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotSame;
 import static junit.framework.Assert.assertNull;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -33,6 +34,7 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -49,6 +51,7 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.Point;
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricConstants;
@@ -166,6 +169,8 @@
     private ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
     @Captor
     private ArgumentCaptor<WakefulnessLifecycle.Observer> mWakefullnessObserverCaptor;
+    @Mock
+    private Resources mResources;
 
     private TestableContext mContextSpy;
     private Execution mExecution;
@@ -879,6 +884,25 @@
         );
     }
 
+    @Test
+    public void testUpdateFingerprintLocation_defaultPointChanges_whenConfigChanges() {
+        when(mContextSpy.getResources()).thenReturn(mResources);
+
+        doReturn(500).when(mResources)
+                .getDimensionPixelSize(eq(com.android.systemui.R.dimen
+                        .physical_fingerprint_sensor_center_screen_location_y));
+        mAuthController.onConfigurationChanged(null /* newConfig */);
+
+        final Point firstFpLocation = mAuthController.getFingerprintSensorLocation();
+
+        doReturn(1000).when(mResources)
+                .getDimensionPixelSize(eq(com.android.systemui.R.dimen
+                        .physical_fingerprint_sensor_center_screen_location_y));
+        mAuthController.onConfigurationChanged(null /* newConfig */);
+
+        assertNotSame(firstFpLocation, mAuthController.getFingerprintSensorLocation());
+    }
+
     private void showDialog(int[] sensorIds, boolean credentialAllowed) {
         mAuthController.showAuthenticationDialog(createTestPromptInfo(),
                 mReceiver /* receiver */,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
index 612e557..6333a68 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
@@ -63,6 +63,7 @@
 import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
 import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
 import com.android.systemui.recents.OverviewProxyService
+import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
@@ -97,6 +98,7 @@
 
     @JvmField @Rule var rule = MockitoJUnit.rule()
 
+    @Mock lateinit var keyguardStateController: KeyguardStateController
     @Mock lateinit var layoutInflater: LayoutInflater
     @Mock lateinit var fingerprintManager: FingerprintManager
     @Mock lateinit var windowManager: WindowManager
@@ -136,6 +138,7 @@
         keyguardBouncerRepository = FakeKeyguardBouncerRepository()
         alternateBouncerInteractor =
             AlternateBouncerInteractor(
+                keyguardStateController,
                 keyguardBouncerRepository,
                 FakeBiometricSettingsRepository(),
                 FakeDeviceEntryFingerprintAuthRepository(),
@@ -169,6 +172,7 @@
         isReverseDefaultRotation: Boolean = false,
         initInfo: DisplayInfo.() -> Unit = {},
         windowInsets: WindowInsets = insetsForSmallNavbar(),
+        inRearDisplayMode: Boolean = false,
         block: () -> Unit
     ) {
         this.deviceConfig = deviceConfig
@@ -229,6 +233,12 @@
             isReverseDefaultRotation
         )
 
+        val rearDisplayDeviceStates = if (inRearDisplayMode) intArrayOf(3) else intArrayOf()
+        sideFpsControllerContext.orCreateTestableResources.addOverride(
+            com.android.internal.R.array.config_rearDisplayDeviceStates,
+            rearDisplayDeviceStates
+        )
+
         sideFpsController =
             SideFpsController(
                 sideFpsControllerContext,
@@ -542,10 +552,62 @@
             { rotation = Surface.ROTATION_270 }
         ) { verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true) }
 
+    @Test
+    fun verifiesSfpsIndicatorNotAddedInRearDisplayMode_0() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_0 },
+            inRearDisplayMode = true,
+        ) {
+            verifySfpsIndicator_notAdded_InRearDisplayMode()
+        }
+
+    @Test
+    fun verifiesSfpsIndicatorNotAddedInRearDisplayMode_90() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_90 },
+            inRearDisplayMode = true,
+        ) {
+            verifySfpsIndicator_notAdded_InRearDisplayMode()
+        }
+
+    @Test
+    fun verifiesSfpsIndicatorNotAddedInRearDisplayMode_180() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_180 },
+            inRearDisplayMode = true,
+        ) {
+            verifySfpsIndicator_notAdded_InRearDisplayMode()
+        }
+
+    @Test
+    fun verifiesSfpsIndicatorNotAddedInRearDisplayMode_270() =
+        testWithDisplay(
+            deviceConfig = DeviceConfig.Y_ALIGNED,
+            isReverseDefaultRotation = false,
+            { rotation = Surface.ROTATION_270 },
+            inRearDisplayMode = true,
+        ) {
+            verifySfpsIndicator_notAdded_InRearDisplayMode()
+        }
+
     private fun verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible: Boolean) {
         sideFpsController.overlayOffsets = sensorLocation
     }
 
+    private fun verifySfpsIndicator_notAdded_InRearDisplayMode() {
+        sideFpsController.overlayOffsets = sensorLocation
+        overlayController.show(SENSOR_ID, REASON_UNKNOWN)
+        executor.runAllReady()
+
+        verify(windowManager, never()).addView(any(), any())
+    }
+
     fun alternateBouncerVisibility_showAndHideSideFpsUI() = testWithDisplay {
         // WHEN alternate bouncer is visible
         keyguardBouncerRepository.setAlternateVisible(true)
@@ -582,7 +644,7 @@
      * in other rotations have been omitted.
      */
     @Test
-    fun verifiesIndicatorPlacementForXAlignedSensor_0() {
+    fun verifiesIndicatorPlacementForXAlignedSensor_0() =
         testWithDisplay(
             deviceConfig = DeviceConfig.X_ALIGNED,
             isReverseDefaultRotation = false,
@@ -599,7 +661,6 @@
             assertThat(overlayViewParamsCaptor.value.x).isEqualTo(sensorLocation.sensorLocationX)
             assertThat(overlayViewParamsCaptor.value.y).isEqualTo(0)
         }
-    }
 
     /**
      * {@link SideFpsController#updateOverlayParams} calculates indicator placement for ROTATION_270
@@ -608,7 +669,7 @@
      * correctly, tests for indicator placement in other rotations have been omitted.
      */
     @Test
-    fun verifiesIndicatorPlacementForXAlignedSensor_InReverseDefaultRotation_270() {
+    fun verifiesIndicatorPlacementForXAlignedSensor_InReverseDefaultRotation_270() =
         testWithDisplay(
             deviceConfig = DeviceConfig.X_ALIGNED,
             isReverseDefaultRotation = true,
@@ -625,7 +686,6 @@
             assertThat(overlayViewParamsCaptor.value.x).isEqualTo(sensorLocation.sensorLocationX)
             assertThat(overlayViewParamsCaptor.value.y).isEqualTo(0)
         }
-    }
 
     /**
      * {@link SideFpsController#updateOverlayParams} calculates indicator placement for ROTATION_0,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt
index c73ff1d..86fb279 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt
@@ -37,6 +37,7 @@
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.time.FakeSystemClock
 import com.android.systemui.util.time.SystemClock
 import kotlinx.coroutines.Dispatchers
@@ -86,11 +87,13 @@
                 mock(PrimaryBouncerCallbackInteractor::class.java),
                 mock(FalsingCollector::class.java),
                 mock(DismissCallbackRegistry::class.java),
+                context,
+                mKeyguardUpdateMonitor,
                 mock(KeyguardBypassController::class.java),
-                mKeyguardUpdateMonitor
             )
         mAlternateBouncerInteractor =
             AlternateBouncerInteractor(
+                mock(KeyguardStateController::class.java),
                 keyguardBouncerRepository,
                 mock(BiometricSettingsRepository::class.java),
                 mock(DeviceEntryFingerprintAuthRepository::class.java),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java
index a61cecb..3503902 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java
@@ -20,14 +20,14 @@
 
 import static org.mockito.Mockito.mock;
 
-import androidx.test.filters.SmallTest;
-
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.View;
 import android.widget.Button;
 import android.widget.TextView;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
@@ -44,18 +44,21 @@
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class BroadcastDialogTest extends SysuiTestCase {
 
-    private static final String SWITCH_APP = "Music";
+    private static final String CURRENT_BROADCAST_APP = "Music";
+    private static final String SWITCH_APP = "Files by Google";
     private static final String TEST_PACKAGE = "com.google.android.apps.nbu.files";
     private BroadcastDialog mBroadcastDialog;
     private View mDialogView;
+    private TextView mTitle;
     private TextView mSubTitle;
+    private Button mSwitchBroadcastAppButton;
     private Button mChangeOutputButton;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mBroadcastDialog = new BroadcastDialog(mContext, mock(MediaOutputDialogFactory.class),
-                SWITCH_APP, TEST_PACKAGE, mock(UiEventLogger.class));
+                CURRENT_BROADCAST_APP, TEST_PACKAGE, mock(UiEventLogger.class));
         mBroadcastDialog.show();
         mDialogView = mBroadcastDialog.mDialogView;
     }
@@ -66,7 +69,15 @@
     }
 
     @Test
-    public void onCreate_withCurrentApp_checkSwitchAppContent() {
+    public void onCreate_withCurrentApp_titleIsCurrentAppName() {
+        mTitle = mDialogView.requireViewById(R.id.dialog_title);
+
+        assertThat(mTitle.getText().toString()).isEqualTo(mContext.getString(
+                R.string.bt_le_audio_broadcast_dialog_title, CURRENT_BROADCAST_APP));
+    }
+
+    @Test
+    public void onCreate_withCurrentApp_subTitleIsSwitchAppName() {
         mSubTitle = mDialogView.requireViewById(R.id.dialog_subtitle);
 
         assertThat(mSubTitle.getText()).isEqualTo(
@@ -74,6 +85,14 @@
     }
 
     @Test
+    public void onCreate_withCurrentApp_switchBtnIsSwitchAppName() {
+        mSwitchBroadcastAppButton = mDialogView.requireViewById(R.id.switch_broadcast);
+
+        assertThat(mSwitchBroadcastAppButton.getText().toString()).isEqualTo(
+                mContext.getString(R.string.bt_le_audio_broadcast_dialog_switch_app, SWITCH_APP));
+    }
+
+    @Test
     public void onClick_withChangeOutput_dismissBroadcastDialog() {
         mChangeOutputButton = mDialogView.requireViewById(R.id.change_output);
         mChangeOutputButton.performClick();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
index e4df754..8cb9130 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
@@ -106,7 +106,7 @@
         mClassifiers.add(mClassifierB);
         when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList);
         when(mKeyguardStateController.isShowing()).thenReturn(true);
-        when(mFalsingDataProvider.isFolded()).thenReturn(true);
+        when(mFalsingDataProvider.isUnfolded()).thenReturn(false);
         mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider,
                 mMetricsLogger, mClassifiers, mSingleTapClassfier, mLongTapClassifier,
                 mDoubleTapClassifier, mHistoryTracker, mKeyguardStateController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
index ae38eb6..315774a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
@@ -89,7 +89,7 @@
         mClassifiers.add(mClassifierA);
         when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList);
         when(mKeyguardStateController.isShowing()).thenReturn(true);
-        when(mFalsingDataProvider.isFolded()).thenReturn(true);
+        when(mFalsingDataProvider.isUnfolded()).thenReturn(false);
         mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider,
                 mMetricsLogger, mClassifiers, mSingleTapClassifier, mLongTapClassifier,
                 mDoubleTapClassifier, mHistoryTracker, mKeyguardStateController,
@@ -185,7 +185,7 @@
     @Test
     public void testSkipUnfolded() {
         assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue();
-        when(mFalsingDataProvider.isFolded()).thenReturn(false);
+        when(mFalsingDataProvider.isUnfolded()).thenReturn(true);
         assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse();
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
index c451a1e7..2edc3d3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
@@ -324,12 +324,18 @@
     @Test
     public void test_FoldedState_Folded() {
         when(mFoldStateListener.getFolded()).thenReturn(true);
-        assertThat(mDataProvider.isFolded()).isTrue();
+        assertThat(mDataProvider.isUnfolded()).isFalse();
     }
 
     @Test
     public void test_FoldedState_Unfolded() {
         when(mFoldStateListener.getFolded()).thenReturn(false);
-        assertThat(mDataProvider.isFolded()).isFalse();
+        assertThat(mDataProvider.isUnfolded()).isTrue();
+    }
+
+    @Test
+    public void test_FoldedState_NotFoldable() {
+        when(mFoldStateListener.getFolded()).thenReturn(null);
+        assertThat(mDataProvider.isUnfolded()).isFalse();
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java
index 2ed0346..eafe727 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java
@@ -20,6 +20,7 @@
 
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.SeekBar;
 
@@ -42,6 +43,8 @@
 
     private ImageView mIconStart;
     private ImageView mIconEnd;
+    private ViewGroup mIconStartFrame;
+    private ViewGroup mIconEndFrame;
     private SeekBar mSeekbar;
     private SeekBarWithIconButtonsView mIconDiscreteSliderLinearLayout;
 
@@ -50,6 +53,8 @@
         mIconDiscreteSliderLinearLayout = new SeekBarWithIconButtonsView(mContext);
         mIconStart = mIconDiscreteSliderLinearLayout.findViewById(R.id.icon_start);
         mIconEnd = mIconDiscreteSliderLinearLayout.findViewById(R.id.icon_end);
+        mIconStartFrame = mIconDiscreteSliderLinearLayout.findViewById(R.id.icon_start_frame);
+        mIconEndFrame = mIconDiscreteSliderLinearLayout.findViewById(R.id.icon_end_frame);
         mSeekbar = mIconDiscreteSliderLinearLayout.findViewById(R.id.seekbar);
     }
 
@@ -59,6 +64,8 @@
 
         assertThat(mIconStart.isEnabled()).isFalse();
         assertThat(mIconEnd.isEnabled()).isTrue();
+        assertThat(mIconStartFrame.isEnabled()).isFalse();
+        assertThat(mIconEndFrame.isEnabled()).isTrue();
     }
 
     @Test
@@ -67,6 +74,8 @@
 
         assertThat(mIconEnd.isEnabled()).isFalse();
         assertThat(mIconStart.isEnabled()).isTrue();
+        assertThat(mIconEndFrame.isEnabled()).isFalse();
+        assertThat(mIconStartFrame.isEnabled()).isTrue();
     }
 
     @Test
@@ -77,12 +86,15 @@
 
         assertThat(mIconStart.isEnabled()).isTrue();
         assertThat(mIconEnd.isEnabled()).isTrue();
+        assertThat(mIconStartFrame.isEnabled()).isTrue();
+        assertThat(mIconEndFrame.isEnabled()).isTrue();
     }
 
     @Test
     public void clickIconEnd_currentProgressIsOneToMax_reachesMax() {
         mIconDiscreteSliderLinearLayout.setProgress(mSeekbar.getMax() - 1);
-        mIconEnd.performClick();
+
+        mIconEndFrame.performClick();
 
         assertThat(mSeekbar.getProgress()).isEqualTo(mSeekbar.getMax());
     }
@@ -90,7 +102,8 @@
     @Test
     public void clickIconStart_currentProgressIsOne_reachesZero() {
         mIconDiscreteSliderLinearLayout.setProgress(1);
-        mIconStart.performClick();
+
+        mIconStartFrame.performClick();
 
         assertThat(mSeekbar.getProgress()).isEqualTo(0);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
index 85f9961..aa90e2a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
@@ -29,6 +29,7 @@
 import android.util.AttributeSet
 import android.view.LayoutInflater
 import android.view.View
+import android.view.ViewGroup
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
@@ -328,7 +329,7 @@
             )
             .isTrue()
 
-        underTest.hide()
+        underTest.hide(parent)
 
         clearInvocations(controlsListingController, taskViewFactory)
         controlsSettingsRepository.setAllowActionOnTrivialControlsInLockscreen(false)
@@ -387,6 +388,28 @@
         assertThat(underTest.resolveActivity()).isEqualTo(ControlsActivity::class.java)
     }
 
+    @Test
+    fun testRemoveViewsOnlyForParentPassedInHide() {
+        underTest.show(parent, {}, context)
+        parent.addView(View(context))
+
+        val mockParent: ViewGroup = mock()
+
+        underTest.hide(mockParent)
+
+        verify(mockParent).removeAllViews()
+        assertThat(parent.childCount).isGreaterThan(0)
+    }
+
+    @Test
+    fun testHideDifferentParentDoesntCancelListeners() {
+        underTest.show(parent, {}, context)
+        underTest.hide(mock())
+
+        verify(controlsController, never()).unsubscribe()
+        verify(controlsListingController, never()).removeCallback(any())
+    }
+
     private fun setUpPanel(panel: SelectedItem.PanelItem): ControlsServiceInfo {
         val activity = ComponentName("pkg", "activity")
         sharedPreferences
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
index dfb4d5b..1820f64 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
@@ -20,6 +20,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -190,6 +191,31 @@
         verify(mWindowManager).addView(any(), any());
     }
 
+    // Validates that {@link DreamOverlayService} properly handles the case where the dream's
+    // window is no longer valid by the time start is called.
+    @Test
+    public void testInvalidWindowAddStart() throws Exception {
+        final IDreamOverlayClient client = getClient();
+
+        doThrow(new WindowManager.BadTokenException()).when(mWindowManager).addView(any(), any());
+        // Inform the overlay service of dream starting.
+        client.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT,
+                false /*shouldShowComplication*/);
+        mMainExecutor.runAllReady();
+
+        verify(mWindowManager).addView(any(), any());
+
+        verify(mStateController).setOverlayActive(false);
+        verify(mStateController).setLowLightActive(false);
+        verify(mStateController).setEntryAnimationsFinished(false);
+
+        verify(mStateController, never()).setOverlayActive(true);
+        verify(mUiEventLogger, never()).log(
+                DreamOverlayService.DreamOverlayEvent.DREAM_OVERLAY_COMPLETE_START);
+
+        verify(mDreamOverlayCallbackController, never()).onStartDream();
+    }
+
     @Test
     public void testDreamOverlayContainerViewControllerInitialized() throws Exception {
         final IDreamOverlayClient client = getClient();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java
index ef62abf..175da0b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java
@@ -33,6 +33,8 @@
 import com.android.systemui.condition.SelfExecutingMonitor;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.BcSmartspaceDataPlugin;
 import com.android.systemui.shared.condition.Condition;
 import com.android.systemui.shared.condition.Monitor;
@@ -65,6 +67,9 @@
     @Mock
     private View mBcSmartspaceView;
 
+    @Mock
+    private FeatureFlags mFeatureFlags;
+
     private Monitor mMonitor;
 
     private final Set<Condition> mPreconditions = new HashSet<>();
@@ -73,6 +78,8 @@
     public void setup() {
         MockitoAnnotations.initMocks(this);
         mMonitor = SelfExecutingMonitor.createInstance();
+
+        when(mFeatureFlags.isEnabled(Flags.HIDE_SMARTSPACE_ON_DREAM_OVERLAY)).thenReturn(false);
     }
 
     /**
@@ -85,12 +92,22 @@
         verify(mDreamOverlayStateController, never()).addComplication(eq(mComplication));
     }
 
-    private SmartSpaceComplication.Registrant getRegistrant() {
-        return new SmartSpaceComplication.Registrant(
-                mDreamOverlayStateController,
-                mComplication,
-                mSmartspaceController,
-                mMonitor);
+    @Test
+    public void testRegistrantStart_featureEnabled_addOverlayStateCallback() {
+        final SmartSpaceComplication.Registrant registrant = getRegistrant();
+        registrant.start();
+
+        verify(mDreamOverlayStateController).addCallback(any());
+    }
+
+    @Test
+    public void testRegistrantStart_featureDisabled_doesNotAddOverlayStateCallback() {
+        when(mFeatureFlags.isEnabled(Flags.HIDE_SMARTSPACE_ON_DREAM_OVERLAY)).thenReturn(true);
+
+        final SmartSpaceComplication.Registrant registrant = getRegistrant();
+        registrant.start();
+
+        verify(mDreamOverlayStateController, never()).addCallback(any());
     }
 
     @Test
@@ -188,4 +205,13 @@
         when(mSmartspaceController.buildAndConnectView(any())).thenReturn(mBcSmartspaceView);
         assertEquals(viewHolder.getView(), viewHolder.getView());
     }
+
+    private SmartSpaceComplication.Registrant getRegistrant() {
+        return new SmartSpaceComplication.Registrant(
+                mDreamOverlayStateController,
+                mComplication,
+                mSmartspaceController,
+                mMonitor,
+                mFeatureFlags);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt
new file mode 100644
index 0000000..de0e511
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.flags
+
+import android.os.PowerManager
+import android.test.suitebuilder.annotation.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.util.settings.FakeSettings
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.mockito.ArgumentCaptor
+import org.mockito.Mock
+import org.mockito.Mockito.anyLong
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+class RestartDozeListenerTest : SysuiTestCase() {
+
+    lateinit var restartDozeListener: RestartDozeListener
+
+    val settings = FakeSettings()
+    @Mock lateinit var statusBarStateController: StatusBarStateController
+    @Mock lateinit var powerManager: PowerManager
+    val clock = FakeSystemClock()
+    lateinit var listener: StatusBarStateController.StateListener
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        restartDozeListener =
+            RestartDozeListener(settings, statusBarStateController, powerManager, clock)
+
+        val captor = ArgumentCaptor.forClass(StatusBarStateController.StateListener::class.java)
+        restartDozeListener.init()
+        verify(statusBarStateController).addCallback(captor.capture())
+        listener = captor.value
+    }
+
+    @Test
+    fun testStoreDreamState_onDreamingStarted() {
+        listener.onDreamingChanged(true)
+        assertThat(settings.getBool(RestartDozeListener.RESTART_NAP_KEY)).isTrue()
+    }
+
+    @Test
+    fun testStoreDreamState_onDreamingStopped() {
+        listener.onDreamingChanged(false)
+        assertThat(settings.getBool(RestartDozeListener.RESTART_NAP_KEY)).isFalse()
+    }
+
+    @Test
+    fun testRestoreDreamState_dreamingShouldStart() {
+        settings.putBool(RestartDozeListener.RESTART_NAP_KEY, true)
+        restartDozeListener.maybeRestartSleep()
+        verify(powerManager).wakeUp(clock.uptimeMillis())
+        verify(powerManager).goToSleep(clock.uptimeMillis())
+    }
+
+    @Test
+    fun testRestoreDreamState_dreamingShouldNot() {
+        settings.putBool(RestartDozeListener.RESTART_NAP_KEY, false)
+        restartDozeListener.maybeRestartSleep()
+        verify(powerManager, never()).wakeUp(anyLong())
+        verify(powerManager, never()).goToSleep(anyLong())
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt
index 4ebf974..2e98006 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt
@@ -26,6 +26,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
+import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
@@ -50,12 +51,24 @@
 
     @Test
     fun testChange_alertsListener() {
+        val flag = ReleasedFlag(1, "flag_1", "test")
+        serverFlagReader.listenForChanges(listOf(flag), changeListener)
+
+        deviceConfig.setProperty(NAMESPACE, "flag_1", "1", false)
+        executor.runAllReady()
+
+        verify(changeListener).onChange(flag)
+    }
+
+    @Test
+    fun testChange_ignoresListenersDuringTest() {
+        val serverFlagReader = ServerFlagReaderImpl(NAMESPACE, deviceConfig, executor, true)
         val flag = ReleasedFlag(1, "1", "test")
         serverFlagReader.listenForChanges(listOf(flag), changeListener)
 
         deviceConfig.setProperty(NAMESPACE, "flag_override_1", "1", false)
         executor.runAllReady()
 
-        verify(changeListener).onChange(flag)
+        verify(changeListener, never()).onChange(flag)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt
new file mode 100644
index 0000000..f6ff4b2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyboard.data.repository
+
+import android.hardware.input.InputManager
+import android.view.InputDevice
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.nullable
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+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.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class KeyboardRepositoryTest : SysuiTestCase() {
+
+    @Captor
+    private lateinit var deviceListenerCaptor: ArgumentCaptor<InputManager.InputDeviceListener>
+    @Mock private lateinit var inputManager: InputManager
+
+    private lateinit var underTest: KeyboardRepository
+    private lateinit var dispatcher: CoroutineDispatcher
+    private lateinit var testScope: TestScope
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf())
+        whenever(inputManager.getInputDevice(any())).then { invocation ->
+            val id = invocation.arguments.first()
+            INPUT_DEVICES_MAP[id]
+        }
+        dispatcher = StandardTestDispatcher()
+        testScope = TestScope(dispatcher)
+        underTest = KeyboardRepositoryImpl(testScope.backgroundScope, dispatcher, inputManager)
+    }
+
+    @Test
+    fun emitsDisconnected_ifNothingIsConnected() =
+        testScope.runTest {
+            val initialState = underTest.keyboardConnected.first()
+            assertThat(initialState).isFalse()
+        }
+
+    @Test
+    fun emitsConnected_ifKeyboardAlreadyConnectedAtTheStart() =
+        testScope.runTest {
+            whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(PHYSICAL_FULL_KEYBOARD_ID))
+            val initialValue = underTest.keyboardConnected.first()
+            assertThat(initialValue).isTrue()
+        }
+
+    @Test
+    fun emitsConnected_whenNewPhysicalKeyboardConnects() =
+        testScope.runTest {
+            val deviceListener = captureDeviceListener()
+            val isKeyboardConnected by collectLastValue(underTest.keyboardConnected)
+
+            deviceListener.onInputDeviceAdded(PHYSICAL_FULL_KEYBOARD_ID)
+
+            assertThat(isKeyboardConnected).isTrue()
+        }
+
+    @Test
+    fun emitsDisconnected_whenKeyboardDisconnects() =
+        testScope.runTest {
+            val deviceListener = captureDeviceListener()
+            val isKeyboardConnected by collectLastValue(underTest.keyboardConnected)
+
+            deviceListener.onInputDeviceAdded(PHYSICAL_FULL_KEYBOARD_ID)
+            assertThat(isKeyboardConnected).isTrue()
+
+            deviceListener.onInputDeviceRemoved(PHYSICAL_FULL_KEYBOARD_ID)
+            assertThat(isKeyboardConnected).isFalse()
+        }
+
+    private suspend fun captureDeviceListener(): InputManager.InputDeviceListener {
+        underTest.keyboardConnected.first()
+        verify(inputManager).registerInputDeviceListener(deviceListenerCaptor.capture(), nullable())
+        return deviceListenerCaptor.value
+    }
+
+    @Test
+    fun emitsDisconnected_whenVirtualOrNotFullKeyboardConnects() =
+        testScope.runTest {
+            val deviceListener = captureDeviceListener()
+            val isKeyboardConnected by collectLastValue(underTest.keyboardConnected)
+
+            deviceListener.onInputDeviceAdded(PHYSICAL_NOT_FULL_KEYBOARD_ID)
+            assertThat(isKeyboardConnected).isFalse()
+
+            deviceListener.onInputDeviceAdded(VIRTUAL_FULL_KEYBOARD_ID)
+            assertThat(isKeyboardConnected).isFalse()
+        }
+
+    @Test
+    fun emitsDisconnected_whenKeyboardDisconnectsAndWasAlreadyConnectedAtTheStart() =
+        testScope.runTest {
+            val deviceListener = captureDeviceListener()
+            val isKeyboardConnected by collectLastValue(underTest.keyboardConnected)
+
+            deviceListener.onInputDeviceRemoved(PHYSICAL_FULL_KEYBOARD_ID)
+            assertThat(isKeyboardConnected).isFalse()
+        }
+
+    @Test
+    fun emitsConnected_whenAnotherDeviceDisconnects() =
+        testScope.runTest {
+            val deviceListener = captureDeviceListener()
+            val isKeyboardConnected by collectLastValue(underTest.keyboardConnected)
+
+            deviceListener.onInputDeviceAdded(PHYSICAL_FULL_KEYBOARD_ID)
+            deviceListener.onInputDeviceRemoved(VIRTUAL_FULL_KEYBOARD_ID)
+
+            assertThat(isKeyboardConnected).isTrue()
+        }
+
+    @Test
+    fun emitsConnected_whenOnePhysicalKeyboardDisconnectsButAnotherRemainsConnected() =
+        testScope.runTest {
+            val deviceListener = captureDeviceListener()
+            val isKeyboardConnected by collectLastValue(underTest.keyboardConnected)
+
+            deviceListener.onInputDeviceAdded(PHYSICAL_FULL_KEYBOARD_ID)
+            deviceListener.onInputDeviceAdded(ANOTHER_PHYSICAL_FULL_KEYBOARD_ID)
+            deviceListener.onInputDeviceRemoved(ANOTHER_PHYSICAL_FULL_KEYBOARD_ID)
+
+            assertThat(isKeyboardConnected).isTrue()
+        }
+
+    @Test
+    fun passesKeyboardBacklightValues_fromBacklightListener() {
+        // TODO(b/268645734): implement when implementing backlight listener
+    }
+
+    private companion object {
+        private const val PHYSICAL_FULL_KEYBOARD_ID = 1
+        private const val VIRTUAL_FULL_KEYBOARD_ID = 2
+        private const val PHYSICAL_NOT_FULL_KEYBOARD_ID = 3
+        private const val ANOTHER_PHYSICAL_FULL_KEYBOARD_ID = 4
+
+        private val INPUT_DEVICES_MAP: Map<Int, InputDevice> =
+            mapOf(
+                PHYSICAL_FULL_KEYBOARD_ID to inputDevice(virtual = false, fullKeyboard = true),
+                VIRTUAL_FULL_KEYBOARD_ID to inputDevice(virtual = true, fullKeyboard = true),
+                PHYSICAL_NOT_FULL_KEYBOARD_ID to inputDevice(virtual = false, fullKeyboard = false),
+                ANOTHER_PHYSICAL_FULL_KEYBOARD_ID to
+                    inputDevice(virtual = false, fullKeyboard = true)
+            )
+
+        private fun inputDevice(virtual: Boolean, fullKeyboard: Boolean): InputDevice =
+            mock<InputDevice>().also {
+                whenever(it.isVirtual).thenReturn(virtual)
+                whenever(it.isFullKeyboard).thenReturn(fullKeyboard)
+            }
+    }
+}
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 15a454b..a4e5bca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -17,6 +17,7 @@
 
 package com.android.systemui.keyguard
 
+import android.app.admin.DevicePolicyManager
 import android.content.ContentValues
 import android.content.pm.PackageManager
 import android.content.pm.ProviderInfo
@@ -61,7 +62,6 @@
 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.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
@@ -90,6 +90,7 @@
     @Mock private lateinit var previewSurfacePackage: SurfaceControlViewHost.SurfacePackage
     @Mock private lateinit var launchAnimator: DialogLaunchAnimator
     @Mock private lateinit var commandQueue: CommandQueue
+    @Mock private lateinit var devicePolicyManager: DevicePolicyManager
 
     private lateinit var underTest: CustomizationProvider
     private lateinit var testScope: TestScope
@@ -102,7 +103,7 @@
         whenever(backgroundHandler.looper).thenReturn(TestableLooper.get(this).looper)
 
         underTest = CustomizationProvider()
-        val testDispatcher = StandardTestDispatcher()
+        val testDispatcher = UnconfinedTestDispatcher()
         testScope = TestScope(testDispatcher)
         val localUserSelectionManager =
             KeyguardQuickAffordanceLocalUserSelectionManager(
@@ -183,6 +184,8 @@
                 featureFlags = featureFlags,
                 repository = { quickAffordanceRepository },
                 launchAnimator = launchAnimator,
+                devicePolicyManager = devicePolicyManager,
+                backgroundDispatcher = testDispatcher,
             )
         underTest.previewManager =
             KeyguardRemotePreviewManager(
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 f55b866..c93e677 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -29,7 +29,6 @@
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -67,7 +66,6 @@
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.NotificationShadeWindowControllerImpl;
@@ -137,7 +135,6 @@
     private @Mock AuthController mAuthController;
     private @Mock ShadeExpansionStateManager mShadeExpansionStateManager;
     private @Mock ShadeWindowLogger mShadeWindowLogger;
-    private @Mock FeatureFlags mFeatureFlags;
     private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
     private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
 
@@ -545,7 +542,6 @@
                 mScreenOnCoordinator,
                 mInteractionJankMonitor,
                 mDreamOverlayStateController,
-                mFeatureFlags,
                 () -> mShadeController,
                 () -> mNotificationShadeWindowController,
                 () -> mActivityLaunchAnimator,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
index 21ad5e2..5dc04f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
@@ -30,6 +30,7 @@
 import com.android.internal.widget.LockPatternUtils
 import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED
 import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
+import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.AuthController
 import com.android.systemui.coroutines.collectLastValue
@@ -38,11 +39,14 @@
 import com.android.systemui.keyguard.data.repository.BiometricType.REAR_FINGERPRINT
 import com.android.systemui.keyguard.data.repository.BiometricType.SIDE_FINGERPRINT
 import com.android.systemui.keyguard.data.repository.BiometricType.UNDER_DISPLAY_FINGERPRINT
+import com.android.systemui.keyguard.shared.model.DevicePosture
+import com.android.systemui.statusbar.policy.DevicePostureController
 import com.android.systemui.user.data.repository.FakeUserRepository
 import com.android.systemui.util.mockito.argumentCaptor
 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
@@ -62,6 +66,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @RunWith(AndroidTestingRunner::class)
@@ -78,6 +83,7 @@
     private lateinit var biometricManagerCallback:
         ArgumentCaptor<IBiometricEnabledOnKeyguardCallback.Stub>
     private lateinit var userRepository: FakeUserRepository
+    private lateinit var devicePostureRepository: FakeDevicePostureRepository
 
     private lateinit var testDispatcher: TestDispatcher
     private lateinit var testScope: TestScope
@@ -90,6 +96,7 @@
         testDispatcher = StandardTestDispatcher()
         testScope = TestScope(testDispatcher)
         userRepository = FakeUserRepository()
+        devicePostureRepository = FakeDevicePostureRepository()
     }
 
     private suspend fun createBiometricSettingsRepository() {
@@ -108,6 +115,7 @@
                 looper = testableLooper!!.looper,
                 dumpManager = dumpManager,
                 biometricManager = biometricManager,
+                devicePostureRepository = devicePostureRepository,
             )
         testScope.runCurrent()
     }
@@ -299,6 +307,50 @@
             verify(biometricManager, times(1)).registerEnabledOnKeyguardCallback(any())
         }
 
+    @Test
+    fun faceAuthIsAlwaysSupportedIfSpecificPostureIsNotConfigured() =
+        testScope.runTest {
+            overrideResource(
+                R.integer.config_face_auth_supported_posture,
+                DevicePostureController.DEVICE_POSTURE_UNKNOWN
+            )
+
+            createBiometricSettingsRepository()
+
+            assertThat(collectLastValue(underTest.isFaceAuthSupportedInCurrentPosture)()).isTrue()
+        }
+
+    @Test
+    fun faceAuthIsSupportedOnlyWhenDevicePostureMatchesConfigValue() =
+        testScope.runTest {
+            overrideResource(
+                R.integer.config_face_auth_supported_posture,
+                DevicePostureController.DEVICE_POSTURE_FLIPPED
+            )
+
+            createBiometricSettingsRepository()
+
+            val isFaceAuthSupported =
+                collectLastValue(underTest.isFaceAuthSupportedInCurrentPosture)
+
+            assertThat(isFaceAuthSupported()).isFalse()
+
+            devicePostureRepository.setCurrentPosture(DevicePosture.CLOSED)
+            assertThat(isFaceAuthSupported()).isFalse()
+
+            devicePostureRepository.setCurrentPosture(DevicePosture.HALF_OPENED)
+            assertThat(isFaceAuthSupported()).isFalse()
+
+            devicePostureRepository.setCurrentPosture(DevicePosture.OPENED)
+            assertThat(isFaceAuthSupported()).isFalse()
+
+            devicePostureRepository.setCurrentPosture(DevicePosture.UNKNOWN)
+            assertThat(isFaceAuthSupported()).isFalse()
+
+            devicePostureRepository.setCurrentPosture(DevicePosture.FLIPPED)
+            assertThat(isFaceAuthSupported()).isTrue()
+        }
+
     private fun enrollmentChange(biometricType: BiometricType, userId: Int, enabled: Boolean) {
         authControllerCallback.value.onEnrollmentsChanged(biometricType, userId, enabled)
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
new file mode 100644
index 0000000..bd6b7a8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.data.repository
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.shared.model.DevicePosture
+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.runTest
+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.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class DevicePostureRepositoryTest : SysuiTestCase() {
+    private lateinit var underTest: DevicePostureRepository
+    private lateinit var testScope: TestScope
+    @Mock private lateinit var devicePostureController: DevicePostureController
+    @Captor private lateinit var callback: ArgumentCaptor<DevicePostureController.Callback>
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        testScope = TestScope()
+        underTest = DevicePostureRepositoryImpl(postureController = devicePostureController)
+    }
+
+    @Test
+    fun postureChangesArePropagated() =
+        testScope.runTest {
+            whenever(devicePostureController.devicePosture)
+                .thenReturn(DevicePostureController.DEVICE_POSTURE_FLIPPED)
+            val currentPosture = collectLastValue(underTest.currentDevicePosture)
+            assertThat(currentPosture()).isEqualTo(DevicePosture.FLIPPED)
+
+            verify(devicePostureController).addCallback(callback.capture())
+
+            callback.value.onPostureChanged(DevicePostureController.DEVICE_POSTURE_UNKNOWN)
+            assertThat(currentPosture()).isEqualTo(DevicePosture.UNKNOWN)
+
+            callback.value.onPostureChanged(DevicePostureController.DEVICE_POSTURE_CLOSED)
+            assertThat(currentPosture()).isEqualTo(DevicePosture.CLOSED)
+
+            callback.value.onPostureChanged(DevicePostureController.DEVICE_POSTURE_HALF_OPENED)
+            assertThat(currentPosture()).isEqualTo(DevicePosture.HALF_OPENED)
+
+            callback.value.onPostureChanged(DevicePostureController.DEVICE_POSTURE_OPENED)
+            assertThat(currentPosture()).isEqualTo(DevicePosture.OPENED)
+
+            callback.value.onPostureChanged(DevicePostureController.DEVICE_POSTURE_FLIPPED)
+            assertThat(currentPosture()).isEqualTo(DevicePosture.FLIPPED)
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthManagerTest.kt
new file mode 100644
index 0000000..7c604f7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardFaceAuthManagerTest.kt
@@ -0,0 +1,428 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.data.repository
+
+import android.app.StatusBarManager.SESSION_KEYGUARD
+import android.content.pm.UserInfo
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_CANCELED
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT
+import android.hardware.biometrics.ComponentInfoInternal
+import android.hardware.face.FaceManager
+import android.hardware.face.FaceSensorProperties
+import android.hardware.face.FaceSensorPropertiesInternal
+import android.os.CancellationSignal
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId.fakeInstanceId
+import com.android.internal.logging.UiEventLogger
+import com.android.keyguard.FaceAuthUiEvent
+import com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN
+import com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.FlowValue
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.dump.logcatLogBuffer
+import com.android.systemui.keyguard.shared.model.AuthenticationStatus
+import com.android.systemui.keyguard.shared.model.DetectionStatus
+import com.android.systemui.keyguard.shared.model.ErrorAuthenticationStatus
+import com.android.systemui.keyguard.shared.model.HelpAuthenticationStatus
+import com.android.systemui.keyguard.shared.model.SuccessAuthenticationStatus
+import com.android.systemui.log.FaceAuthenticationLogger
+import com.android.systemui.log.SessionTracker
+import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.user.data.repository.FakeUserRepository
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import java.io.PrintWriter
+import java.io.StringWriter
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.isNull
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class KeyguardFaceAuthManagerTest : SysuiTestCase() {
+    private lateinit var underTest: KeyguardFaceAuthManagerImpl
+
+    @Mock private lateinit var faceManager: FaceManager
+    @Mock private lateinit var bypassController: KeyguardBypassController
+    @Mock private lateinit var sessionTracker: SessionTracker
+    @Mock private lateinit var uiEventLogger: UiEventLogger
+    @Mock private lateinit var dumpManager: DumpManager
+
+    @Captor
+    private lateinit var authenticationCallback: ArgumentCaptor<FaceManager.AuthenticationCallback>
+    @Captor
+    private lateinit var detectionCallback: ArgumentCaptor<FaceManager.FaceDetectionCallback>
+    @Captor private lateinit var cancellationSignal: ArgumentCaptor<CancellationSignal>
+    @Captor
+    private lateinit var faceLockoutResetCallback: ArgumentCaptor<FaceManager.LockoutResetCallback>
+    private lateinit var testDispatcher: TestDispatcher
+
+    private lateinit var testScope: TestScope
+    private lateinit var fakeUserRepository: FakeUserRepository
+    private lateinit var authStatus: FlowValue<AuthenticationStatus?>
+    private lateinit var detectStatus: FlowValue<DetectionStatus?>
+    private lateinit var authRunning: FlowValue<Boolean?>
+    private lateinit var lockedOut: FlowValue<Boolean?>
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        fakeUserRepository = FakeUserRepository()
+        fakeUserRepository.setUserInfos(listOf(currentUser))
+        testDispatcher = StandardTestDispatcher()
+        testScope = TestScope(testDispatcher)
+        whenever(sessionTracker.getSessionId(SESSION_KEYGUARD)).thenReturn(keyguardSessionId)
+        whenever(bypassController.bypassEnabled).thenReturn(true)
+        underTest = createFaceAuthManagerImpl(faceManager)
+    }
+
+    private fun createFaceAuthManagerImpl(
+        fmOverride: FaceManager? = faceManager,
+        bypassControllerOverride: KeyguardBypassController? = bypassController
+    ) =
+        KeyguardFaceAuthManagerImpl(
+            mContext,
+            fmOverride,
+            fakeUserRepository,
+            bypassControllerOverride,
+            testScope.backgroundScope,
+            testDispatcher,
+            sessionTracker,
+            uiEventLogger,
+            FaceAuthenticationLogger(logcatLogBuffer("KeyguardFaceAuthManagerLog")),
+            dumpManager,
+        )
+
+    @Test
+    fun faceAuthRunsAndProvidesAuthStatusUpdates() =
+        testScope.runTest {
+            testSetup(this)
+
+            FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER.extraInfo = 10
+            underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER)
+            faceAuthenticateIsCalled()
+            uiEventIsLogged(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER)
+
+            assertThat(authRunning()).isTrue()
+
+            val successResult = successResult()
+            authenticationCallback.value.onAuthenticationSucceeded(successResult)
+
+            assertThat(authStatus()).isEqualTo(SuccessAuthenticationStatus(successResult))
+
+            assertThat(authRunning()).isFalse()
+        }
+
+    private fun uiEventIsLogged(faceAuthUiEvent: FaceAuthUiEvent) {
+        verify(uiEventLogger)
+            .logWithInstanceIdAndPosition(
+                faceAuthUiEvent,
+                0,
+                null,
+                keyguardSessionId,
+                faceAuthUiEvent.extraInfo
+            )
+    }
+
+    @Test
+    fun faceAuthDoesNotRunWhileItIsAlreadyRunning() =
+        testScope.runTest {
+            testSetup(this)
+
+            underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER)
+            faceAuthenticateIsCalled()
+            clearInvocations(faceManager)
+            clearInvocations(uiEventLogger)
+
+            underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER)
+            verifyNoMoreInteractions(faceManager)
+            verifyNoMoreInteractions(uiEventLogger)
+        }
+
+    @Test
+    fun faceLockoutStatusIsPropagated() =
+        testScope.runTest {
+            testSetup(this)
+            verify(faceManager).addLockoutResetCallback(faceLockoutResetCallback.capture())
+
+            underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER)
+            faceAuthenticateIsCalled()
+
+            authenticationCallback.value.onAuthenticationError(
+                FACE_ERROR_LOCKOUT_PERMANENT,
+                "face locked out"
+            )
+
+            assertThat(lockedOut()).isTrue()
+
+            faceLockoutResetCallback.value.onLockoutReset(0)
+            assertThat(lockedOut()).isFalse()
+        }
+
+    @Test
+    fun faceDetectionSupportIsTheCorrectValue() =
+        testScope.runTest {
+            assertThat(createFaceAuthManagerImpl(fmOverride = null).isDetectionSupported).isFalse()
+
+            whenever(faceManager.sensorPropertiesInternal).thenReturn(null)
+            assertThat(createFaceAuthManagerImpl().isDetectionSupported).isFalse()
+
+            whenever(faceManager.sensorPropertiesInternal).thenReturn(listOf())
+            assertThat(createFaceAuthManagerImpl().isDetectionSupported).isFalse()
+
+            whenever(faceManager.sensorPropertiesInternal)
+                .thenReturn(listOf(createFaceSensorProperties(supportsFaceDetection = false)))
+            assertThat(createFaceAuthManagerImpl().isDetectionSupported).isFalse()
+
+            whenever(faceManager.sensorPropertiesInternal)
+                .thenReturn(
+                    listOf(
+                        createFaceSensorProperties(supportsFaceDetection = false),
+                        createFaceSensorProperties(supportsFaceDetection = true)
+                    )
+                )
+            assertThat(createFaceAuthManagerImpl().isDetectionSupported).isFalse()
+
+            whenever(faceManager.sensorPropertiesInternal)
+                .thenReturn(
+                    listOf(
+                        createFaceSensorProperties(supportsFaceDetection = true),
+                        createFaceSensorProperties(supportsFaceDetection = false)
+                    )
+                )
+            assertThat(createFaceAuthManagerImpl().isDetectionSupported).isTrue()
+        }
+
+    @Test
+    fun cancelStopsFaceAuthentication() =
+        testScope.runTest {
+            testSetup(this)
+
+            underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER)
+            faceAuthenticateIsCalled()
+
+            var wasAuthCancelled = false
+            cancellationSignal.value.setOnCancelListener { wasAuthCancelled = true }
+
+            underTest.cancel()
+            assertThat(wasAuthCancelled).isTrue()
+            assertThat(authRunning()).isFalse()
+        }
+
+    @Test
+    fun cancelInvokedWithoutFaceAuthRunningIsANoop() = testScope.runTest { underTest.cancel() }
+
+    @Test
+    fun faceDetectionRunsAndPropagatesDetectionStatus() =
+        testScope.runTest {
+            whenever(faceManager.sensorPropertiesInternal)
+                .thenReturn(listOf(createFaceSensorProperties(supportsFaceDetection = true)))
+            underTest = createFaceAuthManagerImpl()
+            testSetup(this)
+
+            underTest.detect()
+            faceDetectIsCalled()
+
+            detectionCallback.value.onFaceDetected(1, 1, true)
+
+            assertThat(detectStatus()).isEqualTo(DetectionStatus(1, 1, true))
+        }
+
+    @Test
+    fun faceDetectDoesNotRunIfDetectionIsNotSupported() =
+        testScope.runTest {
+            whenever(faceManager.sensorPropertiesInternal)
+                .thenReturn(listOf(createFaceSensorProperties(supportsFaceDetection = false)))
+            underTest = createFaceAuthManagerImpl()
+            testSetup(this)
+            clearInvocations(faceManager)
+
+            underTest.detect()
+
+            verify(faceManager, never()).detectFace(any(), any(), anyInt())
+        }
+
+    @Test
+    fun faceAuthShouldWaitAndRunIfTriggeredWhileCancelling() =
+        testScope.runTest {
+            testSetup(this)
+
+            underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER)
+            faceAuthenticateIsCalled()
+
+            // Enter cancelling state
+            underTest.cancel()
+            clearInvocations(faceManager)
+
+            // Auth is while cancelling.
+            underTest.authenticate(FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN)
+            // Auth is not started
+            verifyNoMoreInteractions(faceManager)
+
+            // Auth is done cancelling.
+            authenticationCallback.value.onAuthenticationError(
+                FACE_ERROR_CANCELED,
+                "First auth attempt cancellation completed"
+            )
+            assertThat(authStatus())
+                .isEqualTo(
+                    ErrorAuthenticationStatus(
+                        FACE_ERROR_CANCELED,
+                        "First auth attempt cancellation completed"
+                    )
+                )
+
+            faceAuthenticateIsCalled()
+            uiEventIsLogged(FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN)
+        }
+
+    @Test
+    fun faceAuthAutoCancelsAfterDefaultCancellationTimeout() =
+        testScope.runTest {
+            testSetup(this)
+
+            underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER)
+            faceAuthenticateIsCalled()
+
+            clearInvocations(faceManager)
+            underTest.cancel()
+            advanceTimeBy(KeyguardFaceAuthManagerImpl.DEFAULT_CANCEL_SIGNAL_TIMEOUT + 1)
+
+            underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER)
+            faceAuthenticateIsCalled()
+        }
+
+    @Test
+    fun faceHelpMessagesAreIgnoredBasedOnConfig() =
+        testScope.runTest {
+            overrideResource(
+                R.array.config_face_acquire_device_entry_ignorelist,
+                intArrayOf(10, 11)
+            )
+            underTest = createFaceAuthManagerImpl()
+            testSetup(this)
+
+            underTest.authenticate(FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER)
+            faceAuthenticateIsCalled()
+
+            authenticationCallback.value.onAuthenticationHelp(9, "help msg")
+            authenticationCallback.value.onAuthenticationHelp(10, "Ignored help msg")
+            authenticationCallback.value.onAuthenticationHelp(11, "Ignored help msg")
+
+            assertThat(authStatus()).isEqualTo(HelpAuthenticationStatus(9, "help msg"))
+        }
+
+    @Test
+    fun dumpDoesNotErrorOutWhenFaceManagerOrBypassControllerIsNull() =
+        testScope.runTest {
+            fakeUserRepository.setSelectedUserInfo(currentUser)
+            underTest.dump(PrintWriter(StringWriter()), emptyArray())
+
+            underTest =
+                createFaceAuthManagerImpl(fmOverride = null, bypassControllerOverride = null)
+            fakeUserRepository.setSelectedUserInfo(currentUser)
+
+            underTest.dump(PrintWriter(StringWriter()), emptyArray())
+        }
+
+    private suspend fun testSetup(testScope: TestScope) {
+        with(testScope) {
+            authStatus = collectLastValue(underTest.authenticationStatus)
+            detectStatus = collectLastValue(underTest.detectionStatus)
+            authRunning = collectLastValue(underTest.isAuthRunning)
+            lockedOut = collectLastValue(underTest.isLockedOut)
+            fakeUserRepository.setSelectedUserInfo(currentUser)
+        }
+    }
+
+    private fun successResult() = FaceManager.AuthenticationResult(null, null, currentUserId, false)
+
+    private fun faceDetectIsCalled() {
+        verify(faceManager)
+            .detectFace(
+                cancellationSignal.capture(),
+                detectionCallback.capture(),
+                eq(currentUserId)
+            )
+    }
+
+    private fun faceAuthenticateIsCalled() {
+        verify(faceManager)
+            .authenticate(
+                isNull(),
+                cancellationSignal.capture(),
+                authenticationCallback.capture(),
+                isNull(),
+                eq(currentUserId),
+                eq(true)
+            )
+    }
+
+    private fun createFaceSensorProperties(
+        supportsFaceDetection: Boolean
+    ): FaceSensorPropertiesInternal {
+        val componentInfo =
+            listOf(
+                ComponentInfoInternal(
+                    "faceSensor" /* componentId */,
+                    "vendor/model/revision" /* hardwareVersion */,
+                    "1.01" /* firmwareVersion */,
+                    "00000001" /* serialNumber */,
+                    "" /* softwareVersion */
+                )
+            )
+        return FaceSensorPropertiesInternal(
+            0 /* id */,
+            FaceSensorProperties.STRENGTH_STRONG,
+            1 /* maxTemplatesAllowed */,
+            componentInfo,
+            FaceSensorProperties.TYPE_UNKNOWN,
+            supportsFaceDetection /* supportsFaceDetection */,
+            true /* supportsSelfIllumination */,
+            false /* resetLockoutRequiresChallenge */
+        )
+    }
+
+    companion object {
+        const val currentUserId = 1
+        val keyguardSessionId = fakeInstanceId(10)!!
+        val currentUser = UserInfo(currentUserId, "test user", 0)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt
index 18e80ea..1365132 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt
@@ -28,6 +28,8 @@
 import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
 import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepositoryImpl
 import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.android.systemui.util.time.SystemClock
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -50,6 +52,7 @@
     private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
     private lateinit var deviceEntryFingerprintAuthRepository:
         FakeDeviceEntryFingerprintAuthRepository
+    @Mock private lateinit var keyguardStateController: KeyguardStateController
     @Mock private lateinit var systemClock: SystemClock
     @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
     @Mock private lateinit var bouncerLogger: TableLogBuffer
@@ -70,6 +73,7 @@
         featureFlags = FakeFeatureFlags().apply { this.set(Flags.MODERN_ALTERNATE_BOUNCER, true) }
         underTest =
             AlternateBouncerInteractor(
+                keyguardStateController,
                 bouncerRepository,
                 biometricSettingsRepository,
                 deviceEntryFingerprintAuthRepository,
@@ -134,6 +138,14 @@
     }
 
     @Test
+    fun canShowAlternateBouncerForFingerprint_butCanDismissLockScreen() {
+        givenCanShowAlternateBouncer()
+        whenever(keyguardStateController.isUnlocked).thenReturn(true)
+
+        assertFalse(underTest.canShowAlternateBouncerForFingerprint())
+    }
+
+    @Test
     fun show_whenCannotShow() {
         givenCannotShowAlternateBouncer()
 
@@ -163,6 +175,7 @@
         biometricSettingsRepository.setStrongBiometricAllowed(true)
         biometricSettingsRepository.setFingerprintEnabledByDevicePolicy(true)
         deviceEntryFingerprintAuthRepository.setLockedOut(false)
+        whenever(keyguardStateController.isUnlocked).thenReturn(false)
     }
 
     private fun givenCannotShowAlternateBouncer() {
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 23e06ec..84ec125 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
@@ -17,6 +17,7 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
+import android.app.admin.DevicePolicyManager
 import android.content.Intent
 import android.os.UserHandle
 import androidx.test.filters.SmallTest
@@ -54,7 +55,10 @@
 import com.android.systemui.util.settings.FakeSettings
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -70,6 +74,7 @@
 import org.mockito.Mockito.verifyZeroInteractions
 import org.mockito.MockitoAnnotations
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(Parameterized::class)
 class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
@@ -219,8 +224,10 @@
     @Mock private lateinit var expandable: Expandable
     @Mock private lateinit var launchAnimator: DialogLaunchAnimator
     @Mock private lateinit var commandQueue: CommandQueue
+    @Mock private lateinit var devicePolicyManager: DevicePolicyManager
 
     private lateinit var underTest: KeyguardQuickAffordanceInteractor
+    private lateinit var testScope: TestScope
 
     @JvmField @Parameter(0) var needStrongAuthAfterBoot: Boolean = false
     @JvmField @Parameter(1) var canShowWhileLocked: Boolean = false
@@ -292,6 +299,8 @@
                 set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
                 set(Flags.FACE_AUTH_REFACTOR, true)
             }
+        val testDispatcher = StandardTestDispatcher()
+        testScope = TestScope(testDispatcher)
         underTest =
             KeyguardQuickAffordanceInteractor(
                 keyguardInteractor =
@@ -322,58 +331,61 @@
                 featureFlags = featureFlags,
                 repository = { quickAffordanceRepository },
                 launchAnimator = launchAnimator,
+                devicePolicyManager = devicePolicyManager,
+                backgroundDispatcher = testDispatcher,
             )
     }
 
     @Test
-    fun onQuickAffordanceTriggered() = runBlockingTest {
-        setUpMocks(
-            needStrongAuthAfterBoot = needStrongAuthAfterBoot,
-            keyguardIsUnlocked = keyguardIsUnlocked,
-        )
+    fun onQuickAffordanceTriggered() =
+        testScope.runTest {
+            setUpMocks(
+                needStrongAuthAfterBoot = needStrongAuthAfterBoot,
+                keyguardIsUnlocked = keyguardIsUnlocked,
+            )
 
-        homeControls.setState(
-            lockScreenState =
-                KeyguardQuickAffordanceConfig.LockScreenState.Visible(
-                    icon = DRAWABLE,
-                )
-        )
-        homeControls.onTriggeredResult =
+            homeControls.setState(
+                lockScreenState =
+                    KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+                        icon = DRAWABLE,
+                    )
+            )
+            homeControls.onTriggeredResult =
+                if (startActivity) {
+                    KeyguardQuickAffordanceConfig.OnTriggeredResult.StartActivity(
+                        intent = INTENT,
+                        canShowWhileLocked = canShowWhileLocked,
+                    )
+                } else {
+                    KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
+                }
+
+            underTest.onQuickAffordanceTriggered(
+                configKey = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS,
+                expandable = expandable,
+            )
+
             if (startActivity) {
-                KeyguardQuickAffordanceConfig.OnTriggeredResult.StartActivity(
-                    intent = INTENT,
-                    canShowWhileLocked = canShowWhileLocked,
-                )
+                if (needsToUnlockFirst) {
+                    verify(activityStarter)
+                        .postStartActivityDismissingKeyguard(
+                            any(),
+                            /* delay= */ eq(0),
+                            same(animationController),
+                        )
+                } else {
+                    verify(activityStarter)
+                        .startActivity(
+                            any(),
+                            /* dismissShade= */ eq(true),
+                            same(animationController),
+                            /* showOverLockscreenWhenLocked= */ eq(true),
+                        )
+                }
             } else {
-                KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
+                verifyZeroInteractions(activityStarter)
             }
-
-        underTest.onQuickAffordanceTriggered(
-            configKey = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS,
-            expandable = expandable,
-        )
-
-        if (startActivity) {
-            if (needsToUnlockFirst) {
-                verify(activityStarter)
-                    .postStartActivityDismissingKeyguard(
-                        any(),
-                        /* delay= */ eq(0),
-                        same(animationController),
-                    )
-            } else {
-                verify(activityStarter)
-                    .startActivity(
-                        any(),
-                        /* dismissShade= */ eq(true),
-                        same(animationController),
-                        /* showOverLockscreenWhenLocked= */ eq(true),
-                    )
-            }
-        } else {
-            verifyZeroInteractions(activityStarter)
         }
-    }
 
     private fun setUpMocks(
         needStrongAuthAfterBoot: Boolean = true,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index 1b8c627..62c9e5f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
@@ -17,6 +17,7 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
+import android.app.admin.DevicePolicyManager
 import android.os.UserHandle
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -78,6 +79,7 @@
     @Mock private lateinit var activityStarter: ActivityStarter
     @Mock private lateinit var launchAnimator: DialogLaunchAnimator
     @Mock private lateinit var commandQueue: CommandQueue
+    @Mock private lateinit var devicePolicyManager: DevicePolicyManager
 
     private lateinit var underTest: KeyguardQuickAffordanceInteractor
 
@@ -184,6 +186,8 @@
                 featureFlags = featureFlags,
                 repository = { quickAffordanceRepository },
                 launchAnimator = launchAnimator,
+                devicePolicyManager = devicePolicyManager,
+                backgroundDispatcher = testDispatcher,
             )
     }
 
@@ -239,6 +243,44 @@
         }
 
     @Test
+    fun `quickAffordance - hidden when all features are disabled by device policy`() =
+        testScope.runTest {
+            whenever(devicePolicyManager.getKeyguardDisabledFeatures(null, userTracker.userId))
+                .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)
+            quickAccessWallet.setState(
+                KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+                    icon = ICON,
+                )
+            )
+
+            val collectedValue by
+                collectLastValue(
+                    underTest.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_END)
+                )
+
+            assertThat(collectedValue).isInstanceOf(KeyguardQuickAffordanceModel.Hidden::class.java)
+        }
+
+    @Test
+    fun `quickAffordance - hidden when shortcuts feature is disabled by device policy`() =
+        testScope.runTest {
+            whenever(devicePolicyManager.getKeyguardDisabledFeatures(null, userTracker.userId))
+                .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL)
+            quickAccessWallet.setState(
+                KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+                    icon = ICON,
+                )
+            )
+
+            val collectedValue by
+                collectLastValue(
+                    underTest.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_END)
+                )
+
+            assertThat(collectedValue).isInstanceOf(KeyguardQuickAffordanceModel.Hidden::class.java)
+        }
+
+    @Test
     fun `quickAffordance - bottom start affordance hidden while dozing`() =
         testScope.runTest {
             repository.setDozing(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
index 46ed829..6b7fd61 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
@@ -19,11 +19,13 @@
 import android.os.Looper
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
+import android.testing.TestableResources
 import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardSecurityModel
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.DejankUtils
+import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.keyguard.DismissCallbackRegistry
@@ -69,6 +71,7 @@
     @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
     private val mainHandler = FakeHandler(Looper.getMainLooper())
     private lateinit var underTest: PrimaryBouncerInteractor
+    private lateinit var resources: TestableResources
 
     @Before
     fun setUp() {
@@ -84,18 +87,19 @@
                 mPrimaryBouncerCallbackInteractor,
                 falsingCollector,
                 dismissCallbackRegistry,
-                keyguardBypassController,
+                context,
                 keyguardUpdateMonitor,
+                keyguardBypassController,
             )
         `when`(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null)
         `when`(repository.primaryBouncerShow.value).thenReturn(null)
         `when`(bouncerView.delegate).thenReturn(bouncerViewDelegate)
+        resources = context.orCreateTestableResources
     }
 
     @Test
     fun testShow_isScrimmed() {
         underTest.show(true)
-        verify(repository).setOnScreenTurnedOff(false)
         verify(repository).setKeyguardAuthenticated(null)
         verify(repository).setPrimaryHide(false)
         verify(repository).setPrimaryStartingToHide(false)
@@ -207,12 +211,6 @@
     }
 
     @Test
-    fun testOnScreenTurnedOff() {
-        underTest.onScreenTurnedOff()
-        verify(repository).setOnScreenTurnedOff(true)
-    }
-
-    @Test
     fun testSetKeyguardPosition() {
         underTest.setKeyguardPosition(0f)
         verify(repository).setKeyguardPosition(0f)
@@ -286,4 +284,98 @@
         `when`(bouncerViewDelegate.willDismissWithActions()).thenReturn(false)
         assertThat(underTest.willDismissWithAction()).isFalse()
     }
+
+    @Test
+    fun testSideFpsVisibility() {
+        updateSideFpsVisibilityParameters(
+            isVisible = true,
+            sfpsEnabled = true,
+            fpsDetectionRunning = true,
+            isUnlockingWithFpAllowed = true,
+            isAnimatingAway = false
+        )
+        underTest.updateSideFpsVisibility()
+        verify(repository).setSideFpsShowing(true)
+    }
+
+    @Test
+    fun testSideFpsVisibility_notVisible() {
+        updateSideFpsVisibilityParameters(
+            isVisible = false,
+            sfpsEnabled = true,
+            fpsDetectionRunning = true,
+            isUnlockingWithFpAllowed = true,
+            isAnimatingAway = false
+        )
+        underTest.updateSideFpsVisibility()
+        verify(repository).setSideFpsShowing(false)
+    }
+
+    @Test
+    fun testSideFpsVisibility_sfpsNotEnabled() {
+        updateSideFpsVisibilityParameters(
+            isVisible = true,
+            sfpsEnabled = false,
+            fpsDetectionRunning = true,
+            isUnlockingWithFpAllowed = true,
+            isAnimatingAway = false
+        )
+        underTest.updateSideFpsVisibility()
+        verify(repository).setSideFpsShowing(false)
+    }
+
+    @Test
+    fun testSideFpsVisibility_fpsDetectionNotRunning() {
+        updateSideFpsVisibilityParameters(
+            isVisible = true,
+            sfpsEnabled = true,
+            fpsDetectionRunning = false,
+            isUnlockingWithFpAllowed = true,
+            isAnimatingAway = false
+        )
+        underTest.updateSideFpsVisibility()
+        verify(repository).setSideFpsShowing(false)
+    }
+
+    @Test
+    fun testSideFpsVisibility_UnlockingWithFpNotAllowed() {
+        updateSideFpsVisibilityParameters(
+            isVisible = true,
+            sfpsEnabled = true,
+            fpsDetectionRunning = true,
+            isUnlockingWithFpAllowed = false,
+            isAnimatingAway = false
+        )
+        underTest.updateSideFpsVisibility()
+        verify(repository).setSideFpsShowing(false)
+    }
+
+    @Test
+    fun testSideFpsVisibility_AnimatingAway() {
+        updateSideFpsVisibilityParameters(
+            isVisible = true,
+            sfpsEnabled = true,
+            fpsDetectionRunning = true,
+            isUnlockingWithFpAllowed = true,
+            isAnimatingAway = true
+        )
+        underTest.updateSideFpsVisibility()
+        verify(repository).setSideFpsShowing(false)
+    }
+
+    private fun updateSideFpsVisibilityParameters(
+        isVisible: Boolean,
+        sfpsEnabled: Boolean,
+        fpsDetectionRunning: Boolean,
+        isUnlockingWithFpAllowed: Boolean,
+        isAnimatingAway: Boolean
+    ) {
+        `when`(repository.primaryBouncerVisible.value).thenReturn(isVisible)
+        resources.addOverride(R.bool.config_show_sidefps_hint_on_bouncer, sfpsEnabled)
+        `when`(keyguardUpdateMonitor.isFingerprintDetectionRunning).thenReturn(fpsDetectionRunning)
+        `when`(keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed)
+            .thenReturn(isUnlockingWithFpAllowed)
+        `when`(repository.primaryBouncerStartingDisappearAnimation.value)
+            .thenReturn(if (isAnimatingAway) Runnable {} else null)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
index 75b74b0..f675e79 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.data.BouncerView
-import com.android.systemui.keyguard.data.BouncerViewDelegate
 import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -44,7 +43,6 @@
 class PrimaryBouncerInteractorWithCoroutinesTest : SysuiTestCase() {
     private lateinit var repository: FakeKeyguardBouncerRepository
     @Mock private lateinit var bouncerView: BouncerView
-    @Mock private lateinit var bouncerViewDelegate: BouncerViewDelegate
     @Mock private lateinit var keyguardStateController: KeyguardStateController
     @Mock private lateinit var keyguardSecurityModel: KeyguardSecurityModel
     @Mock private lateinit var primaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor
@@ -69,8 +67,9 @@
                 primaryBouncerCallbackInteractor,
                 falsingCollector,
                 dismissCallbackRegistry,
-                keyguardBypassController,
+                context,
                 keyguardUpdateMonitor,
+                keyguardBypassController,
             )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
index 6afeddd..c727b3a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
+import android.app.admin.DevicePolicyManager
 import android.content.Intent
 import android.os.UserHandle
 import androidx.test.filters.SmallTest
@@ -87,6 +88,7 @@
     @Mock private lateinit var activityStarter: ActivityStarter
     @Mock private lateinit var launchAnimator: DialogLaunchAnimator
     @Mock private lateinit var commandQueue: CommandQueue
+    @Mock private lateinit var devicePolicyManager: DevicePolicyManager
 
     private lateinit var underTest: KeyguardBottomAreaViewModel
 
@@ -140,6 +142,7 @@
                 bouncerRepository = FakeKeyguardBouncerRepository(),
             )
         whenever(userTracker.userHandle).thenReturn(mock())
+        whenever(userTracker.userId).thenReturn(10)
         whenever(lockPatternUtils.getStrongAuthForUser(anyInt()))
             .thenReturn(LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED)
         val testDispatcher = StandardTestDispatcher()
@@ -205,6 +208,8 @@
                         featureFlags = featureFlags,
                         repository = { quickAffordanceRepository },
                         launchAnimator = launchAnimator,
+                        devicePolicyManager = devicePolicyManager,
+                        backgroundDispatcher = testDispatcher,
                     ),
                 bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository),
                 burnInHelperWrapper = burnInHelperWrapper,
@@ -240,6 +245,39 @@
         }
 
     @Test
+    fun `startButton - hidden when device policy disables all keyguard features`() =
+        testScope.runTest {
+            whenever(devicePolicyManager.getKeyguardDisabledFeatures(null, userTracker.userId))
+                .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)
+            repository.setKeyguardShowing(true)
+            val latest by collectLastValue(underTest.startButton)
+
+            val testConfig =
+                TestConfig(
+                    isVisible = true,
+                    isClickable = true,
+                    isActivated = true,
+                    icon = mock(),
+                    canShowWhileLocked = false,
+                    intent = Intent("action"),
+                )
+            val configKey =
+                setUpQuickAffordanceModel(
+                    position = KeyguardQuickAffordancePosition.BOTTOM_START,
+                    testConfig = testConfig,
+                )
+
+            assertQuickAffordanceViewModel(
+                viewModel = latest,
+                testConfig =
+                    TestConfig(
+                        isVisible = false,
+                    ),
+                configKey = configKey,
+            )
+        }
+
+    @Test
     fun `startButton - in preview mode - visible even when keyguard not showing`() =
         testScope.runTest {
             underTest.enablePreviewMode(
@@ -270,7 +308,7 @@
                     TestConfig(
                         isVisible = true,
                         isClickable = false,
-                        isActivated = true,
+                        isActivated = false,
                         icon = icon,
                         canShowWhileLocked = false,
                         intent = Intent("action"),
@@ -325,7 +363,7 @@
                     TestConfig(
                         isVisible = true,
                         isClickable = false,
-                        isActivated = true,
+                        isActivated = false,
                         icon = icon,
                         canShowWhileLocked = false,
                         intent = Intent("action"),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt
index 586af62..65e4c10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt
@@ -16,15 +16,23 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
+import android.os.Looper
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardSecurityModel
+import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingCollector
+import com.android.systemui.keyguard.DismissCallbackRegistry
 import com.android.systemui.keyguard.data.BouncerView
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
 import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
+import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.utils.os.FakeHandler
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.test.runCurrent
@@ -33,7 +41,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
-import org.mockito.Mockito
 import org.mockito.MockitoAnnotations
 
 @SmallTest
@@ -41,31 +48,69 @@
 @kotlinx.coroutines.ExperimentalCoroutinesApi
 class KeyguardBouncerViewModelTest : SysuiTestCase() {
     lateinit var underTest: KeyguardBouncerViewModel
+    lateinit var bouncerInteractor: PrimaryBouncerInteractor
     @Mock lateinit var bouncerView: BouncerView
-    @Mock lateinit var bouncerInteractor: PrimaryBouncerInteractor
+    @Mock private lateinit var keyguardStateController: KeyguardStateController
+    @Mock private lateinit var keyguardSecurityModel: KeyguardSecurityModel
+    @Mock private lateinit var primaryBouncerCallbackInteractor: PrimaryBouncerCallbackInteractor
+    @Mock private lateinit var falsingCollector: FalsingCollector
+    @Mock private lateinit var dismissCallbackRegistry: DismissCallbackRegistry
+    @Mock private lateinit var keyguardBypassController: KeyguardBypassController
+    @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+    private val mainHandler = FakeHandler(Looper.getMainLooper())
+    val repository = FakeKeyguardBouncerRepository()
 
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
+        bouncerInteractor =
+            PrimaryBouncerInteractor(
+                repository,
+                bouncerView,
+                mainHandler,
+                keyguardStateController,
+                keyguardSecurityModel,
+                primaryBouncerCallbackInteractor,
+                falsingCollector,
+                dismissCallbackRegistry,
+                context,
+                keyguardUpdateMonitor,
+                keyguardBypassController,
+            )
         underTest = KeyguardBouncerViewModel(bouncerView, bouncerInteractor)
     }
 
     @Test
-    fun setMessage() =
-        runTest {
-            val flow = MutableStateFlow<BouncerShowMessageModel?>(null)
-            var message: BouncerShowMessageModel? = null
-            Mockito.`when`(bouncerInteractor.showMessage)
-                .thenReturn(flow as Flow<BouncerShowMessageModel>)
-            // Reinitialize the view model.
-            underTest = KeyguardBouncerViewModel(bouncerView, bouncerInteractor)
+    fun setMessage() = runTest {
+        var message: BouncerShowMessageModel? = null
+        val job = underTest.bouncerShowMessage.onEach { message = it }.launchIn(this)
 
-            flow.value = BouncerShowMessageModel(message = "abc", colorStateList = null)
+        repository.setShowMessage(BouncerShowMessageModel("abc", null))
+        // Run the tasks that are pending at this point of virtual time.
+        runCurrent()
+        assertThat(message?.message).isEqualTo("abc")
+        job.cancel()
+    }
 
-            val job = underTest.bouncerShowMessage.onEach { message = it }.launchIn(this)
-            // Run the tasks that are pending at this point of virtual time.
-            runCurrent()
-            assertThat(message?.message).isEqualTo("abc")
-            job.cancel()
-        }
+    @Test
+    fun shouldUpdateSideFps() = runTest {
+        var count = 0
+        val job = underTest.shouldUpdateSideFps.onEach { count++ }.launchIn(this)
+        repository.setPrimaryVisible(true)
+        // Run the tasks that are pending at this point of virtual time.
+        runCurrent()
+        assertThat(count).isEqualTo(1)
+        job.cancel()
+    }
+
+    @Test
+    fun sideFpsShowing() = runTest {
+        var sideFpsIsShowing = false
+        val job = underTest.sideFpsShowing.onEach { sideFpsIsShowing = it }.launchIn(this)
+        repository.setSideFpsShowing(true)
+        // Run the tasks that are pending at this point of virtual time.
+        runCurrent()
+        assertThat(sideFpsIsShowing).isEqualTo(true)
+        job.cancel()
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataFilterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataFilterTest.kt
index eb6235c..8532ffe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataFilterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataFilterTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.media.controls.pipeline
 
 import android.app.smartspace.SmartspaceAction
+import android.os.Bundle
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
@@ -25,6 +26,7 @@
 import com.android.systemui.broadcast.BroadcastSender
 import com.android.systemui.media.controls.MediaTestUtils
 import com.android.systemui.media.controls.models.player.MediaData
+import com.android.systemui.media.controls.models.recommendation.EXTRA_KEY_TRIGGER_RESUME
 import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData
 import com.android.systemui.media.controls.ui.MediaPlayerData
 import com.android.systemui.media.controls.util.MediaFlags
@@ -75,6 +77,7 @@
     @Mock private lateinit var smartspaceMediaRecommendationItem: SmartspaceAction
     @Mock private lateinit var logger: MediaUiEventLogger
     @Mock private lateinit var mediaFlags: MediaFlags
+    @Mock private lateinit var cardAction: SmartspaceAction
 
     private lateinit var mediaDataFilter: MediaDataFilter
     private lateinit var dataMain: MediaData
@@ -122,6 +125,7 @@
         whenever(smartspaceData.headphoneConnectionTimeMillis)
             .thenReturn(clock.currentTimeMillis() - 100)
         whenever(smartspaceData.instanceId).thenReturn(SMARTSPACE_INSTANCE_ID)
+        whenever(smartspaceData.cardAction).thenReturn(cardAction)
     }
 
     private fun setUser(id: Int) {
@@ -574,4 +578,55 @@
         verify(mediaDataManager, never())
             .dismissSmartspaceRecommendation(eq(SMARTSPACE_KEY), anyLong())
     }
+
+    @Test
+    fun testSmartspaceLoaded_shouldTriggerResume_doesTrigger() {
+        // WHEN we have media that was recently played, but not currently active
+        val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
+        mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
+        verify(listener)
+            .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
+
+        // AND we get a smartspace signal with extra to trigger resume
+        val extras = Bundle().apply { putBoolean(EXTRA_KEY_TRIGGER_RESUME, true) }
+        whenever(cardAction.extras).thenReturn(extras)
+        mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
+
+        // THEN we should tell listeners to treat the media as active instead
+        val dataCurrentAndActive = dataCurrent.copy(active = true)
+        verify(listener)
+            .onMediaDataLoaded(
+                eq(KEY),
+                eq(KEY),
+                eq(dataCurrentAndActive),
+                eq(true),
+                eq(100),
+                eq(true)
+            )
+        assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isTrue()
+        // And send the smartspace data, but not prioritized
+        verify(listener)
+            .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
+    }
+
+    @Test
+    fun testSmartspaceLoaded_notShouldTriggerResume_doesNotTrigger() {
+        // WHEN we have media that was recently played, but not currently active
+        val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
+        mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
+        verify(listener)
+            .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
+
+        // AND we get a smartspace signal with extra to not trigger resume
+        val extras = Bundle().apply { putBoolean(EXTRA_KEY_TRIGGER_RESUME, false) }
+        whenever(cardAction.extras).thenReturn(extras)
+        mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
+
+        // THEN listeners are not updated to show media
+        verify(listener, never())
+            .onMediaDataLoaded(eq(KEY), eq(KEY), any(), eq(true), eq(100), eq(true))
+        // But the smartspace update is still propagated
+        verify(listener)
+            .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
index a07a714..ab0669a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
@@ -93,6 +93,8 @@
 private const val APP_NAME = "SystemUI"
 private const val SESSION_ARTIST = "artist"
 private const val SESSION_TITLE = "title"
+private const val SESSION_BLANK_TITLE = " "
+private const val SESSION_EMPTY_TITLE = ""
 private const val USER_ID = 0
 private val DISMISS_INTENT = Intent().apply { action = "dismiss" }
 
@@ -137,6 +139,7 @@
     @Mock private lateinit var logger: MediaUiEventLogger
     lateinit var mediaDataManager: MediaDataManager
     lateinit var mediaNotification: StatusBarNotification
+    lateinit var remoteCastNotification: StatusBarNotification
     @Captor lateinit var mediaDataCaptor: ArgumentCaptor<MediaData>
     private val clock = FakeSystemClock()
     @Mock private lateinit var tunerService: TunerService
@@ -205,6 +208,20 @@
                 }
                 build()
             }
+        remoteCastNotification =
+            SbnBuilder().run {
+                setPkg(SYSTEM_PACKAGE_NAME)
+                modifyNotification(context).also {
+                    it.setSmallIcon(android.R.drawable.ic_media_pause)
+                    it.setStyle(
+                        MediaStyle().apply {
+                            setMediaSession(session.sessionToken)
+                            setRemotePlaybackInfo("Remote device", 0, null)
+                        }
+                    )
+                }
+                build()
+            }
         metadataBuilder =
             MediaMetadata.Builder().apply {
                 putString(MediaMetadata.METADATA_KEY_ARTIST, SESSION_ARTIST)
@@ -214,6 +231,7 @@
         whenever(mediaControllerFactory.create(eq(session.sessionToken))).thenReturn(controller)
         whenever(controller.transportControls).thenReturn(transportControls)
         whenever(controller.playbackInfo).thenReturn(playbackInfo)
+        whenever(controller.metadata).thenReturn(metadataBuilder.build())
         whenever(playbackInfo.playbackType)
             .thenReturn(MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL)
 
@@ -244,6 +262,7 @@
         whenever(mediaFlags.isExplicitIndicatorEnabled()).thenReturn(true)
         whenever(mediaFlags.isRetainingPlayersEnabled()).thenReturn(false)
         whenever(mediaFlags.isPersistentSsCardEnabled()).thenReturn(false)
+        whenever(mediaFlags.isRemoteResumeAllowed()).thenReturn(false)
         whenever(logger.getNewInstanceId()).thenReturn(instanceIdSequence.newInstanceId())
         whenever(keyguardUpdateMonitor.isUserInLockdown(any())).thenReturn(false)
     }
@@ -318,18 +337,15 @@
 
     @Test
     fun testLoadMetadata_withExplicitIndicator() {
-        val metadata =
-            MediaMetadata.Builder().run {
-                putString(MediaMetadata.METADATA_KEY_ARTIST, SESSION_ARTIST)
-                putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_TITLE)
-                putLong(
-                    MediaConstants.METADATA_KEY_IS_EXPLICIT,
-                    MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT
-                )
-                build()
-            }
-        whenever(mediaControllerFactory.create(anyObject())).thenReturn(controller)
-        whenever(controller.metadata).thenReturn(metadata)
+        whenever(controller.metadata)
+            .thenReturn(
+                metadataBuilder
+                    .putLong(
+                        MediaConstants.METADATA_KEY_IS_EXPLICIT,
+                        MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT
+                    )
+                    .build()
+            )
 
         mediaDataManager.addListener(listener)
         mediaDataManager.onNotificationAdded(KEY, mediaNotification)
@@ -350,9 +366,6 @@
 
     @Test
     fun testOnMetaDataLoaded_withoutExplicitIndicator() {
-        whenever(mediaControllerFactory.create(anyObject())).thenReturn(controller)
-        whenever(controller.metadata).thenReturn(metadataBuilder.build())
-
         mediaDataManager.addListener(listener)
         mediaDataManager.onNotificationAdded(KEY, mediaNotification)
 
@@ -385,7 +398,6 @@
     @Test
     fun testOnMetaDataLoaded_conservesActiveFlag() {
         whenever(mediaControllerFactory.create(anyObject())).thenReturn(controller)
-        whenever(controller.metadata).thenReturn(metadataBuilder.build())
         mediaDataManager.addListener(listener)
         mediaDataManager.onNotificationAdded(KEY, mediaNotification)
         assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
@@ -404,33 +416,8 @@
 
     @Test
     fun testOnNotificationAdded_isRcn_markedRemote() {
-        val rcn =
-            SbnBuilder().run {
-                setPkg(SYSTEM_PACKAGE_NAME)
-                modifyNotification(context).also {
-                    it.setSmallIcon(android.R.drawable.ic_media_pause)
-                    it.setStyle(
-                        MediaStyle().apply {
-                            setMediaSession(session.sessionToken)
-                            setRemotePlaybackInfo("Remote device", 0, null)
-                        }
-                    )
-                }
-                build()
-            }
+        addNotificationAndLoad(remoteCastNotification)
 
-        mediaDataManager.onNotificationAdded(KEY, rcn)
-        assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
-        assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
-        verify(listener)
-            .onMediaDataLoaded(
-                eq(KEY),
-                eq(null),
-                capture(mediaDataCaptor),
-                eq(true),
-                eq(0),
-                eq(false)
-            )
         assertThat(mediaDataCaptor.value!!.playbackLocation)
             .isEqualTo(MediaData.PLAYBACK_CAST_REMOTE)
         verify(logger)
@@ -530,9 +517,78 @@
     }
 
     @Test
+    fun testOnNotificationRemoved_emptyTitle_notConverted() {
+        // GIVEN that the manager has a notification with a resume action and empty title.
+        whenever(controller.metadata)
+            .thenReturn(
+                metadataBuilder
+                    .putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_EMPTY_TITLE)
+                    .build()
+            )
+        addNotificationAndLoad()
+        val data = mediaDataCaptor.value
+        val instanceId = data.instanceId
+        assertThat(data.resumption).isFalse()
+        mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
+
+        // WHEN the notification is removed
+        reset(listener)
+        mediaDataManager.onNotificationRemoved(KEY)
+
+        // THEN active media is not converted to resume.
+        verify(listener, never())
+            .onMediaDataLoaded(
+                eq(PACKAGE_NAME),
+                eq(KEY),
+                capture(mediaDataCaptor),
+                eq(true),
+                eq(0),
+                eq(false)
+            )
+        verify(logger, never())
+            .logActiveConvertedToResume(anyInt(), eq(PACKAGE_NAME), eq(instanceId))
+        verify(logger, never()).logResumeMediaAdded(anyInt(), eq(PACKAGE_NAME), any())
+        verify(logger).logMediaRemoved(anyInt(), eq(PACKAGE_NAME), eq(instanceId))
+    }
+
+    @Test
+    fun testOnNotificationRemoved_blankTitle_notConverted() {
+        // GIVEN that the manager has a notification with a resume action and blank title.
+        whenever(controller.metadata)
+            .thenReturn(
+                metadataBuilder
+                    .putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_BLANK_TITLE)
+                    .build()
+            )
+        addNotificationAndLoad()
+        val data = mediaDataCaptor.value
+        val instanceId = data.instanceId
+        assertThat(data.resumption).isFalse()
+        mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
+
+        // WHEN the notification is removed
+        reset(listener)
+        mediaDataManager.onNotificationRemoved(KEY)
+
+        // THEN active media is not converted to resume.
+        verify(listener, never())
+            .onMediaDataLoaded(
+                eq(PACKAGE_NAME),
+                eq(KEY),
+                capture(mediaDataCaptor),
+                eq(true),
+                eq(0),
+                eq(false)
+            )
+        verify(logger, never())
+            .logActiveConvertedToResume(anyInt(), eq(PACKAGE_NAME), eq(instanceId))
+        verify(logger, never()).logResumeMediaAdded(anyInt(), eq(PACKAGE_NAME), any())
+        verify(logger).logMediaRemoved(anyInt(), eq(PACKAGE_NAME), eq(instanceId))
+    }
+
+    @Test
     fun testOnNotificationRemoved_withResumption() {
         // GIVEN that the manager has a notification with a resume action
-        whenever(controller.metadata).thenReturn(metadataBuilder.build())
         addNotificationAndLoad()
         val data = mediaDataCaptor.value
         assertThat(data.resumption).isFalse()
@@ -557,7 +613,6 @@
     @Test
     fun testOnNotificationRemoved_twoWithResumption() {
         // GIVEN that the manager has two notifications with resume actions
-        whenever(controller.metadata).thenReturn(metadataBuilder.build())
         mediaDataManager.onNotificationAdded(KEY, mediaNotification)
         mediaDataManager.onNotificationAdded(KEY_2, mediaNotification)
         assertThat(backgroundExecutor.runAllReady()).isEqualTo(2)
@@ -623,7 +678,6 @@
     @Test
     fun testOnNotificationRemoved_withResumption_butNotLocal() {
         // GIVEN that the manager has a notification with a resume action, but is not local
-        whenever(controller.metadata).thenReturn(metadataBuilder.build())
         whenever(playbackInfo.playbackType)
             .thenReturn(MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE)
         addNotificationAndLoad()
@@ -647,6 +701,56 @@
     }
 
     @Test
+    fun testOnNotificationRemoved_withResumption_isRemoteAndRemoteAllowed() {
+        // With the flag enabled to allow remote media to resume
+        whenever(mediaFlags.isRemoteResumeAllowed()).thenReturn(true)
+
+        // GIVEN that the manager has a notification with a resume action, but is not local
+        whenever(controller.metadata).thenReturn(metadataBuilder.build())
+        whenever(playbackInfo.playbackType)
+            .thenReturn(MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE)
+        addNotificationAndLoad()
+        val data = mediaDataCaptor.value
+        val dataRemoteWithResume =
+            data.copy(resumeAction = Runnable {}, playbackLocation = MediaData.PLAYBACK_CAST_LOCAL)
+        mediaDataManager.onMediaDataLoaded(KEY, null, dataRemoteWithResume)
+
+        // WHEN the notification is removed
+        mediaDataManager.onNotificationRemoved(KEY)
+
+        // THEN the media data is converted to a resume state
+        verify(listener)
+            .onMediaDataLoaded(
+                eq(PACKAGE_NAME),
+                eq(KEY),
+                capture(mediaDataCaptor),
+                eq(true),
+                eq(0),
+                eq(false)
+            )
+        assertThat(mediaDataCaptor.value.resumption).isTrue()
+    }
+
+    @Test
+    fun testOnNotificationRemoved_withResumption_isRcnAndRemoteAllowed() {
+        // With the flag enabled to allow remote media to resume
+        whenever(mediaFlags.isRemoteResumeAllowed()).thenReturn(true)
+
+        // GIVEN that the manager has a remote cast notification
+        addNotificationAndLoad(remoteCastNotification)
+        val data = mediaDataCaptor.value
+        assertThat(data.playbackLocation).isEqualTo(MediaData.PLAYBACK_CAST_REMOTE)
+        val dataRemoteWithResume = data.copy(resumeAction = Runnable {})
+        mediaDataManager.onMediaDataLoaded(KEY, null, dataRemoteWithResume)
+
+        // WHEN the RCN is removed
+        mediaDataManager.onNotificationRemoved(KEY)
+
+        // THEN the media data is removed
+        verify(listener).onMediaDataRemoved(eq(KEY))
+    }
+
+    @Test
     fun testOnNotificationRemoved_withResumption_tooManyPlayers() {
         // Given the maximum number of resume controls already
         val desc =
@@ -660,7 +764,6 @@
         }
 
         // And an active, resumable notification
-        whenever(controller.metadata).thenReturn(metadataBuilder.build())
         addNotificationAndLoad()
         val data = mediaDataCaptor.value
         assertThat(data.resumption).isFalse()
@@ -845,6 +948,74 @@
     }
 
     @Test
+    fun testAddResumptionControls_hasEmptyTitle() {
+        whenever(mediaFlags.isResumeProgressEnabled()).thenReturn(true)
+
+        // WHEN resumption controls are added that have empty title
+        val desc =
+            MediaDescription.Builder().run {
+                setTitle(SESSION_EMPTY_TITLE)
+                build()
+            }
+        mediaDataManager.addResumptionControls(
+            USER_ID,
+            desc,
+            Runnable {},
+            session.sessionToken,
+            APP_NAME,
+            pendingIntent,
+            PACKAGE_NAME
+        )
+
+        // Resumption controls are not added.
+        assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+        assertThat(foregroundExecutor.runAllReady()).isEqualTo(0)
+        verify(listener, never())
+            .onMediaDataLoaded(
+                eq(PACKAGE_NAME),
+                eq(null),
+                capture(mediaDataCaptor),
+                eq(true),
+                eq(0),
+                eq(false)
+            )
+    }
+
+    @Test
+    fun testAddResumptionControls_hasBlankTitle() {
+        whenever(mediaFlags.isResumeProgressEnabled()).thenReturn(true)
+
+        // WHEN resumption controls are added that have a blank title
+        val desc =
+            MediaDescription.Builder().run {
+                setTitle(SESSION_BLANK_TITLE)
+                build()
+            }
+        mediaDataManager.addResumptionControls(
+            USER_ID,
+            desc,
+            Runnable {},
+            session.sessionToken,
+            APP_NAME,
+            pendingIntent,
+            PACKAGE_NAME
+        )
+
+        // Resumption controls are not added.
+        assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+        assertThat(foregroundExecutor.runAllReady()).isEqualTo(0)
+        verify(listener, never())
+            .onMediaDataLoaded(
+                eq(PACKAGE_NAME),
+                eq(null),
+                capture(mediaDataCaptor),
+                eq(true),
+                eq(0),
+                eq(false)
+            )
+    }
+
+    @Test
     fun testResumptionDisabled_dismissesResumeControls() {
         // WHEN there are resume controls and resumption is switched off
         val desc =
@@ -1213,7 +1384,6 @@
     @Test
     fun testOnActiveMediaConverted_doesNotUpdateLastActiveTime() {
         // GIVEN that the manager has a notification with a resume action
-        whenever(controller.metadata).thenReturn(metadataBuilder.build())
         addNotificationAndLoad()
         val data = mediaDataCaptor.value
         val instanceId = data.instanceId
@@ -1513,7 +1683,6 @@
         val instanceId = mediaDataCaptor.value.instanceId
 
         // Location is updated to local cast
-        whenever(controller.metadata).thenReturn(metadataBuilder.build())
         whenever(playbackInfo.playbackType)
             .thenReturn(MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE)
         addNotificationAndLoad()
@@ -1526,22 +1695,7 @@
             )
 
         // update to remote cast
-        val rcn =
-            SbnBuilder().run {
-                setPkg(SYSTEM_PACKAGE_NAME) // System package
-                modifyNotification(context).also {
-                    it.setSmallIcon(android.R.drawable.ic_media_pause)
-                    it.setStyle(
-                        MediaStyle().apply {
-                            setMediaSession(session.sessionToken)
-                            setRemotePlaybackInfo("Remote device", 0, null)
-                        }
-                    )
-                }
-                build()
-            }
-
-        mediaDataManager.onNotificationAdded(KEY, rcn)
+        mediaDataManager.onNotificationAdded(KEY, remoteCastNotification)
         assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
         assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
         verify(logger)
@@ -1589,7 +1743,6 @@
     @Test
     fun testPlaybackStateChange_keyHasNullToken_doesNothing() {
         // When we get an update that sets the data's token to null
-        whenever(controller.metadata).thenReturn(metadataBuilder.build())
         addNotificationAndLoad()
         val data = mediaDataCaptor.value
         assertThat(data.resumption).isFalse()
@@ -1911,9 +2064,14 @@
         verify(listener).onMediaDataRemoved(eq(KEY))
     }
 
-    /** Helper function to add a media notification and capture the resulting MediaData */
+    /** Helper function to add a basic media notification and capture the resulting MediaData */
     private fun addNotificationAndLoad() {
-        mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+        addNotificationAndLoad(mediaNotification)
+    }
+
+    /** Helper function to add the given notification and capture the resulting MediaData */
+    private fun addNotificationAndLoad(sbn: StatusBarNotification) {
+        mediaDataManager.onNotificationAdded(KEY, sbn)
         assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
         assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
         verify(listener)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/resume/MediaResumeListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/resume/MediaResumeListenerTest.kt
index 136ace1..4dfa626 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/resume/MediaResumeListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/resume/MediaResumeListenerTest.kt
@@ -38,6 +38,7 @@
 import com.android.systemui.media.controls.models.player.MediaDeviceData
 import com.android.systemui.media.controls.pipeline.MediaDataManager
 import com.android.systemui.media.controls.pipeline.RESUME_MEDIA_TIMEOUT
+import com.android.systemui.media.controls.util.MediaFlags
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.tuner.TunerService
 import com.android.systemui.util.concurrency.FakeExecutor
@@ -92,6 +93,7 @@
     @Mock private lateinit var mockContext: Context
     @Mock private lateinit var pendingIntent: PendingIntent
     @Mock private lateinit var dumpManager: DumpManager
+    @Mock private lateinit var mediaFlags: MediaFlags
 
     @Captor lateinit var callbackCaptor: ArgumentCaptor<ResumeMediaBrowser.Callback>
     @Captor lateinit var actionCaptor: ArgumentCaptor<Runnable>
@@ -134,6 +136,7 @@
         whenever(mockContext.packageManager).thenReturn(context.packageManager)
         whenever(mockContext.contentResolver).thenReturn(context.contentResolver)
         whenever(mockContext.userId).thenReturn(context.userId)
+        whenever(mediaFlags.isRemoteResumeAllowed()).thenReturn(false)
 
         executor = FakeExecutor(clock)
         resumeListener =
@@ -146,7 +149,8 @@
                 tunerService,
                 resumeBrowserFactory,
                 dumpManager,
-                clock
+                clock,
+                mediaFlags,
             )
         resumeListener.setManager(mediaDataManager)
         mediaDataManager.addListener(resumeListener)
@@ -188,7 +192,8 @@
                 tunerService,
                 resumeBrowserFactory,
                 dumpManager,
-                clock
+                clock,
+                mediaFlags,
             )
         listener.setManager(mediaDataManager)
         verify(broadcastDispatcher, never())
@@ -244,6 +249,32 @@
     }
 
     @Test
+    fun testOnLoad_localCast_remoteResumeAllowed_doesCheck() {
+        // If local cast media is allowed to resume
+        whenever(mediaFlags.isRemoteResumeAllowed()).thenReturn(true)
+
+        // When media data is loaded that has not been checked yet, and is a local cast
+        val dataCast = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_LOCAL)
+        resumeListener.onMediaDataLoaded(KEY, null, dataCast)
+
+        // Then we report back to the manager
+        verify(mediaDataManager).setResumeAction(KEY, null)
+    }
+
+    @Test
+    fun testOnLoad_remoteCast_remoteResumeAllowed_doesCheck() {
+        // If local cast media is allowed to resume
+        whenever(mediaFlags.isRemoteResumeAllowed()).thenReturn(true)
+
+        // When media data is loaded that has not been checked yet, and is a remote cast
+        val dataRcn = data.copy(playbackLocation = MediaData.PLAYBACK_CAST_REMOTE)
+        resumeListener.onMediaDataLoaded(KEY, null, dataRcn)
+
+        // Then we do not take action
+        verify(mediaDataManager, never()).setResumeAction(any(), any())
+    }
+
+    @Test
     fun testOnLoad_checksForResume_hasService() {
         setUpMbsWithValidResolveInfo()
 
@@ -389,7 +420,8 @@
                 tunerService,
                 resumeBrowserFactory,
                 dumpManager,
-                clock
+                clock,
+                mediaFlags,
             )
         resumeListener.setManager(mediaDataManager)
         mediaDataManager.addListener(resumeListener)
@@ -421,7 +453,8 @@
                 tunerService,
                 resumeBrowserFactory,
                 dumpManager,
-                clock
+                clock,
+                mediaFlags,
             )
         resumeListener.setManager(mediaDataManager)
         mediaDataManager.addListener(resumeListener)
@@ -463,7 +496,8 @@
                 tunerService,
                 resumeBrowserFactory,
                 dumpManager,
-                clock
+                clock,
+                mediaFlags,
             )
         resumeListener.setManager(mediaDataManager)
         mediaDataManager.addListener(resumeListener)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
index a72634b..7f57077 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.media.controls.ui
 
 import android.app.PendingIntent
+import android.content.res.ColorStateList
 import android.content.res.Configuration
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
@@ -26,9 +27,9 @@
 import com.android.internal.logging.InstanceId
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
-import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -49,7 +50,7 @@
 import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider
 import com.android.systemui.statusbar.policy.ConfigurationController
-import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
@@ -89,7 +90,6 @@
     @Mock lateinit var mediaHostStatesManager: MediaHostStatesManager
     @Mock lateinit var mediaHostState: MediaHostState
     @Mock lateinit var activityStarter: ActivityStarter
-    @Mock @Main private lateinit var executor: DelayableExecutor
     @Mock lateinit var mediaDataManager: MediaDataManager
     @Mock lateinit var configurationController: ConfigurationController
     @Mock lateinit var falsingCollector: FalsingCollector
@@ -113,11 +113,15 @@
 
     private val clock = FakeSystemClock()
     private lateinit var mediaCarouselController: MediaCarouselController
+    private lateinit var mainExecutor: FakeExecutor
+    private lateinit var backgroundExecutor: FakeExecutor
 
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
         transitionRepository = FakeKeyguardTransitionRepository()
+        mainExecutor = FakeExecutor(clock)
+        backgroundExecutor = FakeExecutor(clock)
         mediaCarouselController =
             MediaCarouselController(
                 context,
@@ -126,7 +130,8 @@
                 mediaHostStatesManager,
                 activityStarter,
                 clock,
-                executor,
+                mainExecutor,
+                backgroundExecutor,
                 mediaDataManager,
                 configurationController,
                 falsingCollector,
@@ -401,6 +406,7 @@
                 resumption = true
             )
         )
+        runAllReady()
 
         assertEquals(
             MediaPlayerData.getMediaPlayerIndex("paused local"),
@@ -510,6 +516,8 @@
             false
         )
         mediaCarouselController.shouldScrollToKey = true
+        runAllReady()
+
         // switching between media players.
         listener.value.onMediaDataLoaded(
             "playing local",
@@ -531,6 +539,7 @@
                 resumption = false
             )
         )
+        runAllReady()
 
         assertEquals(
             MediaPlayerData.getMediaPlayerIndex("paused local"),
@@ -555,6 +564,7 @@
                 resumption = false
             )
         )
+        runAllReady()
 
         var playerIndex = MediaPlayerData.getMediaPlayerIndex("playing local")
         assertEquals(
@@ -577,6 +587,8 @@
                 packageName = "PACKAGE_NAME"
             )
         )
+        runAllReady()
+
         playerIndex = MediaPlayerData.getMediaPlayerIndex("playing local")
         assertEquals(playerIndex, 0)
     }
@@ -674,6 +686,8 @@
 
     @Test
     fun testOnConfigChanged_playersAreAddedBack() {
+        mediaCarouselController.pageIndicator = pageIndicator
+
         listener.value.onMediaDataLoaded(
             "playing local",
             null,
@@ -694,11 +708,15 @@
                 resumption = false
             )
         )
+        runAllReady()
 
         val playersSize = MediaPlayerData.players().size
 
         configListener.value.onConfigChanged(Configuration())
+        runAllReady()
 
+        verify(pageIndicator).tintList =
+            ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
         assertEquals(playersSize, MediaPlayerData.players().size)
         assertEquals(
             MediaPlayerData.getMediaPlayerIndex("playing local"),
@@ -707,6 +725,93 @@
     }
 
     @Test
+    fun testOnUiModeChanged_playersAreAddedBack() {
+        mediaCarouselController.pageIndicator = pageIndicator
+
+        listener.value.onMediaDataLoaded(
+            "paused local",
+            null,
+            DATA.copy(
+                active = true,
+                isPlaying = false,
+                playbackLocation = MediaData.PLAYBACK_LOCAL,
+                resumption = false
+            )
+        )
+        runAllReady()
+
+        val playersSize = MediaPlayerData.players().size
+        configListener.value.onUiModeChanged()
+        runAllReady()
+
+        verify(pageIndicator).tintList =
+            ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+        assertEquals(playersSize, MediaPlayerData.players().size)
+        assertEquals(
+            MediaPlayerData.getMediaPlayerIndex("paused local"),
+            mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
+        )
+    }
+
+    @Test
+    fun testOnDensityOrFontScaleChanged_playersAreAddedBack() {
+        mediaCarouselController.pageIndicator = pageIndicator
+
+        listener.value.onMediaDataLoaded(
+            "paused local",
+            null,
+            DATA.copy(
+                active = true,
+                isPlaying = false,
+                playbackLocation = MediaData.PLAYBACK_LOCAL,
+                resumption = false
+            )
+        )
+        runAllReady()
+
+        val playersSize = MediaPlayerData.players().size
+        configListener.value.onDensityOrFontScaleChanged()
+        runAllReady()
+
+        verify(pageIndicator).tintList =
+            ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+        assertEquals(playersSize, MediaPlayerData.players().size)
+        assertEquals(
+            MediaPlayerData.getMediaPlayerIndex("paused local"),
+            mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
+        )
+    }
+
+    @Test
+    fun testOnThemeChanged_playersAreAddedBack() {
+        mediaCarouselController.pageIndicator = pageIndicator
+
+        listener.value.onMediaDataLoaded(
+            "paused local",
+            null,
+            DATA.copy(
+                active = true,
+                isPlaying = false,
+                playbackLocation = MediaData.PLAYBACK_LOCAL,
+                resumption = false
+            )
+        )
+        runAllReady()
+
+        val playersSize = MediaPlayerData.players().size
+        configListener.value.onThemeChanged()
+        runAllReady()
+
+        verify(pageIndicator).tintList =
+            ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+        assertEquals(playersSize, MediaPlayerData.players().size)
+        assertEquals(
+            MediaPlayerData.getMediaPlayerIndex("paused local"),
+            mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
+        )
+    }
+
+    @Test
     fun testRecommendation_persistentEnabled_newSmartspaceLoaded_updatesSort() {
         testRecommendation_persistentEnabled_inactiveSmartspaceDataLoaded_isAdded()
 
@@ -832,4 +937,9 @@
         // Verify that seekbar listening attribute in media control panel is set to false.
         verify(panel, times(MediaPlayerData.players().size)).listening = false
     }
+
+    private fun runAllReady() {
+        backgroundExecutor.runAllReady()
+        mainExecutor.runAllReady()
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
index 537dfb8..1c9336a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
@@ -13,6 +13,7 @@
 import com.android.systemui.statusbar.phone.AutoHideController
 import com.android.systemui.statusbar.phone.LightBarController
 import com.android.systemui.statusbar.phone.LightBarTransitionsController
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
 import com.android.wm.shell.back.BackAnimation
 import com.android.wm.shell.pip.Pip
 import org.junit.Before
@@ -66,6 +67,8 @@
     lateinit var mBackAnimation: BackAnimation
     @Mock
     lateinit var mCurrentSysUiState: NavBarHelper.CurrentSysuiState
+    @Mock
+    lateinit var mStatusBarKeyguardViewManager: StatusBarKeyguardViewManager
 
     @Before
     fun setup() {
@@ -76,7 +79,7 @@
         `when`(mSysUiState.setFlag(anyInt(), anyBoolean())).thenReturn(mSysUiState)
         mTaskStackChangeListeners = TaskStackChangeListeners.getTestInstance()
         mTaskbarDelegate = TaskbarDelegate(context, mEdgeBackGestureHandlerFactory,
-                mLightBarControllerFactory)
+                mLightBarControllerFactory, mStatusBarKeyguardViewManager)
         mTaskbarDelegate.setDependencies(mCommandQueue, mOverviewProxyService, mNavBarHelper,
         mNavigationModeController, mSysUiState, mDumpManager, mAutoHideController,
                 mLightBarController, mOptionalPip, mBackAnimation, mTaskStackChangeListeners)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/process/condition/UserProcessConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/process/condition/SystemProcessConditionTest.java
similarity index 70%
rename from packages/SystemUI/tests/src/com/android/systemui/process/condition/UserProcessConditionTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/process/condition/SystemProcessConditionTest.java
index 2293fc5..fb71977 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/process/condition/UserProcessConditionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/process/condition/SystemProcessConditionTest.java
@@ -26,7 +26,6 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.process.ProcessWrapper;
-import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.condition.Condition;
 import com.android.systemui.shared.condition.Monitor;
 import com.android.systemui.util.concurrency.FakeExecutor;
@@ -41,10 +40,7 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 @SmallTest
-public class UserProcessConditionTest extends SysuiTestCase {
-    @Mock
-    UserTracker mUserTracker;
-
+public class SystemProcessConditionTest extends SysuiTestCase {
     @Mock
     ProcessWrapper mProcessWrapper;
 
@@ -59,15 +55,14 @@
     }
 
     /**
-     * Verifies condition reports false when tracker reports a different user id than the
-     * identifier from the process handle.
+     * Verifies condition reports false when tracker reports the process is being ran by the
+     * system user.
      */
     @Test
-    public void testConditionFailsWithDifferentIds() {
+    public void testConditionFailsWithNonSystemProcess() {
 
-        final Condition condition = new UserProcessCondition(mProcessWrapper, mUserTracker);
-        when(mProcessWrapper.getUserHandleIdentifier()).thenReturn(0);
-        when(mUserTracker.getUserId()).thenReturn(1);
+        final Condition condition = new SystemProcessCondition(mProcessWrapper);
+        when(mProcessWrapper.isSystemUser()).thenReturn(false);
 
         final Monitor monitor = new Monitor(mExecutor);
 
@@ -81,15 +76,14 @@
     }
 
     /**
-     * Verifies condition reports false when tracker reports a different user id than the
-     * identifier from the process handle.
+     * Verifies condition reports true when tracker reports the process is being ran by the
+     * system user.
      */
     @Test
-    public void testConditionSucceedsWithSameIds() {
+    public void testConditionSucceedsWithSystemProcess() {
 
-        final Condition condition = new UserProcessCondition(mProcessWrapper, mUserTracker);
-        when(mProcessWrapper.getUserHandleIdentifier()).thenReturn(0);
-        when(mUserTracker.getUserId()).thenReturn(0);
+        final Condition condition = new SystemProcessCondition(mProcessWrapper);
+        when(mProcessWrapper.isSystemUser()).thenReturn(true);
 
         final Monitor monitor = new Monitor(mExecutor);
 
@@ -101,5 +95,4 @@
 
         verify(mCallback).onConditionsChanged(true);
     }
-
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 4caa50f..89606bf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -52,14 +52,13 @@
 import com.android.systemui.SysuiBaseFragmentTest;
 import com.android.systemui.animation.ShadeInterpolation;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FakeFeatureFlags;
 import com.android.systemui.media.controls.ui.MediaHost;
-import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.qs.customize.QSCustomizerController;
 import com.android.systemui.qs.dagger.QSFragmentComponent;
 import com.android.systemui.qs.external.TileServiceRequestController;
 import com.android.systemui.qs.footer.ui.binder.FooterActionsViewBinder;
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel;
+import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.settings.FakeDisplayTracker;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.StatusBarState;
@@ -86,7 +85,6 @@
     @Mock private MediaHost mQSMediaHost;
     @Mock private MediaHost mQQSMediaHost;
     @Mock private KeyguardBypassController mBypassController;
-    @Mock private FalsingManager mFalsingManager;
     @Mock private TileServiceRequestController.Builder mTileServiceRequestControllerBuilder;
     @Mock private TileServiceRequestController mTileServiceRequestController;
     @Mock private QSCustomizerController mQsCustomizerController;
@@ -503,11 +501,9 @@
         setUpMedia();
         setUpOther();
 
-        FakeFeatureFlags featureFlags = new FakeFeatureFlags();
         return new QSFragment(
                 new RemoteInputQuickSettingsDisabler(
                         context, commandQueue, mock(ConfigurationController.class)),
-                mock(QSTileHost.class),
                 mStatusBarStateController,
                 commandQueue,
                 mQSMediaHost,
@@ -515,9 +511,8 @@
                 mBypassController,
                 mQsComponentFactory,
                 mock(QSFragmentDisableFlagsLogger.class),
-                mFalsingManager,
                 mock(DumpManager.class),
-                featureFlags,
+                mock(QSLogger.class),
                 mock(FooterActionsController.class),
                 mFooterActionsViewModelFactory);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
index 5058373..3d55c51 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
@@ -71,7 +71,7 @@
     @Mock
     private QSPanel mQSPanel;
     @Mock
-    private QSTileHost mQSTileHost;
+    private QSHost mQSHost;
     @Mock
     private QSCustomizerController mQSCustomizerController;
     @Mock
@@ -105,7 +105,7 @@
 
     /** Implementation needed to ensure we have a reflectively-available class name. */
     private class TestableQSPanelControllerBase extends QSPanelControllerBase<QSPanel> {
-        protected TestableQSPanelControllerBase(QSPanel view, QSTileHost host,
+        protected TestableQSPanelControllerBase(QSPanel view, QSHost host,
                 QSCustomizerController qsCustomizerController, MediaHost mediaHost,
                 MetricsLogger metricsLogger, UiEventLogger uiEventLogger, QSLogger qsLogger,
                 DumpManager dumpManager) {
@@ -130,8 +130,8 @@
         when(mQSPanel.getOrCreateTileLayout()).thenReturn(mPagedTileLayout);
         when(mQSPanel.getTileLayout()).thenReturn(mPagedTileLayout);
         when(mQSTile.getTileSpec()).thenReturn("dnd");
-        when(mQSTileHost.getTiles()).thenReturn(Collections.singleton(mQSTile));
-        when(mQSTileHost.createTileView(any(), eq(mQSTile), anyBoolean())).thenReturn(mQSTileView);
+        when(mQSHost.getTiles()).thenReturn(Collections.singleton(mQSTile));
+        when(mQSHost.createTileView(any(), eq(mQSTile), anyBoolean())).thenReturn(mQSTileView);
         when(mQSTileRevealControllerFactory.create(any(), any()))
                 .thenReturn(mQSTileRevealController);
         when(mMediaHost.getDisappearParameters()).thenReturn(new DisappearParameters());
@@ -142,7 +142,7 @@
             return null;
         }).when(mQSPanel).setListening(anyBoolean());
 
-        mController = new TestableQSPanelControllerBase(mQSPanel, mQSTileHost,
+        mController = new TestableQSPanelControllerBase(mQSPanel, mQSHost,
                 mQSCustomizerController, mMediaHost,
                 mMetricsLogger, mUiEventLogger, mQSLogger, mDumpManager);
 
@@ -155,7 +155,7 @@
         mController.onViewDetached();
 
         QSPanelControllerBase<QSPanel> controller = new TestableQSPanelControllerBase(mQSPanel,
-                mQSTileHost, mQSCustomizerController, mMediaHost,
+                mQSHost, mQSCustomizerController, mMediaHost,
                 mMetricsLogger, mUiEventLogger, mQSLogger, mDumpManager) {
             @Override
             protected QSTileRevealController createTileRevealController() {
@@ -250,7 +250,7 @@
 
         when(mResources.getBoolean(R.bool.config_use_split_notification_shade)).thenReturn(false);
         when(mQSPanel.getDumpableTag()).thenReturn("QSPanelLandscape");
-        mController = new TestableQSPanelControllerBase(mQSPanel, mQSTileHost,
+        mController = new TestableQSPanelControllerBase(mQSPanel, mQSHost,
                 mQSCustomizerController, mMediaHost,
                 mMetricsLogger, mUiEventLogger, mQSLogger, mDumpManager);
         mController.init();
@@ -259,7 +259,7 @@
 
         when(mResources.getBoolean(R.bool.config_use_split_notification_shade)).thenReturn(true);
         when(mQSPanel.getDumpableTag()).thenReturn("QSPanelPortrait");
-        mController = new TestableQSPanelControllerBase(mQSPanel, mQSTileHost,
+        mController = new TestableQSPanelControllerBase(mQSPanel, mQSHost,
                 mQSCustomizerController, mMediaHost,
                 mMetricsLogger, mUiEventLogger, mQSLogger, mDumpManager);
         mController.init();
@@ -291,7 +291,7 @@
 
     @Test
     public void testRefreshAllTilesDoesntRefreshListeningTiles() {
-        when(mQSTileHost.getTiles()).thenReturn(List.of(mQSTile, mOtherTile));
+        when(mQSHost.getTiles()).thenReturn(List.of(mQSTile, mOtherTile));
         mController.setTiles();
 
         when(mQSTile.isListening()).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
index 6cf642c..a0d8f98 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
@@ -9,7 +9,6 @@
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
-import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.media.controls.ui.MediaHost
 import com.android.systemui.media.controls.ui.MediaHostState
 import com.android.systemui.plugins.FalsingManager
@@ -41,7 +40,7 @@
 
     @Mock private lateinit var qsPanel: QSPanel
     @Mock private lateinit var tunerService: TunerService
-    @Mock private lateinit var qsTileHost: QSTileHost
+    @Mock private lateinit var qsHost: QSHost
     @Mock private lateinit var qsCustomizerController: QSCustomizerController
     @Mock private lateinit var qsTileRevealControllerFactory: QSTileRevealController.Factory
     @Mock private lateinit var dumpManager: DumpManager
@@ -57,7 +56,6 @@
     @Mock private lateinit var tile: QSTile
     @Mock private lateinit var otherTile: QSTile
     @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
-    @Mock private lateinit var featureFlags: FeatureFlags
     @Mock private lateinit var configuration: Configuration
     @Mock private lateinit var pagedTileLayout: PagedTileLayout
 
@@ -70,7 +68,7 @@
 
         whenever(brightnessSliderFactory.create(any(), any())).thenReturn(brightnessSlider)
         whenever(brightnessControllerFactory.create(any())).thenReturn(brightnessController)
-        testableResources.addOverride(R.bool.config_use_split_notification_shade, false)
+        setShouldUseSplitShade(false)
         whenever(qsPanel.resources).thenReturn(testableResources.resources)
         whenever(qsPanel.getOrCreateTileLayout()).thenReturn(pagedTileLayout)
         whenever(statusBarKeyguardViewManager.isPrimaryBouncerInTransit()).thenReturn(false)
@@ -81,7 +79,7 @@
         controller = QSPanelController(
             qsPanel,
             tunerService,
-            qsTileHost,
+            qsHost,
             qsCustomizerController,
             /* usingMediaPlayer= */ true,
             mediaHost,
@@ -93,8 +91,7 @@
             brightnessControllerFactory,
             brightnessSliderFactory,
             falsingManager,
-            statusBarKeyguardViewManager,
-            featureFlags
+            statusBarKeyguardViewManager
         )
     }
 
@@ -112,7 +109,7 @@
 
     @Test
     fun testSetListeningDoesntRefreshListeningTiles() {
-        whenever(qsTileHost.getTiles()).thenReturn(listOf(tile, otherTile))
+        whenever(qsHost.getTiles()).thenReturn(listOf(tile, otherTile))
         controller.setTiles()
         whenever(tile.isListening()).thenReturn(false)
         whenever(otherTile.isListening()).thenReturn(true)
@@ -133,12 +130,31 @@
 
     @Test
     fun configurationChange_onlySplitShadeConfigChanges_tileAreRedistributed() {
-        testableResources.addOverride(R.bool.config_use_split_notification_shade, false)
+        setShouldUseSplitShade(false)
         controller.mOnConfigurationChangedListener.onConfigurationChange(configuration)
         verify(pagedTileLayout, never()).forceTilesRedistribution(any())
 
-        testableResources.addOverride(R.bool.config_use_split_notification_shade, true)
+        setShouldUseSplitShade(true)
         controller.mOnConfigurationChangedListener.onConfigurationChange(configuration)
         verify(pagedTileLayout).forceTilesRedistribution("Split shade state changed")
     }
+
+    @Test
+    fun configurationChange_onlySplitShadeConfigChanges_qsPanelCanBeCollapsed() {
+        setShouldUseSplitShade(false)
+        controller.mOnConfigurationChangedListener.onConfigurationChange(configuration)
+        verify(qsPanel, never()).setCanCollapse(anyBoolean())
+
+        setShouldUseSplitShade(true)
+        controller.mOnConfigurationChangedListener.onConfigurationChange(configuration)
+        verify(qsPanel).setCanCollapse(false)
+
+        setShouldUseSplitShade(false)
+        controller.mOnConfigurationChangedListener.onConfigurationChange(configuration)
+        verify(qsPanel).setCanCollapse(true)
+    }
+
+    private fun setShouldUseSplitShade(shouldUse: Boolean) {
+        testableResources.addOverride(R.bool.config_use_split_notification_shade, shouldUse)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
index d52b296..93cebe2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
@@ -37,6 +37,7 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
@@ -164,26 +165,11 @@
     }
 
     @Test
-    fun testTopPadding_notCombinedHeaders() {
-        qsPanel.setUsingCombinedHeaders(false)
+    fun testTopPadding() {
         val padding = 10
         val paddingCombined = 100
         context.orCreateTestableResources.addOverride(R.dimen.qs_panel_padding_top, padding)
-        context.orCreateTestableResources.addOverride(
-                R.dimen.qs_panel_padding_top_combined_headers, paddingCombined)
-
-        qsPanel.updatePadding()
-        assertThat(qsPanel.paddingTop).isEqualTo(padding)
-    }
-
-    @Test
-    fun testTopPadding_combinedHeaders() {
-        qsPanel.setUsingCombinedHeaders(true)
-        val padding = 10
-        val paddingCombined = 100
-        context.orCreateTestableResources.addOverride(R.dimen.qs_panel_padding_top, padding)
-        context.orCreateTestableResources.addOverride(
-                R.dimen.qs_panel_padding_top_combined_headers, paddingCombined)
+        context.orCreateTestableResources.addOverride(R.dimen.qs_panel_padding_top, paddingCombined)
 
         qsPanel.updatePadding()
         assertThat(qsPanel.paddingTop).isEqualTo(paddingCombined)
@@ -196,6 +182,16 @@
         qsPanel.setSquishinessFraction(0.5f)
     }
 
+    @Test
+    fun testSplitShade_CollapseAccessibilityActionNotAnnounced() {
+        qsPanel.setCanCollapse(false)
+        val accessibilityInfo = mock(AccessibilityNodeInfo::class.java)
+        qsPanel.onInitializeAccessibilityNodeInfo(accessibilityInfo)
+
+        val actionCollapse = AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE
+        verify(accessibilityInfo, never()).addAction(actionCollapse)
+    }
+
     private infix fun View.isLeftOf(other: View): Boolean {
         val rect = Rect()
         getBoundsOnScreen(rect)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
index fb1a720..34d2b14 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
@@ -69,7 +69,6 @@
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.phone.AutoTileManager;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
-import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.util.FakeSharedPreferences;
 import com.android.systemui.util.concurrency.FakeExecutor;
@@ -100,11 +99,9 @@
     private static ComponentName CUSTOM_TILE =
             ComponentName.unflattenFromString("TEST_PKG/.TEST_CLS");
     private static final String CUSTOM_TILE_SPEC = CustomTile.toSpec(CUSTOM_TILE);
-    private static final String SETTING = QSTileHost.TILES_SETTING;
+    private static final String SETTING = QSHost.TILES_SETTING;
 
     @Mock
-    private StatusBarIconController mIconController;
-    @Mock
     private QSFactory mDefaultFactory;
     @Mock
     private PluginManager mPluginManager;
@@ -167,7 +164,7 @@
 
         mSecureSettings = new FakeSettings();
         saveSetting("");
-        mQSTileHost = new TestQSTileHost(mContext, mIconController, mDefaultFactory, mMainExecutor,
+        mQSTileHost = new TestQSTileHost(mContext, mDefaultFactory, mMainExecutor,
                 mPluginManager, mTunerService, mAutoTiles, mDumpManager, mCentralSurfaces,
                 mQSLogger, mUiEventLogger, mUserTracker, mSecureSettings, mCustomTileStatePersister,
                 mTileServiceRequestControllerBuilder, mTileLifecycleManagerFactory,
@@ -248,44 +245,44 @@
     public void testRemoveWifiAndCellularWithoutInternet() {
         saveSetting("wifi, spec1, cell, spec2");
 
-        assertEquals("internet", mQSTileHost.mTileSpecs.get(0));
-        assertEquals("spec1", mQSTileHost.mTileSpecs.get(1));
-        assertEquals("spec2", mQSTileHost.mTileSpecs.get(2));
+        assertEquals("internet", mQSTileHost.getSpecs().get(0));
+        assertEquals("spec1", mQSTileHost.getSpecs().get(1));
+        assertEquals("spec2", mQSTileHost.getSpecs().get(2));
     }
 
     @Test
     public void testRemoveWifiAndCellularWithInternet() {
         saveSetting("wifi, spec1, cell, spec2, internet");
 
-        assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
-        assertEquals("spec2", mQSTileHost.mTileSpecs.get(1));
-        assertEquals("internet", mQSTileHost.mTileSpecs.get(2));
+        assertEquals("spec1", mQSTileHost.getSpecs().get(0));
+        assertEquals("spec2", mQSTileHost.getSpecs().get(1));
+        assertEquals("internet", mQSTileHost.getSpecs().get(2));
     }
 
     @Test
     public void testRemoveWifiWithoutInternet() {
         saveSetting("spec1, wifi, spec2");
 
-        assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
-        assertEquals("internet", mQSTileHost.mTileSpecs.get(1));
-        assertEquals("spec2", mQSTileHost.mTileSpecs.get(2));
+        assertEquals("spec1", mQSTileHost.getSpecs().get(0));
+        assertEquals("internet", mQSTileHost.getSpecs().get(1));
+        assertEquals("spec2", mQSTileHost.getSpecs().get(2));
     }
 
     @Test
     public void testRemoveCellWithInternet() {
         saveSetting("spec1, spec2, cell, internet");
 
-        assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
-        assertEquals("spec2", mQSTileHost.mTileSpecs.get(1));
-        assertEquals("internet", mQSTileHost.mTileSpecs.get(2));
+        assertEquals("spec1", mQSTileHost.getSpecs().get(0));
+        assertEquals("spec2", mQSTileHost.getSpecs().get(1));
+        assertEquals("internet", mQSTileHost.getSpecs().get(2));
     }
 
     @Test
     public void testNoWifiNoCellularNoInternet() {
         saveSetting("spec1,spec2");
 
-        assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
-        assertEquals("spec2", mQSTileHost.mTileSpecs.get(1));
+        assertEquals("spec1", mQSTileHost.getSpecs().get(0));
+        assertEquals("spec2", mQSTileHost.getSpecs().get(1));
     }
 
     @Test
@@ -332,9 +329,9 @@
 
         mQSTileHost.addTile("spec1");
 
-        assertEquals(2, mQSTileHost.mTileSpecs.size());
-        assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
-        assertEquals("spec2", mQSTileHost.mTileSpecs.get(1));
+        assertEquals(2, mQSTileHost.getSpecs().size());
+        assertEquals("spec1", mQSTileHost.getSpecs().get(0));
+        assertEquals("spec2", mQSTileHost.getSpecs().get(1));
     }
 
     @Test
@@ -346,10 +343,10 @@
         mQSTileHost.addTile("spec2", 1);
         mMainExecutor.runAllReady();
 
-        assertEquals(3, mQSTileHost.mTileSpecs.size());
-        assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
-        assertEquals("spec2", mQSTileHost.mTileSpecs.get(1));
-        assertEquals("spec3", mQSTileHost.mTileSpecs.get(2));
+        assertEquals(3, mQSTileHost.getSpecs().size());
+        assertEquals("spec1", mQSTileHost.getSpecs().get(0));
+        assertEquals("spec2", mQSTileHost.getSpecs().get(1));
+        assertEquals("spec3", mQSTileHost.getSpecs().get(2));
     }
 
     @Test
@@ -361,10 +358,10 @@
         mQSTileHost.addTile("spec2", 100);
         mMainExecutor.runAllReady();
 
-        assertEquals(3, mQSTileHost.mTileSpecs.size());
-        assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
-        assertEquals("spec3", mQSTileHost.mTileSpecs.get(1));
-        assertEquals("spec2", mQSTileHost.mTileSpecs.get(2));
+        assertEquals(3, mQSTileHost.getSpecs().size());
+        assertEquals("spec1", mQSTileHost.getSpecs().get(0));
+        assertEquals("spec3", mQSTileHost.getSpecs().get(1));
+        assertEquals("spec2", mQSTileHost.getSpecs().get(2));
     }
 
     @Test
@@ -376,10 +373,10 @@
         mQSTileHost.addTile("spec2", QSTileHost.POSITION_AT_END);
         mMainExecutor.runAllReady();
 
-        assertEquals(3, mQSTileHost.mTileSpecs.size());
-        assertEquals("spec1", mQSTileHost.mTileSpecs.get(0));
-        assertEquals("spec3", mQSTileHost.mTileSpecs.get(1));
-        assertEquals("spec2", mQSTileHost.mTileSpecs.get(2));
+        assertEquals(3, mQSTileHost.getSpecs().size());
+        assertEquals("spec1", mQSTileHost.getSpecs().get(0));
+        assertEquals("spec3", mQSTileHost.getSpecs().get(1));
+        assertEquals("spec2", mQSTileHost.getSpecs().get(2));
     }
 
     @Test
@@ -389,8 +386,8 @@
         mQSTileHost.addTile(CUSTOM_TILE, /* end */ false);
         mMainExecutor.runAllReady();
 
-        assertEquals(1, mQSTileHost.mTileSpecs.size());
-        assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.mTileSpecs.get(0));
+        assertEquals(1, mQSTileHost.getSpecs().size());
+        assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.getSpecs().get(0));
     }
 
     @Test
@@ -400,8 +397,8 @@
         mQSTileHost.addTile(CUSTOM_TILE);
         mMainExecutor.runAllReady();
 
-        assertEquals(2, mQSTileHost.mTileSpecs.size());
-        assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.mTileSpecs.get(0));
+        assertEquals(2, mQSTileHost.getSpecs().size());
+        assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.getSpecs().get(0));
     }
 
     @Test
@@ -411,8 +408,8 @@
         mQSTileHost.addTile(CUSTOM_TILE, /* end */ false);
         mMainExecutor.runAllReady();
 
-        assertEquals(2, mQSTileHost.mTileSpecs.size());
-        assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.mTileSpecs.get(0));
+        assertEquals(2, mQSTileHost.getSpecs().size());
+        assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.getSpecs().get(0));
     }
 
     @Test
@@ -422,8 +419,8 @@
         mQSTileHost.addTile(CUSTOM_TILE, /* end */ true);
         mMainExecutor.runAllReady();
 
-        assertEquals(2, mQSTileHost.mTileSpecs.size());
-        assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.mTileSpecs.get(1));
+        assertEquals(2, mQSTileHost.getSpecs().size());
+        assertEquals(CUSTOM_TILE_SPEC, mQSTileHost.getSpecs().get(1));
     }
 
     @Test
@@ -478,7 +475,7 @@
         mQSTileHost.removeTiles(List.of("spec1", "spec2"));
 
         mMainExecutor.runAllReady();
-        assertEquals(List.of("spec3"), mQSTileHost.mTileSpecs);
+        assertEquals(List.of("spec3"), mQSTileHost.getSpecs());
     }
 
     @Test
@@ -488,7 +485,7 @@
         mQSTileHost.removeTile("spec3");
 
         mMainExecutor.runAllReady();
-        assertEquals(List.of("spec2"), mQSTileHost.mTileSpecs);
+        assertEquals(List.of("spec2"), mQSTileHost.getSpecs());
         assertEquals("spec2", getSetting());
     }
 
@@ -497,10 +494,10 @@
         saveSetting("spec1,spec2");
 
         mQSTileHost.addTile("spec3");
-        assertEquals(List.of("spec1", "spec2"), mQSTileHost.mTileSpecs);
+        assertEquals(List.of("spec1", "spec2"), mQSTileHost.getSpecs());
 
         mMainExecutor.runAllReady();
-        assertEquals(List.of("spec1", "spec2", "spec3"), mQSTileHost.mTileSpecs);
+        assertEquals(List.of("spec1", "spec2", "spec3"), mQSTileHost.getSpecs());
     }
 
     @Test
@@ -508,10 +505,10 @@
         saveSetting("spec1,spec2");
 
         mQSTileHost.removeTile("spec1");
-        assertEquals(List.of("spec1", "spec2"), mQSTileHost.mTileSpecs);
+        assertEquals(List.of("spec1", "spec2"), mQSTileHost.getSpecs());
 
         mMainExecutor.runAllReady();
-        assertEquals(List.of("spec2"), mQSTileHost.mTileSpecs);
+        assertEquals(List.of("spec2"), mQSTileHost.getSpecs());
     }
 
     @Test
@@ -519,10 +516,10 @@
         saveSetting("spec1,spec2,spec3");
 
         mQSTileHost.removeTiles(List.of("spec3", "spec1"));
-        assertEquals(List.of("spec1", "spec2", "spec3"), mQSTileHost.mTileSpecs);
+        assertEquals(List.of("spec1", "spec2", "spec3"), mQSTileHost.getSpecs());
 
         mMainExecutor.runAllReady();
-        assertEquals(List.of("spec2"), mQSTileHost.mTileSpecs);
+        assertEquals(List.of("spec2"), mQSTileHost.getSpecs());
     }
 
     @Test
@@ -530,17 +527,17 @@
         saveSetting("spec1," + CUSTOM_TILE_SPEC);
 
         mQSTileHost.removeTileByUser(CUSTOM_TILE);
-        assertEquals(List.of("spec1", CUSTOM_TILE_SPEC), mQSTileHost.mTileSpecs);
+        assertEquals(List.of("spec1", CUSTOM_TILE_SPEC), mQSTileHost.getSpecs());
 
         mMainExecutor.runAllReady();
-        assertEquals(List.of("spec1"), mQSTileHost.mTileSpecs);
+        assertEquals(List.of("spec1"), mQSTileHost.getSpecs());
     }
 
     @Test
     public void testNonValidTileNotStoredInSettings() {
         saveSetting("spec1,not-valid");
 
-        assertEquals(List.of("spec1"), mQSTileHost.mTileSpecs);
+        assertEquals(List.of("spec1"), mQSTileHost.getSpecs());
         assertEquals("spec1", getSetting());
     }
 
@@ -548,14 +545,14 @@
     public void testNotAvailableTileNotStoredInSettings() {
         saveSetting("spec1,na");
 
-        assertEquals(List.of("spec1"), mQSTileHost.mTileSpecs);
+        assertEquals(List.of("spec1"), mQSTileHost.getSpecs());
         assertEquals("spec1", getSetting());
     }
 
     @Test
     public void testIsTileAdded_true() {
         int user = mUserTracker.getUserId();
-        getSharedPreferenecesForUser(user)
+        getSharedPreferencesForUser(user)
                 .edit()
                 .putBoolean(CUSTOM_TILE.flattenToString(), true)
                 .apply();
@@ -566,7 +563,7 @@
     @Test
     public void testIsTileAdded_false() {
         int user = mUserTracker.getUserId();
-        getSharedPreferenecesForUser(user)
+        getSharedPreferencesForUser(user)
                 .edit()
                 .putBoolean(CUSTOM_TILE.flattenToString(), false)
                 .apply();
@@ -597,7 +594,7 @@
         int user = mUserTracker.getUserId();
         mQSTileHost.setTileAdded(CUSTOM_TILE, user, true);
 
-        assertTrue(getSharedPreferenecesForUser(user)
+        assertTrue(getSharedPreferencesForUser(user)
                 .getBoolean(CUSTOM_TILE.flattenToString(), false));
     }
 
@@ -606,7 +603,7 @@
         int user = mUserTracker.getUserId();
         mQSTileHost.setTileAdded(CUSTOM_TILE, user, false);
 
-        assertFalse(getSharedPreferenecesForUser(user)
+        assertFalse(getSharedPreferencesForUser(user)
                 .getBoolean(CUSTOM_TILE.flattenToString(), false));
     }
 
@@ -615,7 +612,7 @@
         int user = mUserTracker.getUserId();
         mQSTileHost.setTileAdded(CUSTOM_TILE, user, true);
 
-        assertFalse(getSharedPreferenecesForUser(user + 1)
+        assertFalse(getSharedPreferencesForUser(user + 1)
                 .getBoolean(CUSTOM_TILE.flattenToString(), false));
     }
 
@@ -627,8 +624,8 @@
         // This will be done by TileServiceManager
         mQSTileHost.setTileAdded(CUSTOM_TILE, user, true);
 
-        mQSTileHost.changeTilesByUser(mQSTileHost.mTileSpecs, List.of("spec1"));
-        assertFalse(getSharedPreferenecesForUser(user)
+        mQSTileHost.changeTilesByUser(mQSTileHost.getSpecs(), List.of("spec1"));
+        assertFalse(getSharedPreferencesForUser(user)
                 .getBoolean(CUSTOM_TILE.flattenToString(), false));
     }
 
@@ -642,7 +639,7 @@
 
         mQSTileHost.removeTileByUser(CUSTOM_TILE);
         mMainExecutor.runAllReady();
-        assertFalse(getSharedPreferenecesForUser(user)
+        assertFalse(getSharedPreferencesForUser(user)
                 .getBoolean(CUSTOM_TILE.flattenToString(), false));
     }
 
@@ -656,7 +653,7 @@
 
         mQSTileHost.removeTile(CUSTOM_TILE_SPEC);
         mMainExecutor.runAllReady();
-        assertFalse(getSharedPreferenecesForUser(user)
+        assertFalse(getSharedPreferencesForUser(user)
                 .getBoolean(CUSTOM_TILE.flattenToString(), false));
     }
 
@@ -681,12 +678,12 @@
         assertEquals(CUSTOM_TILE.getClassName(), proto.tiles[1].getComponentName().className);
     }
 
-    private SharedPreferences getSharedPreferenecesForUser(int user) {
+    private SharedPreferences getSharedPreferencesForUser(int user) {
         return mUserFileManager.getSharedPreferences(QSTileHost.TILES, 0, user);
     }
 
     private class TestQSTileHost extends QSTileHost {
-        TestQSTileHost(Context context, StatusBarIconController iconController,
+        TestQSTileHost(Context context,
                 QSFactory defaultFactory, Executor mainExecutor,
                 PluginManager pluginManager, TunerService tunerService,
                 Provider<AutoTileManager> autoTiles, DumpManager dumpManager,
@@ -696,7 +693,7 @@
                 TileServiceRequestController.Builder tileServiceRequestControllerBuilder,
                 TileLifecycleManager.Factory tileLifecycleManagerFactory,
                 UserFileManager userFileManager) {
-            super(context, iconController, defaultFactory, mainExecutor, pluginManager,
+            super(context, defaultFactory, mainExecutor, pluginManager,
                     tunerService, autoTiles, dumpManager, Optional.of(centralSurfaces), qsLogger,
                     uiEventLogger, userTracker, secureSettings, customTileStatePersister,
                     tileServiceRequestControllerBuilder, tileLifecycleManagerFactory,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
index f53e997..71ea831 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
@@ -50,7 +50,7 @@
 class QuickQSPanelControllerTest : SysuiTestCase() {
 
     @Mock private lateinit var quickQSPanel: QuickQSPanel
-    @Mock private lateinit var qsTileHost: QSTileHost
+    @Mock private lateinit var qsHost: QSHost
     @Mock private lateinit var qsCustomizerController: QSCustomizerController
     @Mock private lateinit var mediaHost: MediaHost
     @Mock private lateinit var metricsLogger: MetricsLogger
@@ -75,12 +75,12 @@
         whenever(quickQSPanel.isAttachedToWindow).thenReturn(true)
         whenever(quickQSPanel.dumpableTag).thenReturn("")
         whenever(quickQSPanel.resources).thenReturn(mContext.resources)
-        whenever(qsTileHost.createTileView(any(), any(), anyBoolean())).thenReturn(tileView)
+        whenever(qsHost.createTileView(any(), any(), anyBoolean())).thenReturn(tileView)
 
         controller =
             TestQuickQSPanelController(
                 quickQSPanel,
-                qsTileHost,
+                qsHost,
                 qsCustomizerController,
                 /* usingMediaPlayer = */ false,
                 mediaHost,
@@ -102,7 +102,7 @@
     fun testTileSublistWithFewerTiles_noCrash() {
         whenever(quickQSPanel.numQuickTiles).thenReturn(3)
 
-        whenever(qsTileHost.tiles).thenReturn(listOf(tile, tile))
+        whenever(qsHost.tiles).thenReturn(listOf(tile, tile))
 
         controller.setTiles()
     }
@@ -111,7 +111,7 @@
     fun testTileSublistWithTooManyTiles() {
         val limit = 3
         whenever(quickQSPanel.numQuickTiles).thenReturn(limit)
-        whenever(qsTileHost.tiles).thenReturn(listOf(tile, tile, tile, tile))
+        whenever(qsHost.tiles).thenReturn(listOf(tile, tile, tile, tile))
 
         controller.setTiles()
 
@@ -147,7 +147,7 @@
 
     class TestQuickQSPanelController(
         view: QuickQSPanel,
-        qsTileHost: QSTileHost,
+        qsHost: QSHost,
         qsCustomizerController: QSCustomizerController,
         usingMediaPlayer: Boolean,
         mediaHost: MediaHost,
@@ -159,7 +159,7 @@
     ) :
         QuickQSPanelController(
             view,
-            qsTileHost,
+            qsHost,
             qsCustomizerController,
             usingMediaPlayer,
             mediaHost,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
index 39d89bf..555484c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
@@ -18,37 +18,16 @@
 
 import android.content.Context
 import android.testing.AndroidTestingRunner
-import android.view.View
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.battery.BatteryMeterViewController
-import com.android.systemui.colorextraction.SysuiColorExtractor
-import com.android.systemui.demomode.DemoModeController
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.qs.carrier.QSCarrierGroup
-import com.android.systemui.qs.carrier.QSCarrierGroupController
-import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
-import com.android.systemui.statusbar.phone.StatusBarIconController
-import com.android.systemui.statusbar.phone.StatusIconContainer
-import com.android.systemui.statusbar.policy.Clock
-import com.android.systemui.statusbar.policy.VariableDateView
-import com.android.systemui.statusbar.policy.VariableDateViewController
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.argumentCaptor
-import com.android.systemui.util.mockito.capture
-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.Answers
-import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
-import org.mockito.Mockito.anyBoolean
-import org.mockito.Mockito.reset
-import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
 @SmallTest
@@ -58,78 +37,21 @@
     @Mock
     private lateinit var view: QuickStatusBarHeader
     @Mock
-    private lateinit var privacyIconsController: HeaderPrivacyIconsController
-    @Mock
-    private lateinit var statusBarIconController: StatusBarIconController
-    @Mock
-    private lateinit var demoModeController: DemoModeController
-    @Mock
     private lateinit var quickQSPanelController: QuickQSPanelController
-    @Mock(answer = Answers.RETURNS_SELF)
-    private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder
-    @Mock
-    private lateinit var qsCarrierGroupController: QSCarrierGroupController
-    @Mock
-    private lateinit var colorExtractor: SysuiColorExtractor
-    @Mock
-    private lateinit var iconContainer: StatusIconContainer
-    @Mock
-    private lateinit var qsCarrierGroup: QSCarrierGroup
-    @Mock
-    private lateinit var variableDateViewControllerFactory: VariableDateViewController.Factory
-    @Mock
-    private lateinit var variableDateViewController: VariableDateViewController
-    @Mock
-    private lateinit var batteryMeterViewController: BatteryMeterViewController
-    @Mock
-    private lateinit var clock: Clock
-    @Mock
-    private lateinit var variableDateView: VariableDateView
-    @Mock
-    private lateinit var mockView: View
+
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private lateinit var context: Context
-    @Mock
-    private lateinit var featureFlags: FeatureFlags
-    @Mock
-    private lateinit var insetsProvider: StatusBarContentInsetsProvider
-    @Mock
-    private lateinit var iconManagerFactory: StatusBarIconController.TintedIconManager.Factory
-    @Mock
-    private lateinit var iconManager: StatusBarIconController.TintedIconManager
-
-    private val qsExpansionPathInterpolator = QSExpansionPathInterpolator()
 
     private lateinit var controller: QuickStatusBarHeaderController
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-        stubViews()
-        `when`(iconContainer.context).thenReturn(context)
-        `when`(qsCarrierGroupControllerBuilder.build()).thenReturn(qsCarrierGroupController)
-        `when`(variableDateViewControllerFactory.create(any()))
-                .thenReturn(variableDateViewController)
-        `when`(iconManagerFactory.create(any(), any())).thenReturn(iconManager)
         `when`(view.resources).thenReturn(mContext.resources)
         `when`(view.isAttachedToWindow).thenReturn(true)
         `when`(view.context).thenReturn(context)
 
-        controller = QuickStatusBarHeaderController(
-                view,
-                privacyIconsController,
-                statusBarIconController,
-                demoModeController,
-                quickQSPanelController,
-                qsCarrierGroupControllerBuilder,
-                colorExtractor,
-                qsExpansionPathInterpolator,
-                featureFlags,
-                variableDateViewControllerFactory,
-                batteryMeterViewController,
-                insetsProvider,
-                iconManagerFactory,
-        )
+        controller = QuickStatusBarHeaderController(view, quickQSPanelController)
     }
 
     @After
@@ -138,74 +60,11 @@
     }
 
     @Test
-    fun testClockNotClickable() {
-        assertThat(clock.isClickable).isFalse()
-    }
+    fun testListeningStatus() {
+        controller.setListening(true)
+        verify(quickQSPanelController).setListening(true)
 
-    @Test
-    fun testSingleCarrierListenerAttachedOnInit() {
-        controller.init()
-
-        verify(qsCarrierGroupController).setOnSingleCarrierChangedListener(any())
-    }
-
-    @Test
-    fun testSingleCarrierSetOnViewOnInit_false() {
-        `when`(qsCarrierGroupController.isSingleCarrier).thenReturn(false)
-        controller.init()
-
-        verify(view).setIsSingleCarrier(false)
-    }
-
-    @Test
-    fun testSingleCarrierSetOnViewOnInit_true() {
-        `when`(qsCarrierGroupController.isSingleCarrier).thenReturn(true)
-        controller.init()
-
-        verify(view).setIsSingleCarrier(true)
-    }
-
-    @Test
-    fun testRSSISlot_notCombined() {
-        controller.init()
-
-        val captor = argumentCaptor<List<String>>()
-        verify(view).onAttach(any(), any(), capture(captor), any(), anyBoolean())
-
-        assertThat(captor.value).containsExactly(
-            mContext.getString(com.android.internal.R.string.status_bar_mobile)
-        )
-    }
-
-    @Test
-    fun testSingleCarrierCallback() {
-        controller.init()
-        reset(view)
-
-        val captor = argumentCaptor<QSCarrierGroupController.OnSingleCarrierChangedListener>()
-        verify(qsCarrierGroupController).setOnSingleCarrierChangedListener(capture(captor))
-
-        captor.value.onSingleCarrierChanged(true)
-        verify(view).setIsSingleCarrier(true)
-
-        captor.value.onSingleCarrierChanged(false)
-        verify(view).setIsSingleCarrier(false)
-    }
-
-    @Test
-    fun testAlarmIconIgnored() {
-        controller.init()
-
-        verify(iconContainer).addIgnoredSlot(
-                mContext.getString(com.android.internal.R.string.status_bar_alarm_clock))
-    }
-
-    private fun stubViews() {
-        `when`(view.findViewById<View>(anyInt())).thenReturn(mockView)
-        `when`(view.findViewById<QSCarrierGroup>(R.id.carrier_group)).thenReturn(qsCarrierGroup)
-        `when`(view.findViewById<StatusIconContainer>(R.id.statusIcons)).thenReturn(iconContainer)
-        `when`(view.findViewById<Clock>(R.id.clock)).thenReturn(clock)
-        `when`(view.requireViewById<VariableDateView>(R.id.date)).thenReturn(variableDateView)
-        `when`(view.requireViewById<VariableDateView>(R.id.date_clock)).thenReturn(variableDateView)
+        controller.setListening(false)
+        verify(quickQSPanelController).setListening(false)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
index d42cbe3..c041cb6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileAdapterTest.java
@@ -25,7 +25,7 @@
 
 import com.android.internal.logging.testing.UiEventLoggerFake;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -42,19 +42,19 @@
 
     private TileAdapter mTileAdapter;
     @Mock
-    private QSTileHost mQSTileHost;
+    private QSHost mQSHost;
 
     @Before
     public void setup() throws Exception {
         MockitoAnnotations.initMocks(this);
 
         TestableLooper.get(this).runWithLooper(() -> mTileAdapter =
-                new TileAdapter(mContext, mQSTileHost, new UiEventLoggerFake()));
+                new TileAdapter(mContext, mQSHost, new UiEventLoggerFake()));
     }
 
     @Test
     public void testResetNotifiesHost() {
         mTileAdapter.resetTileSpecs(Collections.emptyList());
-        verify(mQSTileHost).changeTilesByUser(any(), any());
+        verify(mQSHost).changeTilesByUser(any(), any());
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
index 040af70..78a0258 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
@@ -55,7 +55,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.qs.QSIconView;
 import com.android.systemui.plugins.qs.QSTile;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
@@ -102,7 +102,7 @@
     @Mock
     private TileQueryHelper.TileStateListener mListener;
     @Mock
-    private QSTileHost mQSTileHost;
+    private QSHost mQSHost;
     @Mock
     private PackageManager mPackageManager;
     @Mock
@@ -131,7 +131,7 @@
                         return null;
                     }
                 }
-        ).when(mQSTileHost).createTile(anyString());
+        ).when(mQSHost).createTile(anyString());
         FakeSystemClock clock = new FakeSystemClock();
         mMainExecutor = new FakeExecutor(clock);
         mBgExecutor = new FakeExecutor(clock);
@@ -147,7 +147,7 @@
 
     @Test
     public void testIsFinished_trueAfterQuerying() {
-        mTileQueryHelper.queryTiles(mQSTileHost);
+        mTileQueryHelper.queryTiles(mQSHost);
 
         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
 
@@ -156,7 +156,7 @@
 
     @Test
     public void testQueryTiles_callsListenerTwice() {
-        mTileQueryHelper.queryTiles(mQSTileHost);
+        mTileQueryHelper.queryTiles(mQSHost);
 
         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
 
@@ -170,7 +170,7 @@
             return null;
         }).when(mListener).onTilesChanged(any());
 
-        mTileQueryHelper.queryTiles(mQSTileHost);
+        mTileQueryHelper.queryTiles(mQSHost);
 
         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
 
@@ -184,7 +184,7 @@
         mContext.getOrCreateTestableResources().addOverride(R.string.quick_settings_tiles_stock,
                 STOCK_TILES);
 
-        mTileQueryHelper.queryTiles(mQSTileHost);
+        mTileQueryHelper.queryTiles(mQSHost);
 
         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
 
@@ -204,7 +204,7 @@
         mContext.getOrCreateTestableResources().addOverride(R.string.quick_settings_tiles_stock,
                 STOCK_TILES);
 
-        mTileQueryHelper.queryTiles(mQSTileHost);
+        mTileQueryHelper.queryTiles(mQSHost);
 
         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
 
@@ -224,7 +224,7 @@
         mContext.getOrCreateTestableResources().addOverride(R.string.quick_settings_tiles_stock,
                 STOCK_TILES);
 
-        mTileQueryHelper.queryTiles(mQSTileHost);
+        mTileQueryHelper.queryTiles(mQSHost);
 
         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
 
@@ -240,9 +240,9 @@
     public void testCustomTileNotCreated() {
         Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.QS_TILES,
                 CUSTOM_TILE);
-        mTileQueryHelper.queryTiles(mQSTileHost);
+        mTileQueryHelper.queryTiles(mQSHost);
         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
-        verify(mQSTileHost, never()).createTile(CUSTOM_TILE);
+        verify(mQSHost, never()).createTile(CUSTOM_TILE);
     }
 
     @Test
@@ -264,7 +264,7 @@
         mContext.getOrCreateTestableResources().addOverride(R.string.quick_settings_tiles_stock,
                 "");
 
-        mTileQueryHelper.queryTiles(mQSTileHost);
+        mTileQueryHelper.queryTiles(mQSHost);
         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
 
         verify(mListener, atLeastOnce()).onTilesChanged(mCaptor.capture());
@@ -278,7 +278,7 @@
         Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.QS_TILES, null);
         mContext.getOrCreateTestableResources().addOverride(R.string.quick_settings_tiles_stock,
                 STOCK_TILES);
-        mTileQueryHelper.queryTiles(mQSTileHost);
+        mTileQueryHelper.queryTiles(mQSHost);
     }
 
     @Test
@@ -286,12 +286,12 @@
         Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.QS_TILES, null);
 
         QSTile t = mock(QSTile.class);
-        when(mQSTileHost.createTile("hotspot")).thenReturn(t);
+        when(mQSHost.createTile("hotspot")).thenReturn(t);
 
         mContext.getOrCreateTestableResources().addOverride(R.string.quick_settings_tiles_stock,
                 "hotspot");
 
-        mTileQueryHelper.queryTiles(mQSTileHost);
+        mTileQueryHelper.queryTiles(mQSHost);
 
         FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
         InOrder verifier = inOrder(t);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java
index 8aa625a..46af89e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java
@@ -39,7 +39,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.settings.UserTracker;
 
 import org.junit.After;
@@ -61,7 +61,7 @@
     @Mock
     private UserTracker mUserTracker;
     @Mock
-    private QSTileHost mQSTileHost;
+    private QSHost mQSHost;
     @Mock
     private Context mMockContext;
 
@@ -80,7 +80,7 @@
         when(mUserTracker.getUserHandle()).thenReturn(UserHandle.SYSTEM);
 
         when(mTileServices.getContext()).thenReturn(mMockContext);
-        when(mTileServices.getHost()).thenReturn(mQSTileHost);
+        when(mTileServices.getHost()).thenReturn(mQSHost);
         when(mTileLifecycle.getUserId()).thenAnswer(invocation -> mUserTracker.getUserId());
         when(mTileLifecycle.isActiveTile()).thenReturn(false);
 
@@ -98,28 +98,28 @@
 
     @Test
     public void testSetTileAddedIfNotAdded() {
-        when(mQSTileHost.isTileAdded(eq(mComponentName), anyInt())).thenReturn(false);
+        when(mQSHost.isTileAdded(eq(mComponentName), anyInt())).thenReturn(false);
         mTileServiceManager.startLifecycleManagerAndAddTile();
 
-        verify(mQSTileHost).setTileAdded(mComponentName, mUserTracker.getUserId(), true);
+        verify(mQSHost).setTileAdded(mComponentName, mUserTracker.getUserId(), true);
     }
 
     @Test
     public void testNotSetTileAddedIfAdded() {
-        when(mQSTileHost.isTileAdded(eq(mComponentName), anyInt())).thenReturn(true);
+        when(mQSHost.isTileAdded(eq(mComponentName), anyInt())).thenReturn(true);
         mTileServiceManager.startLifecycleManagerAndAddTile();
 
-        verify(mQSTileHost, never()).setTileAdded(eq(mComponentName), anyInt(), eq(true));
+        verify(mQSHost, never()).setTileAdded(eq(mComponentName), anyInt(), eq(true));
     }
 
     @Test
     public void testSetTileAddedCorrectUser() {
         int user = 10;
         when(mUserTracker.getUserId()).thenReturn(user);
-        when(mQSTileHost.isTileAdded(eq(mComponentName), anyInt())).thenReturn(false);
+        when(mQSHost.isTileAdded(eq(mComponentName), anyInt())).thenReturn(false);
         mTileServiceManager.startLifecycleManagerAndAddTile();
 
-        verify(mQSTileHost).setTileAdded(mComponentName, user, true);
+        verify(mQSHost).setTileAdded(mComponentName, user, true);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceRequestControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceRequestControllerTest.kt
index bdfbca4..ccfb5cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceRequestControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceRequestControllerTest.kt
@@ -27,27 +27,27 @@
 import com.android.internal.statusbar.IAddTileResultCallback
 import com.android.systemui.InstanceIdSequenceFake
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.qs.QSTileHost
+import com.android.systemui.qs.QSHost
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.commandline.CommandRegistry
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.eq
 import com.google.common.truth.Truth.assertThat
+import java.util.function.Consumer
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
 import org.mockito.Mock
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.anyBoolean
 import org.mockito.Mockito.anyInt
 import org.mockito.Mockito.anyString
 import org.mockito.Mockito.atLeastOnce
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
-import java.util.function.Consumer
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -62,7 +62,7 @@
     @Mock
     private lateinit var tileRequestDialog: TileRequestDialog
     @Mock
-    private lateinit var qsTileHost: QSTileHost
+    private lateinit var qsHost: QSHost
     @Mock
     private lateinit var commandRegistry: CommandRegistry
     @Mock
@@ -82,10 +82,10 @@
         `when`(logger.newInstanceId()).thenReturn(instanceIdSequence.newInstanceId())
 
         // Tile not present by default
-        `when`(qsTileHost.indexOf(anyString())).thenReturn(-1)
+        `when`(qsHost.indexOf(anyString())).thenReturn(-1)
 
         controller = TileServiceRequestController(
-                qsTileHost,
+                qsHost,
                 commandQueue,
                 commandRegistry,
                 logger
@@ -107,18 +107,18 @@
 
     @Test
     fun tileAlreadyAdded_correctResult() {
-        `when`(qsTileHost.indexOf(CustomTile.toSpec(TEST_COMPONENT))).thenReturn(2)
+        `when`(qsHost.indexOf(CustomTile.toSpec(TEST_COMPONENT))).thenReturn(2)
 
         val callback = Callback()
         controller.requestTileAdd(TEST_COMPONENT, TEST_APP_NAME, TEST_LABEL, icon, callback)
 
         assertThat(callback.lastAccepted).isEqualTo(TileServiceRequestController.TILE_ALREADY_ADDED)
-        verify(qsTileHost, never()).addTile(any(ComponentName::class.java), anyBoolean())
+        verify(qsHost, never()).addTile(any(ComponentName::class.java), anyBoolean())
     }
 
     @Test
     fun tileAlreadyAdded_logged() {
-        `when`(qsTileHost.indexOf(CustomTile.toSpec(TEST_COMPONENT))).thenReturn(2)
+        `when`(qsHost.indexOf(CustomTile.toSpec(TEST_COMPONENT))).thenReturn(2)
 
         controller.requestTileAdd(TEST_COMPONENT, TEST_APP_NAME, TEST_LABEL, icon) {}
 
@@ -157,7 +157,7 @@
 
         cancelListenerCaptor.value.onCancel(tileRequestDialog)
         assertThat(callback.lastAccepted).isEqualTo(TileServiceRequestController.DISMISSED)
-        verify(qsTileHost, never()).addTile(any(ComponentName::class.java), anyBoolean())
+        verify(qsHost, never()).addTile(any(ComponentName::class.java), anyBoolean())
     }
 
     @Test
@@ -191,7 +191,7 @@
         clickListenerCaptor.value.onClick(tileRequestDialog, DialogInterface.BUTTON_POSITIVE)
 
         assertThat(callback.lastAccepted).isEqualTo(TileServiceRequestController.ADD_TILE)
-        verify(qsTileHost).addTile(TEST_COMPONENT, /* end */ true)
+        verify(qsHost).addTile(TEST_COMPONENT, /* end */ true)
     }
 
     @Test
@@ -225,7 +225,7 @@
         clickListenerCaptor.value.onClick(tileRequestDialog, DialogInterface.BUTTON_NEGATIVE)
 
         assertThat(callback.lastAccepted).isEqualTo(TileServiceRequestController.DONT_ADD_TILE)
-        verify(qsTileHost, never()).addTile(any(ComponentName::class.java), anyBoolean())
+        verify(qsHost, never()).addTile(any(ComponentName::class.java), anyBoolean())
     }
 
     @Test
@@ -266,7 +266,7 @@
 
     @Test
     fun commandQueueCallback_callbackCalled() {
-        `when`(qsTileHost.indexOf(CustomTile.toSpec(TEST_COMPONENT))).thenReturn(2)
+        `when`(qsHost.indexOf(CustomTile.toSpec(TEST_COMPONENT))).thenReturn(2)
         val captor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java)
         verify(commandQueue, atLeastOnce()).addCallback(capture(captor))
         val c = Callback()
@@ -365,4 +365,4 @@
             accept(r)
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
index 172c87f..64e9a3e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
@@ -30,7 +30,6 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.os.Handler;
-import android.os.HandlerExecutor;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.service.quicksettings.IQSTileService;
@@ -39,24 +38,13 @@
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 
-import com.android.internal.logging.UiEventLogger;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.plugins.PluginManager;
-import com.android.systemui.qs.QSTileHost;
-import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.qs.tileimpl.QSFactoryImpl;
-import com.android.systemui.settings.UserFileManager;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.AutoTileManager;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
-import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.tuner.TunerService;
-import com.android.systemui.util.settings.SecureSettings;
 
 import org.junit.After;
 import org.junit.Assert;
@@ -68,8 +56,6 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
-import java.util.Optional;
-import java.util.concurrent.Executor;
 
 import javax.inject.Provider;
 
@@ -92,26 +78,8 @@
     @Mock
     private StatusBarIconController mStatusBarIconController;
     @Mock
-    private QSFactoryImpl mQSFactory;
-    @Mock
-    private PluginManager mPluginManager;
-    @Mock
-    private  TunerService mTunerService;
-    @Mock
-    private AutoTileManager mAutoTileManager;
-    @Mock
-    private DumpManager mDumpManager;
-    @Mock
-    private CentralSurfaces mCentralSurfaces;
-    @Mock
-    private QSLogger mQSLogger;
-    @Mock
-    private UiEventLogger mUiEventLogger;
-    @Mock
     private UserTracker mUserTracker;
     @Mock
-    private SecureSettings  mSecureSettings;
-    @Mock
     private TileServiceRequestController.Builder mTileServiceRequestControllerBuilder;
     @Mock
     private TileServiceRequestController mTileServiceRequestController;
@@ -122,12 +90,11 @@
     @Mock
     private TileLifecycleManager mTileLifecycleManager;
     @Mock
-    private UserFileManager mUserFileManager;
+    private QSHost mQSHost;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mDependency.injectMockDependency(BluetoothController.class);
         mManagers = new ArrayList<>();
         mTestableLooper = TestableLooper.get(this);
 
@@ -135,34 +102,16 @@
                 .thenReturn(mTileServiceRequestController);
         when(mTileLifecycleManagerFactory.create(any(Intent.class), any(UserHandle.class)))
                 .thenReturn(mTileLifecycleManager);
+        when(mQSHost.getContext()).thenReturn(mContext);
 
         Provider<Handler> provider = () -> new Handler(mTestableLooper.getLooper());
-        Executor executor = new HandlerExecutor(provider.get());
 
-        QSTileHost host = new QSTileHost(mContext,
-                mStatusBarIconController,
-                mQSFactory,
-                executor,
-                mPluginManager,
-                mTunerService,
-                () -> mAutoTileManager,
-                mDumpManager,
-                Optional.of(mCentralSurfaces),
-                mQSLogger,
-                mUiEventLogger,
-                mUserTracker,
-                mSecureSettings,
-                mock(CustomTileStatePersister.class),
-                mTileServiceRequestControllerBuilder,
-                mTileLifecycleManagerFactory,
-                mUserFileManager);
-        mTileService = new TestTileServices(host, provider, mBroadcastDispatcher,
-                mUserTracker, mKeyguardStateController, mCommandQueue);
+        mTileService = new TestTileServices(mQSHost, provider, mBroadcastDispatcher,
+                mUserTracker, mKeyguardStateController, mCommandQueue, mStatusBarIconController);
     }
 
     @After
     public void tearDown() throws Exception {
-        mTileService.getHost().destroy();
         mTileService.destroy();
         TestableLooper.get(this).processAllMessages();
     }
@@ -274,11 +223,12 @@
     }
 
     private class TestTileServices extends TileServices {
-        TestTileServices(QSTileHost host, Provider<Handler> handlerProvider,
+        TestTileServices(QSHost host, Provider<Handler> handlerProvider,
                 BroadcastDispatcher broadcastDispatcher, UserTracker userTracker,
-                KeyguardStateController keyguardStateController, CommandQueue commandQueue) {
+                KeyguardStateController keyguardStateController, CommandQueue commandQueue,
+                StatusBarIconController statusBarIconController) {
             super(host, handlerProvider, broadcastDispatcher, userTracker, keyguardStateController,
-                    commandQueue);
+                    commandQueue, statusBarIconController);
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
index ba49f3f..36549fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
@@ -69,7 +69,6 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.qs.QSEvent;
 import com.android.systemui.qs.QSHost;
-import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.statusbar.StatusBarState;
 
@@ -97,7 +96,7 @@
     private TestableLooper mTestableLooper;
     private TileImpl mTile;
     @Mock
-    private QSTileHost mHost;
+    private QSHost mHost;
     @Mock
     private MetricsLogger mMetricsLogger;
     private final FalsingManagerFake mFalsingManager = new FalsingManagerFake();
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 d65901777..bf172f1 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
@@ -17,7 +17,7 @@
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.qs.QSTileHost
+import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.statusbar.policy.BluetoothController
@@ -40,7 +40,7 @@
     @Mock
     private lateinit var qsLogger: QSLogger
     @Mock
-    private lateinit var qsHost: QSTileHost
+    private lateinit var qsHost: QSHost
     @Mock
     private lateinit var metricsLogger: MetricsLogger
     private val falsingManager = FalsingManagerFake()
@@ -135,7 +135,7 @@
     }
 
     private class FakeBluetoothTile(
-        qsTileHost: QSTileHost,
+        qsHost: QSHost,
         backgroundLooper: Looper,
         mainHandler: Handler,
         falsingManager: FalsingManager,
@@ -145,7 +145,7 @@
         qsLogger: QSLogger,
         bluetoothController: BluetoothController
     ) : BluetoothTile(
-        qsTileHost,
+        qsHost,
         backgroundLooper,
         mainHandler,
         falsingManager,
@@ -187,4 +187,4 @@
         `when`(bluetoothController.isBluetoothConnected).thenReturn(false)
         `when`(bluetoothController.isBluetoothConnecting).thenReturn(true)
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
index b40a20c..18f891c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
@@ -42,7 +42,7 @@
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.statusbar.connectivity.IconState;
 import com.android.systemui.statusbar.connectivity.NetworkController;
@@ -78,7 +78,7 @@
     @Mock
     private NetworkController mNetworkController;
     @Mock
-    private QSTileHost mHost;
+    private QSHost mHost;
     @Mock
     SignalCallback mSignalCallback;
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorCorrectionTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorCorrectionTileTest.java
index debe41c..fdb63ca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorCorrectionTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorCorrectionTileTest.java
@@ -37,7 +37,7 @@
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.util.settings.FakeSettings;
@@ -56,7 +56,7 @@
 public class ColorCorrectionTileTest extends SysuiTestCase {
 
     @Mock
-    private QSTileHost mHost;
+    private QSHost mHost;
     @Mock
     private MetricsLogger mMetricsLogger;
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java
index 3fd2501..60c1a33 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java
@@ -39,7 +39,7 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.settings.UserTracker;
@@ -61,7 +61,7 @@
     private static final Integer COLOR_INVERSION_ENABLED = 1;
 
     @Mock
-    private QSTileHost mHost;
+    private QSHost mHost;
     @Mock
     private MetricsLogger mMetricsLogger;
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
index a13bece..2782c67 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
@@ -47,7 +47,7 @@
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.settings.UserTracker;
@@ -69,7 +69,7 @@
     @Mock
     private ActivityStarter mActivityStarter;
     @Mock
-    private QSTileHost mHost;
+    private QSHost mHost;
     @Mock
     private MetricsLogger mMetricsLogger;
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt
index d0f851b..c7aba1a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt
@@ -13,7 +13,7 @@
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.qs.QSTileHost
+import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.statusbar.policy.FlashlightController
@@ -34,7 +34,7 @@
 
     @Mock private lateinit var qsLogger: QSLogger
 
-    @Mock private lateinit var qsHost: QSTileHost
+    @Mock private lateinit var qsHost: QSHost
 
     @Mock private lateinit var metricsLogger: MetricsLogger
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/FontScalingTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FontScalingTileTest.kt
similarity index 68%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/FontScalingTileTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FontScalingTileTest.kt
index 57abae0..257d42a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/FontScalingTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FontScalingTileTest.kt
@@ -13,27 +13,35 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.qs.tiles.dialog
+package com.android.systemui.qs.tiles
 
 import android.os.Handler
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.UiEventLogger
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSTileHost
 import com.android.systemui.qs.logging.QSLogger
-import com.android.systemui.qs.tiles.FontScalingTile
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.nullable
 import com.android.systemui.util.settings.FakeSettings
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
+import org.mockito.Mockito.anyBoolean
+import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
@@ -47,15 +55,20 @@
     @Mock private lateinit var activityStarter: ActivityStarter
     @Mock private lateinit var qsLogger: QSLogger
     @Mock private lateinit var dialogLaunchAnimator: DialogLaunchAnimator
+    @Mock private lateinit var uiEventLogger: UiEventLogger
 
     private lateinit var testableLooper: TestableLooper
     private lateinit var fontScalingTile: FontScalingTile
 
+    val featureFlags = FakeFeatureFlags()
+
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
         testableLooper = TestableLooper.get(this)
         `when`(qsHost.getContext()).thenReturn(mContext)
+        `when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
+
         fontScalingTile =
             FontScalingTile(
                 qsHost,
@@ -67,15 +80,37 @@
                 activityStarter,
                 qsLogger,
                 dialogLaunchAnimator,
-                FakeSettings()
+                FakeSettings(),
+                featureFlags
             )
         fontScalingTile.initialize()
+        testableLooper.processAllMessages()
     }
 
     @Test
-    fun isNotAvailable_whenNotSupportedDevice_returnsFalse() {
+    fun isAvailable_whenFlagIsFalse_returnsFalse() {
+        featureFlags.set(Flags.ENABLE_FONT_SCALING_TILE, false)
+
         val isAvailable = fontScalingTile.isAvailable()
 
         assertThat(isAvailable).isFalse()
     }
+
+    @Test
+    fun isAvailable_whenFlagIsTrue_returnsTrue() {
+        featureFlags.set(Flags.ENABLE_FONT_SCALING_TILE, true)
+
+        val isAvailable = fontScalingTile.isAvailable()
+
+        assertThat(isAvailable).isTrue()
+    }
+
+    @Test
+    fun clickTile_showDialog() {
+        val view = View(context)
+        fontScalingTile.click(view)
+        testableLooper.processAllMessages()
+
+        verify(dialogLaunchAnimator).showFromView(any(), eq(view), nullable(), anyBoolean())
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java
index 451e911..4a2ac96 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java
@@ -37,7 +37,7 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.policy.DataSaverController;
@@ -60,7 +60,7 @@
     @Rule
     public MockitoRule mRule = MockitoJUnit.rule();
     @Mock
-    private QSTileHost mHost;
+    private QSHost mHost;
     @Mock
     private HotspotController mHotspotController;
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java
index addca9d..abd9094 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileTest.java
@@ -21,7 +21,6 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-
 import android.os.Handler;
 import android.service.quicksettings.Tile;
 import android.testing.AndroidTestingRunner;
@@ -35,7 +34,7 @@
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.qs.tiles.dialog.InternetDialogFactory;
@@ -56,7 +55,7 @@
 public class InternetTileTest extends SysuiTestCase {
 
     @Mock
-    private QSTileHost mHost;
+    private QSHost mHost;
     @Mock
     private NetworkController mNetworkController;
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
index d2bbc8c..08d10fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
@@ -29,7 +29,7 @@
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.qs.QSTileHost
+import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -52,7 +52,7 @@
     @Mock
     private lateinit var qsLogger: QSLogger
     @Mock
-    private lateinit var qsHost: QSTileHost
+    private lateinit var qsHost: QSHost
     @Mock
     private lateinit var metricsLogger: MetricsLogger
     private val falsingManager = FalsingManagerFake()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java
index cfd3735..9638a45 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/NfcTileTest.java
@@ -36,7 +36,7 @@
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.logging.QSLogger;
 
 import org.junit.Before;
@@ -60,7 +60,7 @@
     @Mock
     private ActivityStarter mActivityStarter;
     @Mock
-    private QSTileHost mHost;
+    private QSHost mHost;
     @Mock
     private MetricsLogger mMetricsLogger;
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/OneHandedModeTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/OneHandedModeTileTest.java
index 8031875..3344a17 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/OneHandedModeTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/OneHandedModeTileTest.java
@@ -32,7 +32,7 @@
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.util.settings.SecureSettings;
@@ -53,7 +53,7 @@
     @Mock
     private ActivityStarter mActivityStarter;
     @Mock
-    private QSTileHost mHost;
+    private QSHost mHost;
     @Mock
     private MetricsLogger mMetricsLogger;
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java
index a1be2f3..24287ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QRCodeScannerTileTest.java
@@ -39,7 +39,7 @@
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.qrcodescanner.controller.QRCodeScannerController;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 
@@ -54,7 +54,7 @@
 @SmallTest
 public class QRCodeScannerTileTest extends SysuiTestCase {
     @Mock
-    private QSTileHost mHost;
+    private QSHost mHost;
     @Mock
     private MetricsLogger mMetricsLogger;
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
index 4f6475f..4722c8d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
@@ -66,7 +66,7 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -99,7 +99,7 @@
             .setComponent(new ComponentName(mContext.getPackageName(), "WalletActivity"));
 
     @Mock
-    private QSTileHost mHost;
+    private QSHost mHost;
     @Mock
     private MetricsLogger mMetricsLogger;
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
index 8601d6c..99e5564 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
@@ -38,13 +38,14 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.ReduceBrightColorsController;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.settings.UserTracker;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -53,9 +54,10 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
+@Ignore("b/269171747")
 public class ReduceBrightColorsTileTest extends SysuiTestCase {
     @Mock
-    private QSTileHost mHost;
+    private QSHost mHost;
     @Mock
     private MetricsLogger mMetricsLogger;
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
index e9dfd3e..c7eb2f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
@@ -38,7 +38,7 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -71,7 +71,7 @@
     @Mock
     private ActivityStarter mActivityStarter;
     @Mock
-    private QSTileHost mHost;
+    private QSHost mHost;
     @Mock
     private MetricsLogger mMetricsLogger;
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
index 30debdf..21acc08 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
@@ -43,7 +43,7 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.screenrecord.RecordingController;
@@ -65,7 +65,7 @@
     @Mock
     private RecordingController mController;
     @Mock
-    private QSTileHost mHost;
+    private QSHost mHost;
     @Mock
     private KeyguardDismissUtil mKeyguardDismissUtil;
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt
index 0c070da..3d9f650 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt
@@ -32,7 +32,7 @@
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.qs.QSTileHost
+import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.statusbar.policy.BatteryController
@@ -55,7 +55,7 @@
     @Mock private lateinit var uiModeManager: UiModeManager
     @Mock private lateinit var resources: Resources
     @Mock private lateinit var qsLogger: QSLogger
-    @Mock private lateinit var qsHost: QSTileHost
+    @Mock private lateinit var qsHost: QSHost
     @Mock private lateinit var metricsLogger: MetricsLogger
     @Mock private lateinit var statusBarStateController: StatusBarStateController
     @Mock private lateinit var activityStarter: ActivityStarter
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
deleted file mode 100644
index 91fef1d..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.shade
-
-import android.content.Context
-import android.content.res.Resources
-import android.content.res.XmlResourceParser
-import android.graphics.Rect
-import android.testing.AndroidTestingRunner
-import android.view.DisplayCutout
-import android.view.View
-import android.view.ViewPropertyAnimator
-import android.view.WindowInsets
-import android.widget.TextView
-import androidx.constraintlayout.motion.widget.MotionLayout
-import androidx.constraintlayout.widget.ConstraintSet
-import androidx.test.filters.SmallTest
-import com.android.systemui.R
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.animation.Interpolators
-import com.android.systemui.animation.ShadeInterpolation
-import com.android.systemui.battery.BatteryMeterView
-import com.android.systemui.battery.BatteryMeterViewController
-import com.android.systemui.demomode.DemoMode
-import com.android.systemui.demomode.DemoModeController
-import com.android.systemui.dump.DumpManager
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
-import com.android.systemui.qs.ChipVisibilityListener
-import com.android.systemui.qs.HeaderPrivacyIconsController
-import com.android.systemui.qs.carrier.QSCarrierGroup
-import com.android.systemui.qs.carrier.QSCarrierGroupController
-import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.HEADER_TRANSITION_ID
-import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.LARGE_SCREEN_HEADER_CONSTRAINT
-import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QQS_HEADER_CONSTRAINT
-import com.android.systemui.shade.LargeScreenShadeHeaderController.Companion.QS_HEADER_CONSTRAINT
-import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
-import com.android.systemui.statusbar.phone.StatusBarIconController
-import com.android.systemui.statusbar.phone.StatusIconContainer
-import com.android.systemui.statusbar.policy.Clock
-import com.android.systemui.statusbar.policy.FakeConfigurationController
-import com.android.systemui.statusbar.policy.VariableDateView
-import com.android.systemui.statusbar.policy.VariableDateViewController
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.argumentCaptor
-import com.android.systemui.util.mockito.capture
-import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.mock
-import com.google.common.truth.Truth.assertThat
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Answers
-import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers
-import org.mockito.Mock
-import org.mockito.Mockito
-import org.mockito.Mockito.anyBoolean
-import org.mockito.Mockito.anyFloat
-import org.mockito.Mockito.anyInt
-import org.mockito.Mockito.clearInvocations
-import org.mockito.Mockito.inOrder
-import org.mockito.Mockito.never
-import org.mockito.Mockito.reset
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
-import org.mockito.junit.MockitoJUnit
-
-private val EMPTY_CHANGES = ConstraintsChanges()
-
-/**
- * Tests for [LargeScreenShadeHeaderController] when [Flags.COMBINED_QS_HEADERS] is `true`.
- *
- * Once that flag is removed, this class will be combined with
- * [LargeScreenShadeHeaderControllerTest].
- */
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() {
-
-    @Mock
-    private lateinit var statusIcons: StatusIconContainer
-    @Mock
-    private lateinit var statusBarIconController: StatusBarIconController
-    @Mock
-    private lateinit var iconManagerFactory: StatusBarIconController.TintedIconManager.Factory
-    @Mock
-    private lateinit var iconManager: StatusBarIconController.TintedIconManager
-    @Mock
-    private lateinit var qsCarrierGroupController: QSCarrierGroupController
-    @Mock
-    private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder
-    @Mock
-    private lateinit var featureFlags: FeatureFlags
-    @Mock
-    private lateinit var clock: Clock
-    @Mock
-    private lateinit var date: VariableDateView
-    @Mock
-    private lateinit var carrierGroup: QSCarrierGroup
-    @Mock
-    private lateinit var batteryMeterView: BatteryMeterView
-    @Mock
-    private lateinit var batteryMeterViewController: BatteryMeterViewController
-    @Mock
-    private lateinit var privacyIconsController: HeaderPrivacyIconsController
-    @Mock
-    private lateinit var insetsProvider: StatusBarContentInsetsProvider
-    @Mock
-    private lateinit var variableDateViewControllerFactory: VariableDateViewController.Factory
-    @Mock
-    private lateinit var variableDateViewController: VariableDateViewController
-    @Mock
-    private lateinit var dumpManager: DumpManager
-    @Mock
-    private lateinit var combinedShadeHeadersConstraintManager:
-        CombinedShadeHeadersConstraintManager
-
-    @Mock
-    private lateinit var mockedContext: Context
-    @Mock(answer = Answers.RETURNS_MOCKS)
-    private lateinit var view: MotionLayout
-
-    @Mock
-    private lateinit var qqsConstraints: ConstraintSet
-    @Mock
-    private lateinit var qsConstraints: ConstraintSet
-    @Mock
-    private lateinit var largeScreenConstraints: ConstraintSet
-    @Mock private lateinit var demoModeController: DemoModeController
-
-    @JvmField @Rule
-    val mockitoRule = MockitoJUnit.rule()
-    var viewVisibility = View.GONE
-
-    private lateinit var controller: LargeScreenShadeHeaderController
-    private lateinit var carrierIconSlots: List<String>
-    private val configurationController = FakeConfigurationController()
-    private lateinit var demoModeControllerCapture: ArgumentCaptor<DemoMode>
-
-    @Before
-    fun setUp() {
-        demoModeControllerCapture = argumentCaptor<DemoMode>()
-        whenever<Clock>(view.findViewById(R.id.clock)).thenReturn(clock)
-        whenever(clock.context).thenReturn(mockedContext)
-
-        whenever<TextView>(view.findViewById(R.id.date)).thenReturn(date)
-        whenever(date.context).thenReturn(mockedContext)
-        whenever(variableDateViewControllerFactory.create(any()))
-            .thenReturn(variableDateViewController)
-
-        whenever<QSCarrierGroup>(view.findViewById(R.id.carrier_group)).thenReturn(carrierGroup)
-        whenever<BatteryMeterView>(view.findViewById(R.id.batteryRemainingIcon))
-            .thenReturn(batteryMeterView)
-
-        whenever<StatusIconContainer>(view.findViewById(R.id.statusIcons)).thenReturn(statusIcons)
-        whenever(statusIcons.context).thenReturn(context)
-
-        whenever(qsCarrierGroupControllerBuilder.setQSCarrierGroup(any()))
-            .thenReturn(qsCarrierGroupControllerBuilder)
-        whenever(qsCarrierGroupControllerBuilder.build()).thenReturn(qsCarrierGroupController)
-
-        whenever(view.context).thenReturn(context)
-        whenever(view.resources).thenReturn(context.resources)
-        whenever(view.setVisibility(ArgumentMatchers.anyInt())).then {
-            viewVisibility = it.arguments[0] as Int
-            null
-        }
-        whenever(view.visibility).thenAnswer { _ -> viewVisibility }
-        whenever(view.alpha).thenReturn(1f)
-
-        whenever(iconManagerFactory.create(any(), any())).thenReturn(iconManager)
-
-        whenever(featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)).thenReturn(true)
-
-        setUpDefaultInsets()
-        setUpMotionLayout(view)
-
-        controller = LargeScreenShadeHeaderController(
-            view,
-            statusBarIconController,
-            iconManagerFactory,
-            privacyIconsController,
-            insetsProvider,
-            configurationController,
-            variableDateViewControllerFactory,
-            batteryMeterViewController,
-            dumpManager,
-            featureFlags,
-            qsCarrierGroupControllerBuilder,
-            combinedShadeHeadersConstraintManager,
-            demoModeController
-        )
-        whenever(view.isAttachedToWindow).thenReturn(true)
-        controller.init()
-        carrierIconSlots = listOf(
-            context.getString(com.android.internal.R.string.status_bar_mobile))
-    }
-
-    @Test
-    fun testControllersCreatedAndInitialized() {
-        verify(variableDateViewController).init()
-
-        verify(batteryMeterViewController).init()
-        verify(batteryMeterViewController).ignoreTunerUpdates()
-        verify(batteryMeterView).setPercentShowMode(BatteryMeterView.MODE_ESTIMATE)
-
-        val inOrder = inOrder(qsCarrierGroupControllerBuilder)
-        inOrder.verify(qsCarrierGroupControllerBuilder).setQSCarrierGroup(carrierGroup)
-        inOrder.verify(qsCarrierGroupControllerBuilder).build()
-    }
-
-    @Test
-    fun testClockPivotLtr() {
-        val width = 200
-        whenever(clock.width).thenReturn(width)
-        whenever(clock.isLayoutRtl).thenReturn(false)
-
-        val captor = ArgumentCaptor.forClass(View.OnLayoutChangeListener::class.java)
-        verify(clock).addOnLayoutChangeListener(capture(captor))
-
-        captor.value.onLayoutChange(clock, 0, 1, 2, 3, 4, 5, 6, 7)
-        verify(clock).pivotX = 0f
-    }
-
-    @Test
-    fun testClockPivotRtl() {
-        val width = 200
-        whenever(clock.width).thenReturn(width)
-        whenever(clock.isLayoutRtl).thenReturn(true)
-
-        val captor = ArgumentCaptor.forClass(View.OnLayoutChangeListener::class.java)
-        verify(clock).addOnLayoutChangeListener(capture(captor))
-
-        captor.value.onLayoutChange(clock, 0, 1, 2, 3, 4, 5, 6, 7)
-        verify(clock).pivotX = width.toFloat()
-    }
-
-    @Test
-    fun testShadeExpanded_true() {
-        // When shade is expanded, view should be visible regardless of largeScreenActive
-        controller.largeScreenActive = false
-        controller.qsVisible = true
-        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
-
-        controller.largeScreenActive = true
-        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
-    }
-
-    @Test
-    fun testShadeExpanded_false() {
-        // When shade is not expanded, view should be invisible regardless of largeScreenActive
-        controller.largeScreenActive = false
-        controller.qsVisible = false
-        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
-
-        controller.largeScreenActive = true
-        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
-    }
-
-    @Test
-    fun testLargeScreenActive_false() {
-        controller.largeScreenActive = true // Make sure there's a change
-        clearInvocations(view)
-
-        controller.largeScreenActive = false
-
-        verify(view).setTransition(HEADER_TRANSITION_ID)
-    }
-
-    @Test
-    fun testShadeExpandedFraction() {
-        // View needs to be visible for this to actually take effect
-        controller.qsVisible = true
-
-        clearInvocations(view)
-        controller.shadeExpandedFraction = 0.3f
-        verify(view).alpha = ShadeInterpolation.getContentAlpha(0.3f)
-
-        clearInvocations(view)
-        controller.shadeExpandedFraction = 1f
-        verify(view).alpha = ShadeInterpolation.getContentAlpha(1f)
-
-        clearInvocations(view)
-        controller.shadeExpandedFraction = 0f
-        verify(view).alpha = ShadeInterpolation.getContentAlpha(0f)
-    }
-
-    @Test
-    fun testQsExpandedFraction_headerTransition() {
-        controller.qsVisible = true
-        controller.largeScreenActive = false
-
-        clearInvocations(view)
-        controller.qsExpandedFraction = 0.3f
-        verify(view).progress = 0.3f
-    }
-
-    @Test
-    fun testQsExpandedFraction_largeScreen() {
-        controller.qsVisible = true
-        controller.largeScreenActive = true
-
-        clearInvocations(view)
-        controller.qsExpandedFraction = 0.3f
-        verify(view, never()).progress = anyFloat()
-    }
-
-    @Test
-    fun testScrollY_headerTransition() {
-        controller.largeScreenActive = false
-
-        clearInvocations(view)
-        controller.qsScrollY = 20
-        verify(view).scrollY = 20
-    }
-
-    @Test
-    fun testScrollY_largeScreen() {
-        controller.largeScreenActive = true
-
-        clearInvocations(view)
-        controller.qsScrollY = 20
-        verify(view, never()).scrollY = anyInt()
-    }
-
-    @Test
-    fun testPrivacyChipVisibilityChanged_visible_changesCorrectConstraints() {
-        val chipVisibleChanges = createMockConstraintChanges()
-        val chipNotVisibleChanges = createMockConstraintChanges()
-
-        whenever(combinedShadeHeadersConstraintManager.privacyChipVisibilityConstraints(true))
-            .thenReturn(chipVisibleChanges)
-        whenever(combinedShadeHeadersConstraintManager.privacyChipVisibilityConstraints(false))
-            .thenReturn(chipNotVisibleChanges)
-
-        val captor = ArgumentCaptor.forClass(ChipVisibilityListener::class.java)
-        verify(privacyIconsController).chipVisibilityListener = capture(captor)
-
-        captor.value.onChipVisibilityRefreshed(true)
-
-        verify(chipVisibleChanges.qqsConstraintsChanges)!!.invoke(qqsConstraints)
-        verify(chipVisibleChanges.qsConstraintsChanges)!!.invoke(qsConstraints)
-        verify(chipVisibleChanges.largeScreenConstraintsChanges)!!.invoke(largeScreenConstraints)
-
-        verify(chipNotVisibleChanges.qqsConstraintsChanges, never())!!.invoke(any())
-        verify(chipNotVisibleChanges.qsConstraintsChanges, never())!!.invoke(any())
-        verify(chipNotVisibleChanges.largeScreenConstraintsChanges, never())!!.invoke(any())
-    }
-
-    @Test
-    fun testPrivacyChipVisibilityChanged_notVisible_changesCorrectConstraints() {
-        val chipVisibleChanges = createMockConstraintChanges()
-        val chipNotVisibleChanges = createMockConstraintChanges()
-
-        whenever(combinedShadeHeadersConstraintManager.privacyChipVisibilityConstraints(true))
-            .thenReturn(chipVisibleChanges)
-        whenever(combinedShadeHeadersConstraintManager.privacyChipVisibilityConstraints(false))
-            .thenReturn(chipNotVisibleChanges)
-
-        val captor = ArgumentCaptor.forClass(ChipVisibilityListener::class.java)
-        verify(privacyIconsController).chipVisibilityListener = capture(captor)
-
-        captor.value.onChipVisibilityRefreshed(false)
-
-        verify(chipVisibleChanges.qqsConstraintsChanges, never())!!.invoke(qqsConstraints)
-        verify(chipVisibleChanges.qsConstraintsChanges, never())!!.invoke(qsConstraints)
-        verify(chipVisibleChanges.largeScreenConstraintsChanges, never())!!
-            .invoke(largeScreenConstraints)
-
-        verify(chipNotVisibleChanges.qqsConstraintsChanges)!!.invoke(any())
-        verify(chipNotVisibleChanges.qsConstraintsChanges)!!.invoke(any())
-        verify(chipNotVisibleChanges.largeScreenConstraintsChanges)!!.invoke(any())
-    }
-
-    @Test
-    fun testInsetsGuides_ltr() {
-        whenever(view.isLayoutRtl).thenReturn(false)
-        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
-        verify(view).setOnApplyWindowInsetsListener(capture(captor))
-        val mockConstraintsChanges = createMockConstraintChanges()
-
-        val (insetLeft, insetRight) = 30 to 40
-        val (paddingStart, paddingEnd) = 10 to 20
-        whenever(view.paddingStart).thenReturn(paddingStart)
-        whenever(view.paddingEnd).thenReturn(paddingEnd)
-
-        mockInsetsProvider(insetLeft to insetRight, false)
-
-        whenever(combinedShadeHeadersConstraintManager
-            .edgesGuidelinesConstraints(anyInt(), anyInt(), anyInt(), anyInt())
-        ).thenReturn(mockConstraintsChanges)
-
-        captor.value.onApplyWindowInsets(view, createWindowInsets())
-
-        verify(combinedShadeHeadersConstraintManager)
-            .edgesGuidelinesConstraints(insetLeft, paddingStart, insetRight, paddingEnd)
-
-        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
-    }
-
-    @Test
-    fun testInsetsGuides_rtl() {
-        whenever(view.isLayoutRtl).thenReturn(true)
-        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
-        verify(view).setOnApplyWindowInsetsListener(capture(captor))
-        val mockConstraintsChanges = createMockConstraintChanges()
-
-        val (insetLeft, insetRight) = 30 to 40
-        val (paddingStart, paddingEnd) = 10 to 20
-        whenever(view.paddingStart).thenReturn(paddingStart)
-        whenever(view.paddingEnd).thenReturn(paddingEnd)
-
-        mockInsetsProvider(insetLeft to insetRight, false)
-
-        whenever(combinedShadeHeadersConstraintManager
-            .edgesGuidelinesConstraints(anyInt(), anyInt(), anyInt(), anyInt())
-        ).thenReturn(mockConstraintsChanges)
-
-        captor.value.onApplyWindowInsets(view, createWindowInsets())
-
-        verify(combinedShadeHeadersConstraintManager)
-            .edgesGuidelinesConstraints(insetRight, paddingStart, insetLeft, paddingEnd)
-
-        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
-    }
-
-    @Test
-    fun testNullCutout() {
-        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
-        verify(view).setOnApplyWindowInsetsListener(capture(captor))
-        val mockConstraintsChanges = createMockConstraintChanges()
-
-        whenever(combinedShadeHeadersConstraintManager.emptyCutoutConstraints())
-            .thenReturn(mockConstraintsChanges)
-
-        captor.value.onApplyWindowInsets(view, createWindowInsets(null))
-
-        verify(combinedShadeHeadersConstraintManager).emptyCutoutConstraints()
-        verify(combinedShadeHeadersConstraintManager, never())
-            .centerCutoutConstraints(anyBoolean(), anyInt())
-
-        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
-    }
-
-    @Test
-    fun testEmptyCutout() {
-        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
-        verify(view).setOnApplyWindowInsetsListener(capture(captor))
-        val mockConstraintsChanges = createMockConstraintChanges()
-
-        whenever(combinedShadeHeadersConstraintManager.emptyCutoutConstraints())
-            .thenReturn(mockConstraintsChanges)
-
-        captor.value.onApplyWindowInsets(view, createWindowInsets())
-
-        verify(combinedShadeHeadersConstraintManager).emptyCutoutConstraints()
-        verify(combinedShadeHeadersConstraintManager, never())
-            .centerCutoutConstraints(anyBoolean(), anyInt())
-
-        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
-    }
-
-    @Test
-    fun testCornerCutout_emptyRect() {
-        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
-        verify(view).setOnApplyWindowInsetsListener(capture(captor))
-        val mockConstraintsChanges = createMockConstraintChanges()
-
-        mockInsetsProvider(0 to 0, true)
-
-        whenever(combinedShadeHeadersConstraintManager.emptyCutoutConstraints())
-            .thenReturn(mockConstraintsChanges)
-
-        captor.value.onApplyWindowInsets(view, createWindowInsets())
-
-        verify(combinedShadeHeadersConstraintManager).emptyCutoutConstraints()
-        verify(combinedShadeHeadersConstraintManager, never())
-            .centerCutoutConstraints(anyBoolean(), anyInt())
-
-        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
-    }
-
-    @Test
-    fun testCornerCutout_nonEmptyRect() {
-        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
-        verify(view).setOnApplyWindowInsetsListener(capture(captor))
-        val mockConstraintsChanges = createMockConstraintChanges()
-
-        mockInsetsProvider(0 to 0, true)
-
-        whenever(combinedShadeHeadersConstraintManager.emptyCutoutConstraints())
-            .thenReturn(mockConstraintsChanges)
-
-        captor.value.onApplyWindowInsets(view, createWindowInsets(Rect(1, 2, 3, 4)))
-
-        verify(combinedShadeHeadersConstraintManager).emptyCutoutConstraints()
-        verify(combinedShadeHeadersConstraintManager, never())
-            .centerCutoutConstraints(anyBoolean(), anyInt())
-
-        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
-    }
-
-    @Test
-    fun testTopCutout_ltr() {
-        val width = 100
-        val paddingLeft = 10
-        val paddingRight = 20
-        val cutoutWidth = 30
-
-        whenever(view.isLayoutRtl).thenReturn(false)
-        whenever(view.width).thenReturn(width)
-        whenever(view.paddingLeft).thenReturn(paddingLeft)
-        whenever(view.paddingRight).thenReturn(paddingRight)
-
-        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
-        verify(view).setOnApplyWindowInsetsListener(capture(captor))
-        val mockConstraintsChanges = createMockConstraintChanges()
-
-        mockInsetsProvider(0 to 0, false)
-
-        whenever(combinedShadeHeadersConstraintManager
-            .centerCutoutConstraints(anyBoolean(), anyInt())
-        ).thenReturn(mockConstraintsChanges)
-
-        captor.value.onApplyWindowInsets(view, createWindowInsets(Rect(0, 0, cutoutWidth, 1)))
-
-        verify(combinedShadeHeadersConstraintManager, never()).emptyCutoutConstraints()
-        val offset = (width - paddingLeft - paddingRight - cutoutWidth) / 2
-        verify(combinedShadeHeadersConstraintManager).centerCutoutConstraints(false, offset)
-
-        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
-    }
-
-    @Test
-    fun testTopCutout_rtl() {
-        val width = 100
-        val paddingLeft = 10
-        val paddingRight = 20
-        val cutoutWidth = 30
-
-        whenever(view.isLayoutRtl).thenReturn(true)
-        whenever(view.width).thenReturn(width)
-        whenever(view.paddingLeft).thenReturn(paddingLeft)
-        whenever(view.paddingRight).thenReturn(paddingRight)
-
-        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
-        verify(view).setOnApplyWindowInsetsListener(capture(captor))
-        val mockConstraintsChanges = createMockConstraintChanges()
-
-        mockInsetsProvider(0 to 0, false)
-
-        whenever(combinedShadeHeadersConstraintManager
-            .centerCutoutConstraints(anyBoolean(), anyInt())
-        ).thenReturn(mockConstraintsChanges)
-
-        captor.value.onApplyWindowInsets(view, createWindowInsets(Rect(0, 0, cutoutWidth, 1)))
-
-        verify(combinedShadeHeadersConstraintManager, never()).emptyCutoutConstraints()
-        val offset = (width - paddingLeft - paddingRight - cutoutWidth) / 2
-        verify(combinedShadeHeadersConstraintManager).centerCutoutConstraints(true, offset)
-
-        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
-        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
-    }
-
-    @Test
-    fun alarmIconNotIgnored() {
-        verify(statusIcons, never()).addIgnoredSlot(
-                context.getString(com.android.internal.R.string.status_bar_alarm_clock)
-        )
-    }
-
-    @Test
-    fun demoMode_attachDemoMode() {
-        verify(demoModeController).addCallback(capture(demoModeControllerCapture))
-        demoModeControllerCapture.value.onDemoModeStarted()
-        verify(clock).onDemoModeStarted()
-    }
-
-    @Test
-    fun demoMode_detachDemoMode() {
-        controller.simulateViewDetached()
-        verify(demoModeController).removeCallback(capture(demoModeControllerCapture))
-        demoModeControllerCapture.value.onDemoModeFinished()
-        verify(clock).onDemoModeFinished()
-    }
-
-    @Test
-    fun animateOutOnStartCustomizing() {
-        val animator = Mockito.mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
-        val duration = 1000L
-        whenever(view.animate()).thenReturn(animator)
-
-        controller.startCustomizingAnimation(show = true, duration)
-
-        verify(animator).setDuration(duration)
-        verify(animator).alpha(0f)
-        verify(animator).setInterpolator(Interpolators.ALPHA_OUT)
-        verify(animator).start()
-    }
-
-    @Test
-    fun animateInOnEndCustomizing() {
-        val animator = Mockito.mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
-        val duration = 1000L
-        whenever(view.animate()).thenReturn(animator)
-
-        controller.startCustomizingAnimation(show = false, duration)
-
-        verify(animator).setDuration(duration)
-        verify(animator).alpha(1f)
-        verify(animator).setInterpolator(Interpolators.ALPHA_IN)
-        verify(animator).start()
-    }
-
-    @Test
-    fun privacyChipParentVisibleFromStart() {
-        verify(privacyIconsController).onParentVisible()
-    }
-
-    @Test
-    fun privacyChipParentVisibleAlways() {
-        controller.largeScreenActive = true
-        controller.largeScreenActive = false
-        controller.largeScreenActive = true
-
-        verify(privacyIconsController, never()).onParentInvisible()
-    }
-
-    @Test
-    fun clockPivotYInCenter() {
-        val captor = ArgumentCaptor.forClass(View.OnLayoutChangeListener::class.java)
-        verify(clock).addOnLayoutChangeListener(capture(captor))
-        var height = 100
-        val width = 50
-
-        clock.executeLayoutChange(0, 0, width, height, captor.value)
-        verify(clock).pivotY = height.toFloat() / 2
-
-        height = 150
-        clock.executeLayoutChange(0, 0, width, height, captor.value)
-        verify(clock).pivotY = height.toFloat() / 2
-    }
-
-    @Test
-    fun onDensityOrFontScaleChanged_reloadConstraints() {
-        // After density or font scale change, constraints need to be reloaded to reflect new
-        // dimensions.
-        reset(qqsConstraints)
-        reset(qsConstraints)
-        reset(largeScreenConstraints)
-
-        configurationController.notifyDensityOrFontScaleChanged()
-
-        val captor = ArgumentCaptor.forClass(XmlResourceParser::class.java)
-        verify(qqsConstraints).load(eq(context), capture(captor))
-        assertThat(captor.value.getResId()).isEqualTo(R.xml.qqs_header)
-        verify(qsConstraints).load(eq(context), capture(captor))
-        assertThat(captor.value.getResId()).isEqualTo(R.xml.qs_header)
-        verify(largeScreenConstraints).load(eq(context), capture(captor))
-        assertThat(captor.value.getResId()).isEqualTo(R.xml.large_screen_shade_header)
-    }
-
-    @Test
-    fun `carrier left padding is set when clock layout changes`() {
-        val width = 200
-        whenever(clock.width).thenReturn(width)
-        whenever(clock.scaleX).thenReturn(2.57f) // 2.57 comes from qs_header.xml
-        val captor = ArgumentCaptor.forClass(View.OnLayoutChangeListener::class.java)
-
-        verify(clock).addOnLayoutChangeListener(capture(captor))
-        captor.value.onLayoutChange(clock, 0, 0, width, 0, 0, 0, 0, 0)
-
-        verify(carrierGroup).setPaddingRelative(514, 0, 0, 0)
-    }
-
-    private fun View.executeLayoutChange(
-            left: Int,
-            top: Int,
-            right: Int,
-            bottom: Int,
-            listener: View.OnLayoutChangeListener
-    ) {
-        val oldLeft = this.left
-        val oldTop = this.top
-        val oldRight = this.right
-        val oldBottom = this.bottom
-        whenever(this.left).thenReturn(left)
-        whenever(this.top).thenReturn(top)
-        whenever(this.right).thenReturn(right)
-        whenever(this.bottom).thenReturn(bottom)
-        whenever(this.height).thenReturn(bottom - top)
-        whenever(this.width).thenReturn(right - left)
-        listener.onLayoutChange(
-                this,
-                oldLeft,
-                oldTop,
-                oldRight,
-                oldBottom,
-                left,
-                top,
-                right,
-                bottom
-        )
-    }
-
-    private fun createWindowInsets(
-        topCutout: Rect? = Rect()
-    ): WindowInsets {
-        val windowInsets: WindowInsets = mock()
-        val displayCutout: DisplayCutout = mock()
-        whenever(windowInsets.displayCutout)
-            .thenReturn(if (topCutout != null) displayCutout else null)
-        whenever(displayCutout.boundingRectTop).thenReturn(topCutout)
-
-        return windowInsets
-    }
-
-    private fun mockInsetsProvider(
-        insets: Pair<Int, Int> = 0 to 0,
-        cornerCutout: Boolean = false,
-    ) {
-        whenever(insetsProvider.getStatusBarContentInsetsForCurrentRotation())
-            .thenReturn(insets.toAndroidPair())
-        whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(cornerCutout)
-    }
-
-    private fun createMockConstraintChanges(): ConstraintsChanges {
-        return ConstraintsChanges(mock(), mock(), mock())
-    }
-
-    private fun XmlResourceParser.getResId(): Int {
-        return Resources.getAttributeSetSourceResId(this)
-    }
-
-    private fun setUpMotionLayout(motionLayout: MotionLayout) {
-        whenever(motionLayout.getConstraintSet(QQS_HEADER_CONSTRAINT)).thenReturn(qqsConstraints)
-        whenever(motionLayout.getConstraintSet(QS_HEADER_CONSTRAINT)).thenReturn(qsConstraints)
-        whenever(motionLayout.getConstraintSet(LARGE_SCREEN_HEADER_CONSTRAINT))
-            .thenReturn(largeScreenConstraints)
-    }
-
-    private fun setUpDefaultInsets() {
-        whenever(combinedShadeHeadersConstraintManager
-            .edgesGuidelinesConstraints(anyInt(), anyInt(), anyInt(), anyInt())
-        ).thenReturn(EMPTY_CHANGES)
-        whenever(combinedShadeHeadersConstraintManager.emptyCutoutConstraints())
-            .thenReturn(EMPTY_CHANGES)
-        whenever(combinedShadeHeadersConstraintManager
-            .centerCutoutConstraints(anyBoolean(), anyInt())
-        ).thenReturn(EMPTY_CHANGES)
-        whenever(combinedShadeHeadersConstraintManager
-            .privacyChipVisibilityConstraints(anyBoolean())
-        ).thenReturn(EMPTY_CHANGES)
-        whenever(insetsProvider.getStatusBarContentInsetsForCurrentRotation())
-            .thenReturn(Pair(0, 0).toAndroidPair())
-        whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(false)
-    }
-
-    private fun<T, U> Pair<T, U>.toAndroidPair(): android.util.Pair<T, U> {
-        return android.util.Pair(first, second)
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
deleted file mode 100644
index 2bf2a81..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
+++ /dev/null
@@ -1,340 +0,0 @@
-package com.android.systemui.shade
-
-import android.animation.Animator
-import android.animation.ValueAnimator
-import android.app.StatusBarManager
-import android.content.Context
-import android.testing.AndroidTestingRunner
-import android.view.View
-import android.view.ViewPropertyAnimator
-import android.widget.TextView
-import androidx.test.filters.SmallTest
-import com.android.systemui.R
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.animation.Interpolators
-import com.android.systemui.animation.ShadeInterpolation
-import com.android.systemui.battery.BatteryMeterView
-import com.android.systemui.battery.BatteryMeterViewController
-import com.android.systemui.demomode.DemoMode
-import com.android.systemui.demomode.DemoModeController
-import com.android.systemui.dump.DumpManager
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
-import com.android.systemui.qs.HeaderPrivacyIconsController
-import com.android.systemui.qs.carrier.QSCarrierGroup
-import com.android.systemui.qs.carrier.QSCarrierGroupController
-import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
-import com.android.systemui.statusbar.phone.StatusBarIconController
-import com.android.systemui.statusbar.phone.StatusIconContainer
-import com.android.systemui.statusbar.policy.Clock
-import com.android.systemui.statusbar.policy.FakeConfigurationController
-import com.android.systemui.statusbar.policy.VariableDateViewController
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.argumentCaptor
-import com.android.systemui.util.mockito.capture
-import com.android.systemui.util.mockito.mock
-import com.google.common.truth.Truth.assertThat
-import org.junit.After
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Answers
-import org.mockito.ArgumentMatchers.anyFloat
-import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.Mock
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.junit.MockitoJUnit
-import org.mockito.Mockito.`when` as whenever
-
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
-
-    @Mock private lateinit var view: View
-    @Mock private lateinit var statusIcons: StatusIconContainer
-    @Mock private lateinit var statusBarIconController: StatusBarIconController
-    @Mock private lateinit var iconManagerFactory: StatusBarIconController.TintedIconManager.Factory
-    @Mock private lateinit var iconManager: StatusBarIconController.TintedIconManager
-    @Mock private lateinit var qsCarrierGroupController: QSCarrierGroupController
-    @Mock private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder
-    @Mock private lateinit var featureFlags: FeatureFlags
-    @Mock private lateinit var clock: Clock
-    @Mock private lateinit var date: TextView
-    @Mock private lateinit var carrierGroup: QSCarrierGroup
-    @Mock private lateinit var batteryMeterView: BatteryMeterView
-    @Mock private lateinit var batteryMeterViewController: BatteryMeterViewController
-    @Mock private lateinit var privacyIconsController: HeaderPrivacyIconsController
-    @Mock private lateinit var insetsProvider: StatusBarContentInsetsProvider
-    @Mock private lateinit var variableDateViewControllerFactory: VariableDateViewController.Factory
-    @Mock private lateinit var variableDateViewController: VariableDateViewController
-    @Mock private lateinit var dumpManager: DumpManager
-    @Mock private lateinit var combinedShadeHeadersConstraintManager:
-        CombinedShadeHeadersConstraintManager
-
-    @Mock private lateinit var mockedContext: Context
-    @Mock private lateinit var demoModeController: DemoModeController
-
-    @JvmField @Rule val mockitoRule = MockitoJUnit.rule()
-    var viewVisibility = View.GONE
-    var viewAlpha = 1f
-
-    private lateinit var mLargeScreenShadeHeaderController: LargeScreenShadeHeaderController
-    private lateinit var carrierIconSlots: List<String>
-    private val configurationController = FakeConfigurationController()
-
-    @Before
-    fun setup() {
-        whenever<Clock>(view.findViewById(R.id.clock)).thenReturn(clock)
-        whenever(clock.context).thenReturn(mockedContext)
-        whenever<TextView>(view.findViewById(R.id.date)).thenReturn(date)
-        whenever(date.context).thenReturn(mockedContext)
-        whenever<QSCarrierGroup>(view.findViewById(R.id.carrier_group)).thenReturn(carrierGroup)
-        whenever<BatteryMeterView>(view.findViewById(R.id.batteryRemainingIcon))
-                .thenReturn(batteryMeterView)
-        whenever<StatusIconContainer>(view.findViewById(R.id.statusIcons)).thenReturn(statusIcons)
-        whenever(view.context).thenReturn(context)
-        whenever(view.resources).thenReturn(context.resources)
-        whenever(statusIcons.context).thenReturn(context)
-        whenever(qsCarrierGroupControllerBuilder.setQSCarrierGroup(any()))
-                .thenReturn(qsCarrierGroupControllerBuilder)
-        whenever(qsCarrierGroupControllerBuilder.build()).thenReturn(qsCarrierGroupController)
-        whenever(view.setVisibility(anyInt())).then {
-            viewVisibility = it.arguments[0] as Int
-            null
-        }
-        whenever(view.visibility).thenAnswer { _ -> viewVisibility }
-
-        whenever(view.setAlpha(anyFloat())).then {
-            viewAlpha = it.arguments[0] as Float
-            null
-        }
-        whenever(view.alpha).thenAnswer { _ -> viewAlpha }
-
-        whenever(variableDateViewControllerFactory.create(any()))
-            .thenReturn(variableDateViewController)
-        whenever(iconManagerFactory.create(any(), any())).thenReturn(iconManager)
-        whenever(featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)).thenReturn(false)
-        mLargeScreenShadeHeaderController = LargeScreenShadeHeaderController(
-                view,
-                statusBarIconController,
-                iconManagerFactory,
-                privacyIconsController,
-                insetsProvider,
-                configurationController,
-                variableDateViewControllerFactory,
-                batteryMeterViewController,
-                dumpManager,
-                featureFlags,
-                qsCarrierGroupControllerBuilder,
-                combinedShadeHeadersConstraintManager,
-                demoModeController
-                )
-        whenever(view.isAttachedToWindow).thenReturn(true)
-        mLargeScreenShadeHeaderController.init()
-        carrierIconSlots = listOf(
-                context.getString(com.android.internal.R.string.status_bar_mobile))
-    }
-
-    @After
-    fun verifyEveryTest() {
-        verifyZeroInteractions(combinedShadeHeadersConstraintManager)
-    }
-
-    @Test
-    fun setVisible_onlyWhenActive() {
-        makeShadeVisible()
-        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
-
-        mLargeScreenShadeHeaderController.largeScreenActive = false
-        assertThat(viewVisibility).isEqualTo(View.GONE)
-    }
-
-    @Test
-    fun updateListeners_registersWhenVisible() {
-        makeShadeVisible()
-        verify(qsCarrierGroupController).setListening(true)
-        verify(statusBarIconController).addIconGroup(any())
-    }
-
-    @Test
-    fun shadeExpandedFraction_updatesAlpha() {
-        makeShadeVisible()
-        mLargeScreenShadeHeaderController.shadeExpandedFraction = 0.5f
-        verify(view).setAlpha(ShadeInterpolation.getContentAlpha(0.5f))
-    }
-
-    @Test
-    fun alphaChangesUpdateVisibility() {
-        makeShadeVisible()
-        mLargeScreenShadeHeaderController.shadeExpandedFraction = 0f
-        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
-
-        mLargeScreenShadeHeaderController.shadeExpandedFraction = 1f
-        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
-    }
-
-    @Test
-    fun singleCarrier_enablesCarrierIconsInStatusIcons() {
-        whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(true)
-
-        makeShadeVisible()
-
-        verify(statusIcons).removeIgnoredSlots(carrierIconSlots)
-    }
-
-    @Test
-    fun dualCarrier_disablesCarrierIconsInStatusIcons() {
-        whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(false)
-
-        makeShadeVisible()
-
-        verify(statusIcons).addIgnoredSlots(carrierIconSlots)
-    }
-
-    @Test
-    fun disableQS_notDisabled_visible() {
-        makeShadeVisible()
-        mLargeScreenShadeHeaderController.disable(0, 0, false)
-
-        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
-    }
-
-    @Test
-    fun disableQS_disabled_gone() {
-        makeShadeVisible()
-        mLargeScreenShadeHeaderController.disable(0, StatusBarManager.DISABLE2_QUICK_SETTINGS,
-            false)
-
-        assertThat(viewVisibility).isEqualTo(View.GONE)
-    }
-
-    private fun makeShadeVisible() {
-        mLargeScreenShadeHeaderController.largeScreenActive = true
-        mLargeScreenShadeHeaderController.qsVisible = true
-    }
-
-    @Test
-    fun updateConfig_changesFontStyle() {
-        configurationController.notifyDensityOrFontScaleChanged()
-
-        verify(clock).setTextAppearance(R.style.TextAppearance_QS_Status)
-        verify(date).setTextAppearance(R.style.TextAppearance_QS_Status)
-        verify(carrierGroup).updateTextAppearance(R.style.TextAppearance_QS_Status_Carriers)
-    }
-
-    @Test
-    fun alarmIconIgnored() {
-        verify(statusIcons).addIgnoredSlot(
-                context.getString(com.android.internal.R.string.status_bar_alarm_clock)
-        )
-    }
-
-    @Test
-    fun animateOutOnStartCustomizing() {
-        val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
-        val duration = 1000L
-        whenever(view.animate()).thenReturn(animator)
-
-        mLargeScreenShadeHeaderController.startCustomizingAnimation(show = true, duration)
-
-        verify(animator).setDuration(duration)
-        verify(animator).alpha(0f)
-        verify(animator).setInterpolator(Interpolators.ALPHA_OUT)
-        verify(animator).start()
-    }
-
-    @Test
-    fun animateInOnEndCustomizing() {
-        val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
-        val duration = 1000L
-        whenever(view.animate()).thenReturn(animator)
-
-        mLargeScreenShadeHeaderController.startCustomizingAnimation(show = false, duration)
-
-        verify(animator).setDuration(duration)
-        verify(animator).alpha(1f)
-        verify(animator).setInterpolator(Interpolators.ALPHA_IN)
-        verify(animator).start()
-    }
-
-    @Test
-    fun testShadeExpanded_true_alpha_zero_invisible() {
-        view.alpha = 0f
-        mLargeScreenShadeHeaderController.largeScreenActive = true
-        mLargeScreenShadeHeaderController.qsVisible = true
-
-        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
-    }
-
-    @Test
-    fun animatorCallsUpdateVisibilityOnUpdate() {
-        val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
-        whenever(view.animate()).thenReturn(animator)
-
-        mLargeScreenShadeHeaderController.startCustomizingAnimation(show = false, 0L)
-
-        val updateCaptor = argumentCaptor<ValueAnimator.AnimatorUpdateListener>()
-        verify(animator).setUpdateListener(capture(updateCaptor))
-
-        mLargeScreenShadeHeaderController.largeScreenActive = true
-        mLargeScreenShadeHeaderController.qsVisible = true
-
-        view.alpha = 1f
-        updateCaptor.value.onAnimationUpdate(mock())
-
-        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
-
-        view.alpha = 0f
-        updateCaptor.value.onAnimationUpdate(mock())
-
-        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
-    }
-
-    @Test
-    fun animatorListenersClearedAtEnd() {
-        val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
-        whenever(view.animate()).thenReturn(animator)
-
-        mLargeScreenShadeHeaderController.startCustomizingAnimation(show = true, 0L)
-        val listenerCaptor = argumentCaptor<Animator.AnimatorListener>()
-        verify(animator).setListener(capture(listenerCaptor))
-
-        listenerCaptor.value.onAnimationEnd(mock())
-        verify(animator).setListener(null)
-        verify(animator).setUpdateListener(null)
-    }
-
-    @Test
-    fun animatorListenersClearedOnCancel() {
-        val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
-        whenever(view.animate()).thenReturn(animator)
-
-        mLargeScreenShadeHeaderController.startCustomizingAnimation(show = true, 0L)
-        val listenerCaptor = argumentCaptor<Animator.AnimatorListener>()
-        verify(animator).setListener(capture(listenerCaptor))
-
-        listenerCaptor.value.onAnimationCancel(mock())
-        verify(animator).setListener(null)
-        verify(animator).setUpdateListener(null)
-    }
-
-    @Test
-    fun demoMode_attachDemoMode() {
-        val cb = argumentCaptor<DemoMode>()
-        verify(demoModeController).addCallback(capture(cb))
-        cb.value.onDemoModeStarted()
-        verify(clock).onDemoModeStarted()
-    }
-
-    @Test
-    fun demoMode_detachDemoMode() {
-        mLargeScreenShadeHeaderController.simulateViewDetached()
-        val cb = argumentCaptor<DemoMode>()
-        verify(demoModeController).removeCallback(capture(cb))
-        cb.value.onDemoModeFinished()
-        verify(clock).onDemoModeFinished()
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
new file mode 100644
index 0000000..52b0b6a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -0,0 +1,753 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shade;
+
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+
+import static com.android.keyguard.KeyguardClockSwitch.LARGE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static kotlinx.coroutines.flow.FlowKt.emptyFlow;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.annotation.IdRes;
+import android.content.ContentResolver;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.UserManager;
+import android.util.DisplayMetrics;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.view.ViewPropertyAnimator;
+import android.view.ViewStub;
+import android.view.ViewTreeObserver;
+import android.view.accessibility.AccessibilityManager;
+
+import androidx.constraintlayout.widget.ConstraintSet;
+
+import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.logging.testing.UiEventLoggerFake;
+import com.android.internal.util.LatencyTracker;
+import com.android.keyguard.KeyguardClockSwitch;
+import com.android.keyguard.KeyguardClockSwitchController;
+import com.android.keyguard.KeyguardStatusView;
+import com.android.keyguard.KeyguardStatusViewController;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.LockIconViewController;
+import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
+import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
+import com.android.keyguard.dagger.KeyguardStatusViewComponent;
+import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.biometrics.AuthController;
+import com.android.systemui.classifier.FalsingCollectorFake;
+import com.android.systemui.classifier.FalsingManagerFake;
+import com.android.systemui.common.ui.view.LongPressHandlingView;
+import com.android.systemui.doze.DozeLog;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository;
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
+import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
+import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor;
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
+import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
+import com.android.systemui.media.controls.pipeline.MediaDataManager;
+import com.android.systemui.media.controls.ui.KeyguardMediaController;
+import com.android.systemui.media.controls.ui.MediaHierarchyManager;
+import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.qs.QS;
+import com.android.systemui.qs.QSFragment;
+import com.android.systemui.screenrecord.RecordingController;
+import com.android.systemui.shade.transition.ShadeTransitionController;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.KeyguardIndicationController;
+import com.android.systemui.statusbar.LockscreenShadeTransitionController;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationShadeDepthController;
+import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.NotificationShelfController;
+import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.QsFrameTranslateController;
+import com.android.systemui.statusbar.StatusBarStateControllerImpl;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.VibratorHelper;
+import com.android.systemui.statusbar.notification.ConversationNotificationManager;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinatorLogger;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.notification.stack.AmbientState;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
+import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
+import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
+import com.android.systemui.statusbar.phone.KeyguardBottomAreaViewController;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
+import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController;
+import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
+import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
+import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
+import com.android.systemui.statusbar.phone.TapAgainViewController;
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController;
+import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView;
+import com.android.systemui.statusbar.window.StatusBarWindowStateController;
+import com.android.systemui.unfold.SysUIUnfoldComponent;
+import com.android.systemui.util.time.FakeSystemClock;
+import com.android.systemui.util.time.SystemClock;
+import com.android.wm.shell.animation.FlingAnimationUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
+
+import java.util.List;
+import java.util.Optional;
+
+import dagger.Lazy;
+import kotlinx.coroutines.CoroutineDispatcher;
+
+public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
+
+    protected static final int SPLIT_SHADE_FULL_TRANSITION_DISTANCE = 400;
+    protected static final int NOTIFICATION_SCRIM_TOP_PADDING_IN_SPLIT_SHADE = 50;
+    protected static final int PANEL_WIDTH = 500; // Random value just for the test.
+
+    @Mock protected CentralSurfaces mCentralSurfaces;
+    @Mock protected NotificationStackScrollLayout mNotificationStackScrollLayout;
+    @Mock protected KeyguardBottomAreaView mKeyguardBottomArea;
+    @Mock protected KeyguardBottomAreaViewController mKeyguardBottomAreaViewController;
+    @Mock protected KeyguardBottomAreaView mQsFrame;
+    @Mock protected HeadsUpManagerPhone mHeadsUpManager;
+    @Mock protected NotificationShelfController mNotificationShelfController;
+    @Mock protected NotificationGutsManager mGutsManager;
+    @Mock protected KeyguardStatusBarView mKeyguardStatusBar;
+    @Mock protected KeyguardUserSwitcherView mUserSwitcherView;
+    @Mock protected ViewStub mUserSwitcherStubView;
+    @Mock protected HeadsUpTouchHelper.Callback mHeadsUpCallback;
+    @Mock protected KeyguardUpdateMonitor mUpdateMonitor;
+    @Mock protected KeyguardBypassController mKeyguardBypassController;
+    @Mock protected DozeParameters mDozeParameters;
+    @Mock protected ScreenOffAnimationController mScreenOffAnimationController;
+    @Mock protected NotificationPanelView mView;
+    @Mock protected LayoutInflater mLayoutInflater;
+    @Mock protected FeatureFlags mFeatureFlags;
+    @Mock protected DynamicPrivacyController mDynamicPrivacyController;
+    @Mock protected StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+    @Mock protected KeyguardStateController mKeyguardStateController;
+    @Mock protected DozeLog mDozeLog;
+    @Mock protected ShadeLogger mShadeLog;
+    @Mock protected ShadeHeightLogger mShadeHeightLogger;
+    @Mock protected CommandQueue mCommandQueue;
+    @Mock protected VibratorHelper mVibratorHelper;
+    @Mock protected LatencyTracker mLatencyTracker;
+    @Mock protected PowerManager mPowerManager;
+    @Mock protected AccessibilityManager mAccessibilityManager;
+    @Mock protected MetricsLogger mMetricsLogger;
+    @Mock protected Resources mResources;
+    @Mock protected Configuration mConfiguration;
+    @Mock protected KeyguardClockSwitch mKeyguardClockSwitch;
+    @Mock protected MediaHierarchyManager mMediaHierarchyManager;
+    @Mock protected ConversationNotificationManager mConversationNotificationManager;
+    @Mock protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    @Mock protected KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
+    @Mock protected KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory;
+    @Mock protected KeyguardQsUserSwitchComponent mKeyguardQsUserSwitchComponent;
+    @Mock protected KeyguardQsUserSwitchController mKeyguardQsUserSwitchController;
+    @Mock protected KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
+    @Mock protected KeyguardUserSwitcherComponent mKeyguardUserSwitcherComponent;
+    @Mock protected KeyguardUserSwitcherController mKeyguardUserSwitcherController;
+    @Mock protected KeyguardStatusViewComponent mKeyguardStatusViewComponent;
+    @Mock protected KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory;
+    @Mock protected KeyguardStatusBarViewComponent mKeyguardStatusBarViewComponent;
+    @Mock protected KeyguardClockSwitchController mKeyguardClockSwitchController;
+    @Mock protected KeyguardStatusViewController mKeyguardStatusViewController;
+    @Mock protected KeyguardStatusBarViewController mKeyguardStatusBarViewController;
+    @Mock protected NotificationStackScrollLayoutController
+            mNotificationStackScrollLayoutController;
+    @Mock protected NotificationShadeDepthController mNotificationShadeDepthController;
+    @Mock protected LockscreenShadeTransitionController mLockscreenShadeTransitionController;
+    @Mock protected AuthController mAuthController;
+    @Mock protected ScrimController mScrimController;
+    @Mock protected MediaDataManager mMediaDataManager;
+    @Mock protected AmbientState mAmbientState;
+    @Mock protected UserManager mUserManager;
+    @Mock protected UiEventLogger mUiEventLogger;
+    @Mock protected LockIconViewController mLockIconViewController;
+    @Mock protected KeyguardMediaController mKeyguardMediaController;
+    @Mock protected NavigationModeController mNavigationModeController;
+    @Mock protected NavigationBarController mNavigationBarController;
+    @Mock protected QuickSettingsController mQsController;
+    @Mock protected ShadeHeaderController mShadeHeaderController;
+    @Mock protected ContentResolver mContentResolver;
+    @Mock protected TapAgainViewController mTapAgainViewController;
+    @Mock protected KeyguardIndicationController mKeyguardIndicationController;
+    @Mock protected FragmentService mFragmentService;
+    @Mock protected FragmentHostManager mFragmentHostManager;
+    @Mock protected NotificationRemoteInputManager mNotificationRemoteInputManager;
+    @Mock protected RecordingController mRecordingController;
+    @Mock protected LockscreenGestureLogger mLockscreenGestureLogger;
+    @Mock protected DumpManager mDumpManager;
+    @Mock protected InteractionJankMonitor mInteractionJankMonitor;
+    @Mock protected NotificationsQSContainerController mNotificationsQSContainerController;
+    @Mock protected QsFrameTranslateController mQsFrameTranslateController;
+    @Mock protected StatusBarWindowStateController mStatusBarWindowStateController;
+    @Mock protected KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
+    @Mock protected NotificationShadeWindowController mNotificationShadeWindowController;
+    @Mock protected SysUiState mSysUiState;
+    @Mock protected NotificationListContainer mNotificationListContainer;
+    @Mock protected NotificationStackSizeCalculator mNotificationStackSizeCalculator;
+    @Mock protected UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
+    @Mock protected ShadeTransitionController mShadeTransitionController;
+    @Mock protected QS mQs;
+    @Mock protected QSFragment mQSFragment;
+    @Mock protected ViewGroup mQsHeader;
+    @Mock protected ViewParent mViewParent;
+    @Mock protected ViewTreeObserver mViewTreeObserver;
+    @Mock protected KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel;
+    @Mock protected DreamingToLockscreenTransitionViewModel
+            mDreamingToLockscreenTransitionViewModel;
+    @Mock protected OccludedToLockscreenTransitionViewModel
+            mOccludedToLockscreenTransitionViewModel;
+    @Mock protected LockscreenToDreamingTransitionViewModel
+            mLockscreenToDreamingTransitionViewModel;
+    @Mock protected LockscreenToOccludedTransitionViewModel
+            mLockscreenToOccludedTransitionViewModel;
+    @Mock protected GoneToDreamingTransitionViewModel mGoneToDreamingTransitionViewModel;
+
+    @Mock protected KeyguardTransitionInteractor mKeyguardTransitionInteractor;
+    @Mock protected KeyguardLongPressViewModel mKeyuardLongPressViewModel;
+    @Mock protected AlternateBouncerInteractor mAlternateBouncerInteractor;
+    @Mock protected MotionEvent mDownMotionEvent;
+    @Mock protected CoroutineDispatcher mMainDispatcher;
+    @Captor
+    protected ArgumentCaptor<NotificationStackScrollLayout.OnEmptySpaceClickListener>
+            mEmptySpaceClickListenerCaptor;
+
+    protected KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
+    protected KeyguardInteractor mKeyguardInteractor;
+    protected NotificationPanelViewController.TouchHandler mTouchHandler;
+    protected ConfigurationController mConfigurationController;
+    protected SysuiStatusBarStateController mStatusBarStateController;
+    protected NotificationPanelViewController mNotificationPanelViewController;
+    protected View.AccessibilityDelegate mAccessibilityDelegate;
+    protected NotificationsQuickSettingsContainer mNotificationContainerParent;
+    protected List<View.OnAttachStateChangeListener> mOnAttachStateChangeListeners;
+    protected Handler mMainHandler;
+    protected View.OnLayoutChangeListener mLayoutChangeListener;
+
+    protected final FalsingManagerFake mFalsingManager = new FalsingManagerFake();
+    protected final Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
+    protected final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
+    protected final ShadeExpansionStateManager mShadeExpansionStateManager =
+            new ShadeExpansionStateManager();
+
+    protected QuickSettingsController mQuickSettingsController;
+    @Mock protected Lazy<NotificationPanelViewController> mNotificationPanelViewControllerLazy;
+
+    protected FragmentHostManager.FragmentListener mFragmentListener;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mMainDispatcher = getMainDispatcher();
+        mKeyguardBottomAreaInteractor = new KeyguardBottomAreaInteractor(
+                new FakeKeyguardRepository());
+        mKeyguardInteractor = new KeyguardInteractor(new FakeKeyguardRepository(), mCommandQueue,
+                mFeatureFlags, new FakeKeyguardBouncerRepository());
+        SystemClock systemClock = new FakeSystemClock();
+        mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
+                mInteractionJankMonitor, mShadeExpansionStateManager);
+
+        KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext);
+        keyguardStatusView.setId(R.id.keyguard_status_view);
+
+        when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false);
+        when(mHeadsUpCallback.getContext()).thenReturn(mContext);
+        when(mView.getResources()).thenReturn(mResources);
+        when(mView.getWidth()).thenReturn(PANEL_WIDTH);
+        when(mResources.getConfiguration()).thenReturn(mConfiguration);
+        mConfiguration.orientation = ORIENTATION_PORTRAIT;
+        when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics);
+        mDisplayMetrics.density = 100;
+        when(mResources.getBoolean(R.bool.config_enableNotificationShadeDrag)).thenReturn(true);
+        when(mResources.getDimensionPixelSize(R.dimen.notifications_top_padding_split_shade))
+                .thenReturn(NOTIFICATION_SCRIM_TOP_PADDING_IN_SPLIT_SHADE);
+        when(mResources.getDimensionPixelSize(R.dimen.notification_panel_margin_horizontal))
+                .thenReturn(10);
+        when(mResources.getDimensionPixelSize(R.dimen.split_shade_full_transition_distance))
+                .thenReturn(SPLIT_SHADE_FULL_TRANSITION_DISTANCE);
+        when(mView.getContext()).thenReturn(getContext());
+        when(mView.findViewById(R.id.keyguard_header)).thenReturn(mKeyguardStatusBar);
+        when(mView.findViewById(R.id.keyguard_user_switcher_view)).thenReturn(mUserSwitcherView);
+        when(mView.findViewById(R.id.keyguard_user_switcher_stub)).thenReturn(
+                mUserSwitcherStubView);
+        when(mView.findViewById(R.id.keyguard_clock_container)).thenReturn(mKeyguardClockSwitch);
+        when(mView.findViewById(R.id.notification_stack_scroller))
+                .thenReturn(mNotificationStackScrollLayout);
+        when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(1000);
+        when(mNotificationStackScrollLayoutController.getHeadsUpCallback())
+                .thenReturn(mHeadsUpCallback);
+        when(mKeyguardBottomAreaViewController.getView()).thenReturn(mKeyguardBottomArea);
+        when(mView.findViewById(R.id.keyguard_bottom_area)).thenReturn(mKeyguardBottomArea);
+        when(mKeyguardBottomArea.animate()).thenReturn(mock(ViewPropertyAnimator.class));
+        when(mView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame);
+        when(mView.findViewById(R.id.keyguard_status_view))
+                .thenReturn(mock(KeyguardStatusView.class));
+        mNotificationContainerParent = new NotificationsQuickSettingsContainer(getContext(), null);
+        mNotificationContainerParent.addView(keyguardStatusView);
+        mNotificationContainerParent.onFinishInflate();
+        when(mView.findViewById(R.id.notification_container_parent))
+                .thenReturn(mNotificationContainerParent);
+        when(mFragmentService.getFragmentHostManager(mView)).thenReturn(mFragmentHostManager);
+        FlingAnimationUtils.Builder flingAnimationUtilsBuilder = new FlingAnimationUtils.Builder(
+                mDisplayMetrics);
+        when(mKeyguardQsUserSwitchComponentFactory.build(any()))
+                .thenReturn(mKeyguardQsUserSwitchComponent);
+        when(mKeyguardQsUserSwitchComponent.getKeyguardQsUserSwitchController())
+                .thenReturn(mKeyguardQsUserSwitchController);
+        when(mKeyguardUserSwitcherComponentFactory.build(any()))
+                .thenReturn(mKeyguardUserSwitcherComponent);
+        when(mKeyguardUserSwitcherComponent.getKeyguardUserSwitcherController())
+                .thenReturn(mKeyguardUserSwitcherController);
+        when(mScreenOffAnimationController.shouldAnimateClockChange()).thenReturn(true);
+        when(mQs.getView()).thenReturn(mView);
+        when(mQSFragment.getView()).thenReturn(mView);
+        doAnswer(invocation -> {
+            mFragmentListener = invocation.getArgument(1);
+            return null;
+        }).when(mFragmentHostManager).addTagListener(eq(QS.TAG), any());
+        doAnswer((Answer<Void>) invocation -> {
+            mTouchHandler = invocation.getArgument(0);
+            return null;
+        }).when(mView).setOnTouchListener(any(NotificationPanelViewController.TouchHandler.class));
+
+        // Dreaming->Lockscreen
+        when(mKeyguardTransitionInteractor.getDreamingToLockscreenTransition())
+                .thenReturn(emptyFlow());
+        when(mDreamingToLockscreenTransitionViewModel.getLockscreenAlpha())
+                .thenReturn(emptyFlow());
+        when(mDreamingToLockscreenTransitionViewModel.lockscreenTranslationY(anyInt()))
+                .thenReturn(emptyFlow());
+
+        // Occluded->Lockscreen
+        when(mKeyguardTransitionInteractor.getOccludedToLockscreenTransition())
+                .thenReturn(emptyFlow());
+        when(mOccludedToLockscreenTransitionViewModel.getLockscreenAlpha())
+                .thenReturn(emptyFlow());
+        when(mOccludedToLockscreenTransitionViewModel.lockscreenTranslationY(anyInt()))
+                .thenReturn(emptyFlow());
+
+        // Lockscreen->Dreaming
+        when(mKeyguardTransitionInteractor.getLockscreenToDreamingTransition())
+                .thenReturn(emptyFlow());
+        when(mLockscreenToDreamingTransitionViewModel.getLockscreenAlpha())
+                .thenReturn(emptyFlow());
+        when(mLockscreenToDreamingTransitionViewModel.lockscreenTranslationY(anyInt()))
+                .thenReturn(emptyFlow());
+
+        // Gone->Dreaming
+        when(mKeyguardTransitionInteractor.getGoneToDreamingTransition())
+                .thenReturn(emptyFlow());
+        when(mGoneToDreamingTransitionViewModel.getLockscreenAlpha())
+                .thenReturn(emptyFlow());
+        when(mGoneToDreamingTransitionViewModel.lockscreenTranslationY(anyInt()))
+                .thenReturn(emptyFlow());
+
+        // Lockscreen->Occluded
+        when(mKeyguardTransitionInteractor.getLockscreenToOccludedTransition())
+                .thenReturn(emptyFlow());
+        when(mLockscreenToOccludedTransitionViewModel.getLockscreenAlpha())
+                .thenReturn(emptyFlow());
+        when(mLockscreenToOccludedTransitionViewModel.lockscreenTranslationY(anyInt()))
+                .thenReturn(emptyFlow());
+
+        NotificationWakeUpCoordinator coordinator =
+                new NotificationWakeUpCoordinator(
+                        mDumpManager,
+                        mock(HeadsUpManagerPhone.class),
+                        new StatusBarStateControllerImpl(new UiEventLoggerFake(), mDumpManager,
+                                mInteractionJankMonitor, mShadeExpansionStateManager),
+                        mKeyguardBypassController,
+                        mDozeParameters,
+                        mScreenOffAnimationController,
+                        mock(NotificationWakeUpCoordinatorLogger.class));
+        mConfigurationController = new ConfigurationControllerImpl(mContext);
+        PulseExpansionHandler expansionHandler = new PulseExpansionHandler(
+                mContext,
+                coordinator,
+                mKeyguardBypassController, mHeadsUpManager,
+                mock(NotificationRoundnessManager.class),
+                mConfigurationController,
+                mStatusBarStateController,
+                mFalsingManager,
+                mShadeExpansionStateManager,
+                mLockscreenShadeTransitionController,
+                new FalsingCollectorFake(),
+                mDumpManager);
+        when(mKeyguardStatusViewComponentFactory.build(any()))
+                .thenReturn(mKeyguardStatusViewComponent);
+        when(mKeyguardStatusViewComponent.getKeyguardClockSwitchController())
+                .thenReturn(mKeyguardClockSwitchController);
+        when(mKeyguardStatusViewComponent.getKeyguardStatusViewController())
+                .thenReturn(mKeyguardStatusViewController);
+        when(mKeyguardStatusBarViewComponentFactory.build(any(), any()))
+                .thenReturn(mKeyguardStatusBarViewComponent);
+        when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController())
+                .thenReturn(mKeyguardStatusBarViewController);
+        when(mLayoutInflater.inflate(eq(R.layout.keyguard_status_view), any(), anyBoolean()))
+                .thenReturn(keyguardStatusView);
+        when(mLayoutInflater.inflate(eq(R.layout.keyguard_user_switcher), any(), anyBoolean()))
+                .thenReturn(mUserSwitcherView);
+        when(mLayoutInflater.inflate(eq(R.layout.keyguard_bottom_area), any(), anyBoolean()))
+                .thenReturn(mKeyguardBottomArea);
+        when(mNotificationRemoteInputManager.isRemoteInputActive())
+                .thenReturn(false);
+        when(mInteractionJankMonitor.begin(any(), anyInt()))
+                .thenReturn(true);
+        when(mInteractionJankMonitor.end(anyInt()))
+                .thenReturn(true);
+        doAnswer(invocation -> {
+            ((Runnable) invocation.getArgument(0)).run();
+            return null;
+        }).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
+        doAnswer(invocation -> {
+            mLayoutChangeListener = invocation.getArgument(0);
+            return null;
+        }).when(mView).addOnLayoutChangeListener(any());
+
+        when(mView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
+        when(mView.getParent()).thenReturn(mViewParent);
+        when(mQs.getHeader()).thenReturn(mQsHeader);
+        when(mDownMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_DOWN);
+        when(mSysUiState.setFlag(anyInt(), anyBoolean())).thenReturn(mSysUiState);
+
+        mMainHandler = new Handler(Looper.getMainLooper());
+
+        when(mView.requireViewById(R.id.keyguard_long_press))
+                .thenReturn(mock(LongPressHandlingView.class));
+
+        mNotificationPanelViewController = new NotificationPanelViewController(
+                mView,
+                mMainHandler,
+                mLayoutInflater,
+                mFeatureFlags,
+                coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController,
+                mFalsingManager, new FalsingCollectorFake(),
+                mKeyguardStateController,
+                mStatusBarStateController,
+                mStatusBarWindowStateController,
+                mNotificationShadeWindowController,
+                mDozeLog, mDozeParameters, mCommandQueue, mVibratorHelper,
+                mLatencyTracker, mPowerManager, mAccessibilityManager, 0, mUpdateMonitor,
+                mMetricsLogger,
+                mShadeLog,
+                mShadeHeightLogger,
+                mConfigurationController,
+                () -> flingAnimationUtilsBuilder, mStatusBarTouchableRegionManager,
+                mConversationNotificationManager, mMediaHierarchyManager,
+                mStatusBarKeyguardViewManager,
+                mGutsManager,
+                mNotificationsQSContainerController,
+                mNotificationStackScrollLayoutController,
+                mKeyguardStatusViewComponentFactory,
+                mKeyguardQsUserSwitchComponentFactory,
+                mKeyguardUserSwitcherComponentFactory,
+                mKeyguardStatusBarViewComponentFactory,
+                mLockscreenShadeTransitionController,
+                mAuthController,
+                mScrimController,
+                mUserManager,
+                mMediaDataManager,
+                mNotificationShadeDepthController,
+                mAmbientState,
+                mLockIconViewController,
+                mKeyguardMediaController,
+                mTapAgainViewController,
+                mNavigationModeController,
+                mNavigationBarController,
+                mQsController,
+                mFragmentService,
+                mContentResolver,
+                mRecordingController,
+                mShadeHeaderController,
+                mScreenOffAnimationController,
+                mLockscreenGestureLogger,
+                mShadeExpansionStateManager,
+                mNotificationRemoteInputManager,
+                mSysUIUnfoldComponent,
+                mSysUiState,
+                () -> mKeyguardBottomAreaViewController,
+                mKeyguardUnlockAnimationController,
+                mKeyguardIndicationController,
+                mNotificationListContainer,
+                mNotificationStackSizeCalculator,
+                mUnlockedScreenOffAnimationController,
+                mShadeTransitionController,
+                systemClock,
+                mKeyguardBottomAreaViewModel,
+                mKeyguardBottomAreaInteractor,
+                mAlternateBouncerInteractor,
+                mDreamingToLockscreenTransitionViewModel,
+                mOccludedToLockscreenTransitionViewModel,
+                mLockscreenToDreamingTransitionViewModel,
+                mGoneToDreamingTransitionViewModel,
+                mLockscreenToOccludedTransitionViewModel,
+                mMainDispatcher,
+                mKeyguardTransitionInteractor,
+                mDumpManager,
+                mKeyuardLongPressViewModel,
+                mKeyguardInteractor);
+        mNotificationPanelViewController.initDependencies(
+                mCentralSurfaces,
+                null,
+                () -> {},
+                mNotificationShelfController);
+        mNotificationPanelViewController.setTrackingStartedListener(() -> {});
+        mNotificationPanelViewController.setOpenCloseListener(
+                new NotificationPanelViewController.OpenCloseListener() {
+                    @Override
+                    public void onClosingFinished() {}
+
+                    @Override
+                    public void onOpenStarted() {}
+                });
+        mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
+        ArgumentCaptor<View.OnAttachStateChangeListener> onAttachStateChangeListenerArgumentCaptor =
+                ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
+        verify(mView, atLeast(1)).addOnAttachStateChangeListener(
+                onAttachStateChangeListenerArgumentCaptor.capture());
+        mOnAttachStateChangeListeners = onAttachStateChangeListenerArgumentCaptor.getAllValues();
+
+        ArgumentCaptor<View.AccessibilityDelegate> accessibilityDelegateArgumentCaptor =
+                ArgumentCaptor.forClass(View.AccessibilityDelegate.class);
+        verify(mView).setAccessibilityDelegate(accessibilityDelegateArgumentCaptor.capture());
+        mAccessibilityDelegate = accessibilityDelegateArgumentCaptor.getValue();
+        mNotificationPanelViewController.getStatusBarStateController()
+                .addCallback(mNotificationPanelViewController.getStatusBarStateListener());
+        mNotificationPanelViewController
+                .setHeadsUpAppearanceController(mock(HeadsUpAppearanceController.class));
+        verify(mNotificationStackScrollLayoutController)
+                .setOnEmptySpaceClickListener(mEmptySpaceClickListenerCaptor.capture());
+        verify(mKeyguardStatusViewController).displayClock(LARGE, /* animate */ true);
+        reset(mKeyguardStatusViewController);
+
+        when(mNotificationPanelViewControllerLazy.get())
+                .thenReturn(mNotificationPanelViewController);
+        mQuickSettingsController = new QuickSettingsController(
+                mNotificationPanelViewControllerLazy,
+                mView,
+                mQsFrameTranslateController,
+                mShadeTransitionController,
+                expansionHandler,
+                mNotificationRemoteInputManager,
+                mShadeExpansionStateManager,
+                mStatusBarKeyguardViewManager,
+                mNotificationStackScrollLayoutController,
+                mLockscreenShadeTransitionController,
+                mNotificationShadeDepthController,
+                mShadeHeaderController,
+                mStatusBarTouchableRegionManager,
+                mKeyguardStateController,
+                mKeyguardBypassController,
+                mUpdateMonitor,
+                mScrimController,
+                mMediaDataManager,
+                mMediaHierarchyManager,
+                mAmbientState,
+                mRecordingController,
+                mFalsingManager,
+                new FalsingCollectorFake(),
+                mAccessibilityManager,
+                mLockscreenGestureLogger,
+                mMetricsLogger,
+                mFeatureFlags,
+                mInteractionJankMonitor,
+                mShadeLog
+        );
+    }
+
+    @After
+    public void tearDown() {
+        mNotificationPanelViewController.mBottomAreaShadeAlphaAnimator.cancel();
+        mNotificationPanelViewController.cancelHeightAnimator();
+        mMainHandler.removeCallbacksAndMessages(null);
+    }
+
+    protected void setBottomPadding(int stackBottom, int lockIconPadding, int indicationPadding,
+            int ambientPadding) {
+
+        when(mNotificationStackScrollLayoutController.getTop()).thenReturn(0);
+        when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(stackBottom);
+        when(mNotificationStackScrollLayoutController.getBottom()).thenReturn(stackBottom);
+        when(mLockIconViewController.getTop()).thenReturn((float) (stackBottom - lockIconPadding));
+
+        when(mResources.getDimensionPixelSize(R.dimen.keyguard_indication_bottom_padding))
+                .thenReturn(indicationPadding);
+        mNotificationPanelViewController.loadDimens();
+
+        mNotificationPanelViewController.setAmbientIndicationTop(
+                /* ambientIndicationTop= */ stackBottom - ambientPadding,
+                /* ambientTextVisible= */ true);
+    }
+
+    protected void triggerPositionClockAndNotifications() {
+        mNotificationPanelViewController.onQsSetExpansionHeightCalled(false);
+    }
+
+    protected FalsingManager.FalsingTapListener getFalsingTapListener() {
+        for (View.OnAttachStateChangeListener listener : mOnAttachStateChangeListeners) {
+            listener.onViewAttachedToWindow(mView);
+        }
+        assertThat(mFalsingManager.getTapListeners().size()).isEqualTo(1);
+        return mFalsingManager.getTapListeners().get(0);
+    }
+
+    protected void givenViewAttached() {
+        for (View.OnAttachStateChangeListener listener : mOnAttachStateChangeListeners) {
+            listener.onViewAttachedToWindow(mView);
+        }
+    }
+
+    protected ConstraintSet.Layout getConstraintSetLayout(@IdRes int id) {
+        ConstraintSet constraintSet = new ConstraintSet();
+        constraintSet.clone(mNotificationContainerParent);
+        return constraintSet.getConstraint(id).layout;
+    }
+
+    protected void enableSplitShade(boolean enabled) {
+        when(mResources.getBoolean(R.bool.config_use_split_notification_shade)).thenReturn(enabled);
+        mNotificationPanelViewController.updateResources();
+    }
+
+    protected void updateMultiUserSetting(boolean enabled) {
+        when(mResources.getBoolean(R.bool.qs_show_user_switcher_for_single_user)).thenReturn(false);
+        when(mUserManager.isUserSwitcherEnabled(false)).thenReturn(enabled);
+        final ArgumentCaptor<ContentObserver> observerCaptor =
+                ArgumentCaptor.forClass(ContentObserver.class);
+        verify(mContentResolver)
+                .registerContentObserver(any(), anyBoolean(), observerCaptor.capture());
+        observerCaptor.getValue().onChange(/* selfChange */ false);
+    }
+
+    protected void updateSmallestScreenWidth(int smallestScreenWidthDp) {
+        Configuration configuration = new Configuration();
+        configuration.smallestScreenWidthDp = smallestScreenWidthDp;
+        mConfigurationController.onConfigurationChanged(configuration);
+    }
+
+    protected void onTouchEvent(MotionEvent ev) {
+        mTouchHandler.onTouch(mView, ev);
+    }
+
+    protected void setDozing(boolean dozing, boolean dozingAlwaysOn) {
+        when(mDozeParameters.getAlwaysOn()).thenReturn(dozingAlwaysOn);
+        mNotificationPanelViewController.setDozing(
+                /* dozing= */ dozing,
+                /* animate= */ false
+        );
+    }
+
+    protected void assertKeyguardStatusViewCentered() {
+        mNotificationPanelViewController.updateResources();
+        assertThat(getConstraintSetLayout(R.id.keyguard_status_view).endToEnd).isAnyOf(
+                ConstraintSet.PARENT_ID, ConstraintSet.UNSET);
+    }
+
+    protected void assertKeyguardStatusViewNotCentered() {
+        mNotificationPanelViewController.updateResources();
+        assertThat(getConstraintSetLayout(R.id.keyguard_status_view).endToEnd).isEqualTo(
+                R.id.qs_edge_guideline);
+    }
+
+    protected void setIsFullWidth(boolean fullWidth) {
+        float nsslWidth = fullWidth ? PANEL_WIDTH : PANEL_WIDTH / 2f;
+        when(mNotificationStackScrollLayoutController.getWidth()).thenReturn(nsslWidth);
+        triggerLayoutChange();
+    }
+
+    protected void triggerLayoutChange() {
+        mLayoutChangeListener.onLayoutChange(
+                mView,
+                /* left= */ 0,
+                /* top= */ 0,
+                /* right= */ 0,
+                /* bottom= */ 0,
+                /* oldLeft= */ 0,
+                /* oldTop= */ 0,
+                /* oldRight= */ 0,
+                /* oldBottom= */ 0
+        );
+    }
+
+    protected CoroutineDispatcher getMainDispatcher() {
+        return mMainDispatcher;
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 28f7edf..abcde3d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.shade;
 
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
-
 import static com.android.keyguard.FaceAuthApiRequestReason.NOTIFICATION_PANEL_CLICKED;
 import static com.android.keyguard.KeyguardClockSwitch.LARGE;
 import static com.android.keyguard.KeyguardClockSwitch.SMALL;
@@ -31,553 +29,53 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.annotation.IdRes;
-import android.content.ContentResolver;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.PowerManager;
-import android.os.UserManager;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
-import android.util.DisplayMetrics;
-import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.view.ViewPropertyAnimator;
-import android.view.ViewStub;
-import android.view.ViewTreeObserver;
-import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 
 import androidx.constraintlayout.widget.ConstraintSet;
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.jank.InteractionJankMonitor;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.UiEventLogger;
-import com.android.internal.logging.testing.UiEventLoggerFake;
-import com.android.internal.util.CollectionUtils;
-import com.android.internal.util.LatencyTracker;
 import com.android.keyguard.FaceAuthApiRequestReason;
-import com.android.keyguard.KeyguardClockSwitch;
-import com.android.keyguard.KeyguardClockSwitchController;
-import com.android.keyguard.KeyguardStatusView;
-import com.android.keyguard.KeyguardStatusViewController;
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.LockIconViewController;
-import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
-import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
-import com.android.keyguard.dagger.KeyguardStatusViewComponent;
-import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.biometrics.AuthController;
-import com.android.systemui.classifier.FalsingCollectorFake;
-import com.android.systemui.classifier.FalsingManagerFake;
-import com.android.systemui.common.ui.view.LongPressHandlingView;
-import com.android.systemui.doze.DozeLog;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.fragments.FragmentHostManager;
-import com.android.systemui.fragments.FragmentService;
-import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
-import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
-import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor;
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
-import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
-import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel;
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel;
-import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel;
-import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel;
-import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
-import com.android.systemui.media.controls.pipeline.MediaDataManager;
-import com.android.systemui.media.controls.ui.KeyguardMediaController;
-import com.android.systemui.media.controls.ui.MediaHierarchyManager;
-import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationModeController;
-import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.qs.QSFragment;
-import com.android.systemui.screenrecord.RecordingController;
-import com.android.systemui.shade.transition.ShadeTransitionController;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.KeyguardIndicationController;
-import com.android.systemui.statusbar.LockscreenShadeTransitionController;
-import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.NotificationShadeDepthController;
-import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.NotificationShelfController;
-import com.android.systemui.statusbar.PulseExpansionHandler;
-import com.android.systemui.statusbar.QsFrameTranslateController;
-import com.android.systemui.statusbar.StatusBarStateControllerImpl;
-import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.VibratorHelper;
-import com.android.systemui.statusbar.notification.ConversationNotificationManager;
-import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
-import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinatorLogger;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 import com.android.systemui.statusbar.notification.row.ExpandableView.OnHeightChangedListener;
-import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.notification.stack.AmbientState;
-import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
-import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
-import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
-import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
-import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
-import com.android.systemui.statusbar.phone.KeyguardBottomAreaViewController;
-import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
-import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController;
-import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
-import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
-import com.android.systemui.statusbar.phone.ScrimController;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
-import com.android.systemui.statusbar.phone.TapAgainViewController;
-import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController;
-import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView;
-import com.android.systemui.statusbar.window.StatusBarWindowStateController;
-import com.android.systemui.unfold.SysUIUnfoldComponent;
-import com.android.systemui.util.time.FakeSystemClock;
-import com.android.systemui.util.time.SystemClock;
-import com.android.wm.shell.animation.FlingAnimationUtils;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
 import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.stubbing.Answer;
 
 import java.util.List;
-import java.util.Optional;
-
-import kotlinx.coroutines.CoroutineDispatcher;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-public class NotificationPanelViewControllerTest extends SysuiTestCase {
-
-    private static final int SPLIT_SHADE_FULL_TRANSITION_DISTANCE = 400;
-    private static final int NOTIFICATION_SCRIM_TOP_PADDING_IN_SPLIT_SHADE = 50;
-    private static final int PANEL_WIDTH = 500; // Random value just for the test.
-
-    @Mock private CentralSurfaces mCentralSurfaces;
-    @Mock private NotificationStackScrollLayout mNotificationStackScrollLayout;
-    @Mock private KeyguardBottomAreaView mKeyguardBottomArea;
-    @Mock private KeyguardBottomAreaViewController mKeyguardBottomAreaViewController;
-    @Mock private KeyguardBottomAreaView mQsFrame;
-    @Mock private HeadsUpManagerPhone mHeadsUpManager;
-    @Mock private NotificationShelfController mNotificationShelfController;
-    @Mock private NotificationGutsManager mGutsManager;
-    @Mock private KeyguardStatusBarView mKeyguardStatusBar;
-    @Mock private KeyguardUserSwitcherView mUserSwitcherView;
-    @Mock private ViewStub mUserSwitcherStubView;
-    @Mock private HeadsUpTouchHelper.Callback mHeadsUpCallback;
-    @Mock private KeyguardUpdateMonitor mUpdateMonitor;
-    @Mock private KeyguardBypassController mKeyguardBypassController;
-    @Mock private DozeParameters mDozeParameters;
-    @Mock private ScreenOffAnimationController mScreenOffAnimationController;
-    @Mock private NotificationPanelView mView;
-    @Mock private LayoutInflater mLayoutInflater;
-    @Mock private FeatureFlags mFeatureFlags;
-    @Mock private DynamicPrivacyController mDynamicPrivacyController;
-    @Mock private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
-    @Mock private KeyguardStateController mKeyguardStateController;
-    @Mock private DozeLog mDozeLog;
-    @Mock private ShadeLogger mShadeLog;
-    @Mock private ShadeHeightLogger mShadeHeightLogger;
-    @Mock private CommandQueue mCommandQueue;
-    @Mock private VibratorHelper mVibratorHelper;
-    @Mock private LatencyTracker mLatencyTracker;
-    @Mock private PowerManager mPowerManager;
-    @Mock private AccessibilityManager mAccessibilityManager;
-    @Mock private MetricsLogger mMetricsLogger;
-    @Mock private Resources mResources;
-    @Mock private Configuration mConfiguration;
-    @Mock private KeyguardClockSwitch mKeyguardClockSwitch;
-    @Mock private MediaHierarchyManager mMediaHierarchyManager;
-    @Mock private ConversationNotificationManager mConversationNotificationManager;
-    @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
-    @Mock private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
-    @Mock private KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory;
-    @Mock private KeyguardQsUserSwitchComponent mKeyguardQsUserSwitchComponent;
-    @Mock private KeyguardQsUserSwitchController mKeyguardQsUserSwitchController;
-    @Mock private KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
-    @Mock private KeyguardUserSwitcherComponent mKeyguardUserSwitcherComponent;
-    @Mock private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
-    @Mock private KeyguardStatusViewComponent mKeyguardStatusViewComponent;
-    @Mock private KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory;
-    @Mock private KeyguardStatusBarViewComponent mKeyguardStatusBarViewComponent;
-    @Mock private KeyguardClockSwitchController mKeyguardClockSwitchController;
-    @Mock private KeyguardStatusViewController mKeyguardStatusViewController;
-    @Mock private KeyguardStatusBarViewController mKeyguardStatusBarViewController;
-    @Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
-    @Mock private NotificationShadeDepthController mNotificationShadeDepthController;
-    @Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
-    @Mock private AuthController mAuthController;
-    @Mock private ScrimController mScrimController;
-    @Mock private MediaDataManager mMediaDataManager;
-    @Mock private AmbientState mAmbientState;
-    @Mock private UserManager mUserManager;
-    @Mock private UiEventLogger mUiEventLogger;
-    @Mock private LockIconViewController mLockIconViewController;
-    @Mock private KeyguardMediaController mKeyguardMediaController;
-    @Mock private NavigationModeController mNavigationModeController;
-    @Mock private NavigationBarController mNavigationBarController;
-    @Mock private LargeScreenShadeHeaderController mLargeScreenShadeHeaderController;
-    @Mock private ContentResolver mContentResolver;
-    @Mock private TapAgainViewController mTapAgainViewController;
-    @Mock private KeyguardIndicationController mKeyguardIndicationController;
-    @Mock private FragmentService mFragmentService;
-    @Mock private FragmentHostManager mFragmentHostManager;
-    @Mock private NotificationRemoteInputManager mNotificationRemoteInputManager;
-    @Mock private RecordingController mRecordingController;
-    @Mock private LockscreenGestureLogger mLockscreenGestureLogger;
-    @Mock private DumpManager mDumpManager;
-    @Mock private InteractionJankMonitor mInteractionJankMonitor;
-    @Mock private NotificationsQSContainerController mNotificationsQSContainerController;
-    @Mock private QsFrameTranslateController mQsFrameTranslateController;
-    @Mock private StatusBarWindowStateController mStatusBarWindowStateController;
-    @Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
-    @Mock private NotificationShadeWindowController mNotificationShadeWindowController;
-    @Mock private SysUiState mSysUiState;
-    @Mock private NotificationListContainer mNotificationListContainer;
-    @Mock private NotificationStackSizeCalculator mNotificationStackSizeCalculator;
-    @Mock private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
-    @Mock private ShadeTransitionController mShadeTransitionController;
-    @Mock private QS mQs;
-    @Mock private QSFragment mQSFragment;
-    @Mock private ViewGroup mQsHeader;
-    @Mock private ViewParent mViewParent;
-    @Mock private ViewTreeObserver mViewTreeObserver;
-    @Mock private KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel;
-    @Mock private KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
-    @Mock private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel;
-    @Mock private OccludedToLockscreenTransitionViewModel mOccludedToLockscreenTransitionViewModel;
-    @Mock private LockscreenToDreamingTransitionViewModel mLockscreenToDreamingTransitionViewModel;
-    @Mock private LockscreenToOccludedTransitionViewModel mLockscreenToOccludedTransitionViewModel;
-    @Mock private GoneToDreamingTransitionViewModel mGoneToDreamingTransitionViewModel;
-
-    @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
-    @Mock private KeyguardInteractor mKeyguardInteractor;
-    @Mock private KeyguardLongPressViewModel mKeyuardLongPressViewModel;
-    @Mock private CoroutineDispatcher mMainDispatcher;
-    @Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
-    @Mock private MotionEvent mDownMotionEvent;
-    @Captor
-    private ArgumentCaptor<NotificationStackScrollLayout.OnEmptySpaceClickListener>
-            mEmptySpaceClickListenerCaptor;
-
-    private NotificationPanelViewController.TouchHandler mTouchHandler;
-    private ConfigurationController mConfigurationController;
-    private SysuiStatusBarStateController mStatusBarStateController;
-    private NotificationPanelViewController mNotificationPanelViewController;
-    private View.AccessibilityDelegate mAccessibilityDelegate;
-    private NotificationsQuickSettingsContainer mNotificationContainerParent;
-    private List<View.OnAttachStateChangeListener> mOnAttachStateChangeListeners;
-    private Handler mMainHandler;
-    private View.OnLayoutChangeListener mLayoutChangeListener;
-
-    private final FalsingManagerFake mFalsingManager = new FalsingManagerFake();
-    private final Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
-    private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
-    private final ShadeExpansionStateManager mShadeExpansionStateManager =
-            new ShadeExpansionStateManager();
-    private FragmentHostManager.FragmentListener mFragmentListener;
+public class NotificationPanelViewControllerTest extends NotificationPanelViewControllerBaseTest {
 
     @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        SystemClock systemClock = new FakeSystemClock();
-        mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
-                mInteractionJankMonitor, mShadeExpansionStateManager);
-
-        KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext);
-        keyguardStatusView.setId(R.id.keyguard_status_view);
+    public void before() {
         DejankUtils.setImmediate(true);
-
-        when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false);
-        when(mHeadsUpCallback.getContext()).thenReturn(mContext);
-        when(mView.getResources()).thenReturn(mResources);
-        when(mView.getWidth()).thenReturn(PANEL_WIDTH);
-        when(mResources.getConfiguration()).thenReturn(mConfiguration);
-        mConfiguration.orientation = ORIENTATION_PORTRAIT;
-        when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics);
-        mDisplayMetrics.density = 100;
-        when(mResources.getBoolean(R.bool.config_enableNotificationShadeDrag)).thenReturn(true);
-        when(mResources.getDimensionPixelSize(R.dimen.notifications_top_padding_split_shade))
-                .thenReturn(NOTIFICATION_SCRIM_TOP_PADDING_IN_SPLIT_SHADE);
-        when(mResources.getDimensionPixelSize(R.dimen.notification_panel_margin_horizontal))
-                .thenReturn(10);
-        when(mResources.getDimensionPixelSize(R.dimen.split_shade_full_transition_distance))
-                .thenReturn(SPLIT_SHADE_FULL_TRANSITION_DISTANCE);
-        when(mView.getContext()).thenReturn(getContext());
-        when(mView.findViewById(R.id.keyguard_header)).thenReturn(mKeyguardStatusBar);
-        when(mView.findViewById(R.id.keyguard_user_switcher_view)).thenReturn(mUserSwitcherView);
-        when(mView.findViewById(R.id.keyguard_user_switcher_stub)).thenReturn(
-                mUserSwitcherStubView);
-        when(mView.findViewById(R.id.keyguard_clock_container)).thenReturn(mKeyguardClockSwitch);
-        when(mView.findViewById(R.id.notification_stack_scroller))
-                .thenReturn(mNotificationStackScrollLayout);
-        when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(1000);
-        when(mNotificationStackScrollLayoutController.getHeadsUpCallback())
-                .thenReturn(mHeadsUpCallback);
-        when(mKeyguardBottomAreaViewController.getView()).thenReturn(mKeyguardBottomArea);
-        when(mView.findViewById(R.id.keyguard_bottom_area)).thenReturn(mKeyguardBottomArea);
-        when(mKeyguardBottomArea.animate()).thenReturn(mock(ViewPropertyAnimator.class));
-        when(mView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame);
-        when(mView.findViewById(R.id.keyguard_status_view))
-                .thenReturn(mock(KeyguardStatusView.class));
-        mNotificationContainerParent = new NotificationsQuickSettingsContainer(getContext(), null);
-        mNotificationContainerParent.addView(keyguardStatusView);
-        mNotificationContainerParent.onFinishInflate();
-        when(mView.findViewById(R.id.notification_container_parent))
-                .thenReturn(mNotificationContainerParent);
-        when(mFragmentService.getFragmentHostManager(mView)).thenReturn(mFragmentHostManager);
-        FlingAnimationUtils.Builder flingAnimationUtilsBuilder = new FlingAnimationUtils.Builder(
-                mDisplayMetrics);
-        when(mKeyguardQsUserSwitchComponentFactory.build(any()))
-                .thenReturn(mKeyguardQsUserSwitchComponent);
-        when(mKeyguardQsUserSwitchComponent.getKeyguardQsUserSwitchController())
-                .thenReturn(mKeyguardQsUserSwitchController);
-        when(mKeyguardUserSwitcherComponentFactory.build(any()))
-                .thenReturn(mKeyguardUserSwitcherComponent);
-        when(mKeyguardUserSwitcherComponent.getKeyguardUserSwitcherController())
-                .thenReturn(mKeyguardUserSwitcherController);
-        when(mScreenOffAnimationController.shouldAnimateClockChange()).thenReturn(true);
-        when(mQs.getView()).thenReturn(mView);
-        when(mQSFragment.getView()).thenReturn(mView);
-        doAnswer(invocation -> {
-            mFragmentListener = invocation.getArgument(1);
-            return null;
-        }).when(mFragmentHostManager).addTagListener(eq(QS.TAG), any());
-        doAnswer((Answer<Void>) invocation -> {
-            mTouchHandler = invocation.getArgument(0);
-            return null;
-        }).when(mView).setOnTouchListener(any(NotificationPanelViewController.TouchHandler.class));
-
-        NotificationWakeUpCoordinator coordinator =
-                new NotificationWakeUpCoordinator(
-                        mDumpManager,
-                        mock(HeadsUpManagerPhone.class),
-                        new StatusBarStateControllerImpl(new UiEventLoggerFake(), mDumpManager,
-                                mInteractionJankMonitor, mShadeExpansionStateManager),
-                        mKeyguardBypassController,
-                        mDozeParameters,
-                        mScreenOffAnimationController,
-                        mock(NotificationWakeUpCoordinatorLogger.class));
-        mConfigurationController = new ConfigurationControllerImpl(mContext);
-        PulseExpansionHandler expansionHandler = new PulseExpansionHandler(
-                mContext,
-                coordinator,
-                mKeyguardBypassController, mHeadsUpManager,
-                mock(NotificationRoundnessManager.class),
-                mConfigurationController,
-                mStatusBarStateController,
-                mFalsingManager,
-                mShadeExpansionStateManager,
-                mLockscreenShadeTransitionController,
-                new FalsingCollectorFake(),
-                mDumpManager);
-        when(mKeyguardStatusViewComponentFactory.build(any()))
-                .thenReturn(mKeyguardStatusViewComponent);
-        when(mKeyguardStatusViewComponent.getKeyguardClockSwitchController())
-                .thenReturn(mKeyguardClockSwitchController);
-        when(mKeyguardStatusViewComponent.getKeyguardStatusViewController())
-                .thenReturn(mKeyguardStatusViewController);
-        when(mKeyguardStatusBarViewComponentFactory.build(any(), any()))
-                .thenReturn(mKeyguardStatusBarViewComponent);
-        when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController())
-                .thenReturn(mKeyguardStatusBarViewController);
-        when(mLayoutInflater.inflate(eq(R.layout.keyguard_status_view), any(), anyBoolean()))
-                .thenReturn(keyguardStatusView);
-        when(mLayoutInflater.inflate(eq(R.layout.keyguard_user_switcher), any(), anyBoolean()))
-                .thenReturn(mUserSwitcherView);
-        when(mLayoutInflater.inflate(eq(R.layout.keyguard_bottom_area), any(), anyBoolean()))
-                .thenReturn(mKeyguardBottomArea);
-        when(mNotificationRemoteInputManager.isRemoteInputActive())
-                .thenReturn(false);
-        when(mInteractionJankMonitor.begin(any(), anyInt()))
-                .thenReturn(true);
-        when(mInteractionJankMonitor.end(anyInt()))
-                .thenReturn(true);
-        doAnswer(invocation -> {
-            ((Runnable) invocation.getArgument(0)).run();
-            return null;
-        }).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
-        doAnswer(invocation -> {
-            mLayoutChangeListener = invocation.getArgument(0);
-            return null;
-        }).when(mView).addOnLayoutChangeListener(any());
-
-        when(mView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
-        when(mView.getParent()).thenReturn(mViewParent);
-        when(mQs.getHeader()).thenReturn(mQsHeader);
-        when(mDownMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_DOWN);
-        when(mSysUiState.setFlag(anyInt(), anyBoolean())).thenReturn(mSysUiState);
-
-        mMainHandler = new Handler(Looper.getMainLooper());
-
-        when(mView.requireViewById(R.id.keyguard_long_press))
-                .thenReturn(mock(LongPressHandlingView.class));
-
-        mNotificationPanelViewController = new NotificationPanelViewController(
-                mView,
-                mMainHandler,
-                mLayoutInflater,
-                mFeatureFlags,
-                coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController,
-                mFalsingManager, new FalsingCollectorFake(),
-                mKeyguardStateController,
-                mStatusBarStateController,
-                mStatusBarWindowStateController,
-                mNotificationShadeWindowController,
-                mDozeLog, mDozeParameters, mCommandQueue, mVibratorHelper,
-                mLatencyTracker, mPowerManager, mAccessibilityManager, 0, mUpdateMonitor,
-                mMetricsLogger,
-                mShadeLog,
-                mShadeHeightLogger,
-                mConfigurationController,
-                () -> flingAnimationUtilsBuilder, mStatusBarTouchableRegionManager,
-                mConversationNotificationManager, mMediaHierarchyManager,
-                mStatusBarKeyguardViewManager,
-                mGutsManager,
-                mNotificationsQSContainerController,
-                mNotificationStackScrollLayoutController,
-                mKeyguardStatusViewComponentFactory,
-                mKeyguardQsUserSwitchComponentFactory,
-                mKeyguardUserSwitcherComponentFactory,
-                mKeyguardStatusBarViewComponentFactory,
-                mLockscreenShadeTransitionController,
-                mAuthController,
-                mScrimController,
-                mUserManager,
-                mMediaDataManager,
-                mNotificationShadeDepthController,
-                mAmbientState,
-                mLockIconViewController,
-                mKeyguardMediaController,
-                mTapAgainViewController,
-                mNavigationModeController,
-                mNavigationBarController,
-                mFragmentService,
-                mContentResolver,
-                mRecordingController,
-                mLargeScreenShadeHeaderController,
-                mScreenOffAnimationController,
-                mLockscreenGestureLogger,
-                mShadeExpansionStateManager,
-                mNotificationRemoteInputManager,
-                mSysUIUnfoldComponent,
-                mInteractionJankMonitor,
-                mQsFrameTranslateController,
-                mSysUiState,
-                () -> mKeyguardBottomAreaViewController,
-                mKeyguardUnlockAnimationController,
-                mKeyguardIndicationController,
-                mNotificationListContainer,
-                mNotificationStackSizeCalculator,
-                mUnlockedScreenOffAnimationController,
-                mShadeTransitionController,
-                systemClock,
-                mKeyguardBottomAreaViewModel,
-                mKeyguardBottomAreaInteractor,
-                mAlternateBouncerInteractor,
-                mDreamingToLockscreenTransitionViewModel,
-                mOccludedToLockscreenTransitionViewModel,
-                mLockscreenToDreamingTransitionViewModel,
-                mGoneToDreamingTransitionViewModel,
-                mLockscreenToOccludedTransitionViewModel,
-                mMainDispatcher,
-                mKeyguardTransitionInteractor,
-                mDumpManager,
-                mKeyuardLongPressViewModel,
-                mKeyguardInteractor);
-        mNotificationPanelViewController.initDependencies(
-                mCentralSurfaces,
-                null,
-                () -> {},
-                mNotificationShelfController);
-        mNotificationPanelViewController.setTrackingStartedListener(() -> {});
-        mNotificationPanelViewController.setOpenCloseListener(
-                new NotificationPanelViewController.OpenCloseListener() {
-                    @Override
-                    public void onClosingFinished() {}
-
-                    @Override
-                    public void onOpenStarted() {}
-                });
-        mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
-        ArgumentCaptor<View.OnAttachStateChangeListener> onAttachStateChangeListenerArgumentCaptor =
-                ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
-        verify(mView, atLeast(1)).addOnAttachStateChangeListener(
-                onAttachStateChangeListenerArgumentCaptor.capture());
-        mOnAttachStateChangeListeners = onAttachStateChangeListenerArgumentCaptor.getAllValues();
-
-        ArgumentCaptor<View.AccessibilityDelegate> accessibilityDelegateArgumentCaptor =
-                ArgumentCaptor.forClass(View.AccessibilityDelegate.class);
-        verify(mView).setAccessibilityDelegate(accessibilityDelegateArgumentCaptor.capture());
-        mAccessibilityDelegate = accessibilityDelegateArgumentCaptor.getValue();
-        mNotificationPanelViewController.getStatusBarStateController()
-                .addCallback(mNotificationPanelViewController.getStatusBarStateListener());
-        mNotificationPanelViewController
-                .setHeadsUpAppearanceController(mock(HeadsUpAppearanceController.class));
-        verify(mNotificationStackScrollLayoutController)
-                .setOnEmptySpaceClickListener(mEmptySpaceClickListenerCaptor.capture());
-        verify(mKeyguardStatusViewController).displayClock(LARGE, /* animate */ true);
-        reset(mKeyguardStatusViewController);
-    }
-
-    @After
-    public void tearDown() {
-        mNotificationPanelViewController.cancelHeightAnimator();
-        mMainHandler.removeCallbacksAndMessages(null);
     }
 
     @Test
@@ -632,23 +130,6 @@
                 .isNotEqualTo(-1);
     }
 
-    private void setBottomPadding(int stackBottom, int lockIconPadding, int indicationPadding,
-            int ambientPadding) {
-
-        when(mNotificationStackScrollLayoutController.getTop()).thenReturn(0);
-        when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(stackBottom);
-        when(mNotificationStackScrollLayoutController.getBottom()).thenReturn(stackBottom);
-        when(mLockIconViewController.getTop()).thenReturn((float) (stackBottom - lockIconPadding));
-
-        when(mResources.getDimensionPixelSize(R.dimen.keyguard_indication_bottom_padding))
-                .thenReturn(indicationPadding);
-        mNotificationPanelViewController.loadDimens();
-
-        mNotificationPanelViewController.setAmbientIndicationTop(
-                /* ambientIndicationTop= */ stackBottom - ambientPadding,
-                /* ambientTextVisible= */ true);
-    }
-
     @Test
     @Ignore("b/261472011 - Test appears inconsistent across environments")
     public void getVerticalSpaceForLockscreenNotifications_useLockIconBottomPadding_returnsSpaceAvailable() {
@@ -755,27 +236,14 @@
 
     @Test
     public void testOnTouchEvent_expansionCanBeBlocked() {
-        onTouchEvent(MotionEvent.obtain(0L /* downTime */,
-                0L /* eventTime */, MotionEvent.ACTION_DOWN, 0f /* x */, 0f /* y */,
-                0 /* metaState */));
-        onTouchEvent(MotionEvent.obtain(0L /* downTime */,
-                0L /* eventTime */, MotionEvent.ACTION_MOVE, 0f /* x */, 200f /* y */,
-                0 /* metaState */));
+        onTouchEvent(MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0));
+        onTouchEvent(MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 200f, 0));
         assertThat((int) mNotificationPanelViewController.getExpandedHeight()).isEqualTo(200);
-        assertThat(mNotificationPanelViewController.isTrackingBlocked()).isFalse();
 
         mNotificationPanelViewController.blockExpansionForCurrentTouch();
-        onTouchEvent(MotionEvent.obtain(0L /* downTime */,
-                0L /* eventTime */, MotionEvent.ACTION_MOVE, 0f /* x */, 300f /* y */,
-                0 /* metaState */));
+        onTouchEvent(MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 300f, 0));
         // Expansion should not have changed because it was blocked
         assertThat((int) mNotificationPanelViewController.getExpandedHeight()).isEqualTo(200);
-        assertThat(mNotificationPanelViewController.isTrackingBlocked()).isTrue();
-
-        onTouchEvent(MotionEvent.obtain(0L /* downTime */,
-                0L /* eventTime */, MotionEvent.ACTION_UP, 0f /* x */, 300f /* y */,
-                0 /* metaState */));
-        assertThat(mNotificationPanelViewController.isTrackingBlocked()).isFalse();
     }
 
     @Test
@@ -966,68 +434,6 @@
     }
 
     @Test
-    public void testDisableUserSwitcherAfterEnabling_returnsViewStubToTheViewHierarchy() {
-        givenViewAttached();
-        when(mResources.getBoolean(
-                com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true);
-        updateMultiUserSetting(true);
-        clearInvocations(mView);
-
-        updateMultiUserSetting(false);
-
-        ArgumentCaptor<View> captor = ArgumentCaptor.forClass(View.class);
-        verify(mView, atLeastOnce()).addView(captor.capture(), anyInt());
-        final View userSwitcherStub = CollectionUtils.find(captor.getAllValues(),
-                view -> view.getId() == R.id.keyguard_user_switcher_stub);
-        assertThat(userSwitcherStub).isNotNull();
-        assertThat(userSwitcherStub).isInstanceOf(ViewStub.class);
-    }
-
-    @Test
-    public void testChangeSmallestScreenWidthAndUserSwitchEnabled_inflatesUserSwitchView() {
-        givenViewAttached();
-        when(mView.findViewById(R.id.keyguard_user_switcher_view)).thenReturn(null);
-        updateSmallestScreenWidth(300);
-        when(mResources.getBoolean(
-                com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true);
-        when(mResources.getBoolean(R.bool.qs_show_user_switcher_for_single_user)).thenReturn(false);
-        when(mUserManager.isUserSwitcherEnabled(false)).thenReturn(true);
-
-        updateSmallestScreenWidth(800);
-
-        verify(mUserSwitcherStubView).inflate();
-    }
-
-    @Test
-    public void testFinishInflate_userSwitcherDisabled_doNotInflateUserSwitchView_initClock() {
-        givenViewAttached();
-        when(mResources.getBoolean(
-                com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true);
-        when(mResources.getBoolean(R.bool.qs_show_user_switcher_for_single_user)).thenReturn(false);
-        when(mUserManager.isUserSwitcherEnabled(false /* showEvenIfNotActionable */))
-                .thenReturn(false);
-
-        mNotificationPanelViewController.onFinishInflate();
-
-        verify(mUserSwitcherStubView, never()).inflate();
-        verify(mKeyguardStatusViewController, times(3)).displayClock(LARGE, /* animate */ true);
-    }
-
-    @Test
-    public void testReInflateViews_userSwitcherDisabled_doNotInflateUserSwitchView() {
-        givenViewAttached();
-        when(mResources.getBoolean(
-                com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true);
-        when(mResources.getBoolean(R.bool.qs_show_user_switcher_for_single_user)).thenReturn(false);
-        when(mUserManager.isUserSwitcherEnabled(false /* showEvenIfNotActionable */))
-                .thenReturn(false);
-
-        mNotificationPanelViewController.reInflateViews();
-
-        verify(mUserSwitcherStubView, never()).inflate();
-    }
-
-    @Test
     public void testCanCollapsePanelOnTouch_trueForKeyGuard() {
         mStatusBarStateController.setState(KEYGUARD);
 
@@ -1045,7 +451,7 @@
     @Test
     public void testCanCollapsePanelOnTouch_trueWhenInSettings() {
         mStatusBarStateController.setState(SHADE);
-        mNotificationPanelViewController.setQsExpanded(true);
+        when(mQsController.getExpanded()).thenReturn(true);
 
         assertThat(mNotificationPanelViewController.canCollapsePanelOnTouch()).isTrue();
     }
@@ -1054,7 +460,7 @@
     public void testCanCollapsePanelOnTouch_falseInDualPaneShade() {
         mStatusBarStateController.setState(SHADE);
         enableSplitShade(/* enabled= */ true);
-        mNotificationPanelViewController.setQsExpanded(true);
+        when(mQsController.getExpanded()).thenReturn(true);
 
         assertThat(mNotificationPanelViewController.canCollapsePanelOnTouch()).isFalse();
     }
@@ -1103,29 +509,9 @@
     }
 
     @Test
-    public void testDoubleTapRequired_Keyguard() {
-        FalsingManager.FalsingTapListener listener = getFalsingTapListener();
-        mStatusBarStateController.setState(KEYGUARD);
-
-        listener.onAdditionalTapRequired();
-
-        verify(mKeyguardIndicationController).showTransientIndication(anyInt());
-    }
-
-    @Test
-    public void testDoubleTapRequired_ShadeLocked() {
-        FalsingManager.FalsingTapListener listener = getFalsingTapListener();
-        mStatusBarStateController.setState(SHADE_LOCKED);
-
-        listener.onAdditionalTapRequired();
-
-        verify(mTapAgainViewController).show();
-    }
-
-    @Test
     public void testRotatingToSplitShadeWithQsExpanded_transitionsToShadeLocked() {
         mStatusBarStateController.setState(KEYGUARD);
-        mNotificationPanelViewController.setQsExpanded(true);
+        when(mQsController.getExpanded()).thenReturn(true);
 
         enableSplitShade(true);
 
@@ -1136,24 +522,18 @@
     public void testUnlockedSplitShadeTransitioningToKeyguard_closesQS() {
         enableSplitShade(true);
         mStatusBarStateController.setState(SHADE);
-        mNotificationPanelViewController.setQsExpanded(true);
-
         mStatusBarStateController.setState(KEYGUARD);
 
-        assertThat(mNotificationPanelViewController.isQsExpanded()).isEqualTo(false);
-        assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isEqualTo(false);
+        verify(mQsController).closeQs();
     }
 
     @Test
     public void testLockedSplitShadeTransitioningToKeyguard_closesQS() {
         enableSplitShade(true);
         mStatusBarStateController.setState(SHADE_LOCKED);
-        mNotificationPanelViewController.setQsExpanded(true);
-
         mStatusBarStateController.setState(KEYGUARD);
 
-        assertThat(mNotificationPanelViewController.isQsExpanded()).isEqualTo(false);
-        assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isEqualTo(false);
+        verify(mQsController).closeQs();
     }
 
     @Test
@@ -1165,7 +545,7 @@
         verify(mKeyguardStatusViewController).displayClock(LARGE, /* animate */ true);
 
         when(mNotificationStackScrollLayoutController.getVisibleNotificationCount()).thenReturn(1);
-        mNotificationPanelViewController.closeQs();
+        triggerPositionClockAndNotifications();
         verify(mKeyguardStatusViewController).displayClock(SMALL, /* animate */ true);
     }
 
@@ -1293,18 +673,6 @@
     }
 
     @Test
-    public void testLargeScreenHeaderMadeActiveForLargeScreen() {
-        mStatusBarStateController.setState(SHADE);
-        when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(true);
-        mNotificationPanelViewController.updateResources();
-        verify(mLargeScreenShadeHeaderController).setLargeScreenActive(true);
-
-        when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(false);
-        mNotificationPanelViewController.updateResources();
-        verify(mLargeScreenShadeHeaderController).setLargeScreenActive(false);
-    }
-
-    @Test
     public void testExpandWithQsMethodIsUsingLockscreenTransitionController() {
         enableSplitShade(/* enabled= */ true);
         mStatusBarStateController.setState(KEYGUARD);
@@ -1358,12 +726,14 @@
     @Test
     public void testQsToBeImmediatelyExpandedWhenOpeningPanelInSplitShade() {
         enableSplitShade(/* enabled= */ true);
+        mShadeExpansionStateManager.updateState(STATE_OPEN);
+        verify(mQsController).setExpandImmediate(false);
+
         mShadeExpansionStateManager.updateState(STATE_CLOSED);
-        assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isFalse();
+        verify(mQsController, times(2)).setExpandImmediate(false);
 
         mShadeExpansionStateManager.updateState(STATE_OPENING);
-
-        assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isTrue();
+        verify(mQsController).setExpandImmediate(true);
     }
 
     @Test
@@ -1375,33 +745,28 @@
         // going to lockscreen would trigger STATE_OPENING
         mShadeExpansionStateManager.updateState(STATE_OPENING);
 
-        assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isFalse();
+        verify(mQsController, never()).setExpandImmediate(true);
     }
 
     @Test
     public void testQsImmediateResetsWhenPanelOpensOrCloses() {
-        mNotificationPanelViewController.setQsExpandImmediate(true);
         mShadeExpansionStateManager.updateState(STATE_OPEN);
-        assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isFalse();
-
-        mNotificationPanelViewController.setQsExpandImmediate(true);
         mShadeExpansionStateManager.updateState(STATE_CLOSED);
-        assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isFalse();
+        verify(mQsController, times(2)).setExpandImmediate(false);
     }
 
     @Test
     public void testQsExpansionChangedToDefaultWhenRotatingFromOrToSplitShade() {
         // to make sure shade is in expanded state
         mNotificationPanelViewController.startWaitingForOpenPanelGesture();
-        assertThat(mNotificationPanelViewController.isQsExpanded()).isFalse();
 
         // switch to split shade from portrait (default state)
         enableSplitShade(/* enabled= */ true);
-        assertThat(mNotificationPanelViewController.isQsExpanded()).isTrue();
+        verify(mQsController).setExpanded(true);
 
         // switch to portrait from split shade
         enableSplitShade(/* enabled= */ false);
-        assertThat(mNotificationPanelViewController.isQsExpanded()).isFalse();
+        verify(mQsController).setExpanded(false);
     }
 
     @Test
@@ -1413,73 +778,11 @@
 
         assertThat(mNotificationPanelViewController.isClosing()).isFalse();
         mNotificationPanelViewController.animateCloseQs(false);
+
         assertThat(mNotificationPanelViewController.isClosing()).isTrue();
     }
 
     @Test
-    public void testPanelStaysOpenWhenClosingQs() {
-        mShadeExpansionStateManager.onPanelExpansionChanged(/* fraction= */ 1,
-                /* expanded= */ true, /* tracking= */ false, /* dragDownPxAmount= */ 0);
-        mNotificationPanelViewController.setExpandedFraction(1f);
-
-        assertThat(mNotificationPanelViewController.isClosing()).isFalse();
-        mNotificationPanelViewController.animateCloseQs(false);
-        assertThat(mNotificationPanelViewController.isClosing()).isFalse();
-    }
-
-    @Test
-    public void interceptTouchEvent_withinQs_shadeExpanded_startsQsTracking() {
-        mNotificationPanelViewController.setQs(mQs);
-        when(mQsFrame.getX()).thenReturn(0f);
-        when(mQsFrame.getWidth()).thenReturn(1000);
-        when(mQsHeader.getTop()).thenReturn(0);
-        when(mQsHeader.getBottom()).thenReturn(1000);
-        NotificationPanelViewController.TouchHandler touchHandler =
-                mNotificationPanelViewController.createTouchHandler();
-
-        mNotificationPanelViewController.setExpandedFraction(1f);
-        touchHandler.onInterceptTouchEvent(
-                createMotionEvent(/* x= */ 0, /* y= */ 0, MotionEvent.ACTION_DOWN));
-        touchHandler.onInterceptTouchEvent(
-                createMotionEvent(/* x= */ 0, /* y= */ 500, MotionEvent.ACTION_MOVE));
-
-        assertThat(mNotificationPanelViewController.isQsTracking()).isTrue();
-    }
-
-    @Test
-    public void interceptTouchEvent_withinQs_shadeExpanded_inSplitShade_doesNotStartQsTracking() {
-        enableSplitShade(true);
-        mNotificationPanelViewController.setQs(mQs);
-        when(mQsFrame.getX()).thenReturn(0f);
-        when(mQsFrame.getWidth()).thenReturn(1000);
-        when(mQsHeader.getTop()).thenReturn(0);
-        when(mQsHeader.getBottom()).thenReturn(1000);
-        NotificationPanelViewController.TouchHandler touchHandler =
-                mNotificationPanelViewController.createTouchHandler();
-
-        mNotificationPanelViewController.setExpandedFraction(1f);
-        touchHandler.onInterceptTouchEvent(
-                createMotionEvent(/* x= */ 0, /* y= */ 0, MotionEvent.ACTION_DOWN));
-        touchHandler.onInterceptTouchEvent(
-                createMotionEvent(/* x= */ 0, /* y= */ 500, MotionEvent.ACTION_MOVE));
-
-        assertThat(mNotificationPanelViewController.isQsTracking()).isFalse();
-    }
-
-    @Test
-    public void testOnAttachRefreshStatusBarState() {
-        mStatusBarStateController.setState(KEYGUARD);
-        when(mKeyguardStateController.isKeyguardFadingAway()).thenReturn(false);
-        for (View.OnAttachStateChangeListener listener : mOnAttachStateChangeListeners) {
-            listener.onViewAttachedToWindow(mView);
-        }
-        verify(mKeyguardStatusViewController).setKeyguardStatusViewVisibility(
-                KEYGUARD/*statusBarState*/,
-                false/*keyguardFadingAway*/,
-                false/*goingToFullShade*/, SHADE/*oldStatusBarState*/);
-    }
-
-    @Test
     public void getMaxPanelTransitionDistance_expanding_inSplitShade_returnsSplitShadeFullTransitionDistance() {
         enableSplitShade(true);
         mNotificationPanelViewController.expandWithQs();
@@ -1494,11 +797,14 @@
         enableSplitShade(true);
         mNotificationPanelViewController.expandWithQs();
         when(mHeadsUpManager.isTrackingHeadsUp()).thenReturn(true);
+        when(mQsController.calculatePanelHeightExpanded(anyInt())).thenReturn(10000);
         mNotificationPanelViewController.setHeadsUpDraggingStartingHeight(
                 SPLIT_SHADE_FULL_TRANSITION_DISTANCE);
 
         int maxDistance = mNotificationPanelViewController.getMaxPanelTransitionDistance();
 
+        // make sure we're ignoring the placeholder value for Qs max height
+        assertThat(maxDistance).isLessThan(10000);
         assertThat(maxDistance).isGreaterThan(SPLIT_SHADE_FULL_TRANSITION_DISTANCE);
     }
 
@@ -1525,95 +831,26 @@
 
     @Test
     public void onLayoutChange_fullWidth_updatesQSWithFullWithTrue() {
-        mNotificationPanelViewController.setQs(mQs);
-
         setIsFullWidth(true);
 
-        verify(mQs).setIsNotificationPanelFullWidth(true);
+        verify(mQsController).setNotificationPanelFullWidth(true);
     }
 
     @Test
     public void onLayoutChange_notFullWidth_updatesQSWithFullWithFalse() {
-        mNotificationPanelViewController.setQs(mQs);
-
         setIsFullWidth(false);
 
-        verify(mQs).setIsNotificationPanelFullWidth(false);
+        verify(mQsController).setNotificationPanelFullWidth(false);
     }
 
     @Test
     public void onLayoutChange_qsNotSet_doesNotCrash() {
-        mNotificationPanelViewController.setQs(null);
+        mQuickSettingsController.setQs(null);
 
         triggerLayoutChange();
     }
 
     @Test
-    public void onQsFragmentAttached_fullWidth_setsFullWidthTrueOnQS() {
-        setIsFullWidth(true);
-        givenViewAttached();
-        mFragmentListener.onFragmentViewCreated(QS.TAG, mQSFragment);
-
-        verify(mQSFragment).setIsNotificationPanelFullWidth(true);
-    }
-
-    @Test
-    public void onQsFragmentAttached_notFullWidth_setsFullWidthFalseOnQS() {
-        setIsFullWidth(false);
-        givenViewAttached();
-        mFragmentListener.onFragmentViewCreated(QS.TAG, mQSFragment);
-
-        verify(mQSFragment).setIsNotificationPanelFullWidth(false);
-    }
-
-    @Test
-    public void setQsExpansion_lockscreenShadeTransitionInProgress_usesLockscreenSquishiness() {
-        float squishinessFraction = 0.456f;
-        mNotificationPanelViewController.setQs(mQs);
-        when(mLockscreenShadeTransitionController.getQsSquishTransitionFraction())
-                .thenReturn(squishinessFraction);
-        when(mNotificationStackScrollLayoutController.getNotificationSquishinessFraction())
-                .thenReturn(0.987f);
-        // Call setTransitionToFullShadeAmount to get into the full shade transition in progress
-        // state.
-        mNotificationPanelViewController.setTransitionToFullShadeAmount(
-                /* pxAmount= */ 234,
-                /* animate= */ false,
-                /* delay= */ 0
-        );
-
-        mNotificationPanelViewController.setQsExpansionHeight(/* height= */ 123);
-
-        // First for setTransitionToFullShadeAmount and then setQsExpansion
-        verify(mQs, times(2)).setQsExpansion(
-                /* expansion= */ anyFloat(),
-                /* panelExpansionFraction= */ anyFloat(),
-                /* proposedTranslation= */ anyFloat(),
-                eq(squishinessFraction)
-        );
-    }
-
-    @Test
-    public void setQsExpansion_lockscreenShadeTransitionNotInProgress_usesStandardSquishiness() {
-        float lsSquishinessFraction = 0.456f;
-        float nsslSquishinessFraction = 0.987f;
-        mNotificationPanelViewController.setQs(mQs);
-        when(mLockscreenShadeTransitionController.getQsSquishTransitionFraction())
-                .thenReturn(lsSquishinessFraction);
-        when(mNotificationStackScrollLayoutController.getNotificationSquishinessFraction())
-                .thenReturn(nsslSquishinessFraction);
-
-        mNotificationPanelViewController.setQsExpansionHeight(/* height= */ 123);
-
-        verify(mQs).setQsExpansion(
-                /* expansion= */ anyFloat(),
-                /* panelExpansionFraction= */ anyFloat(),
-                /* proposedTranslation= */ anyFloat(),
-                eq(nsslSquishinessFraction)
-        );
-    }
-
-    @Test
     public void onEmptySpaceClicked_notDozingAndOnKeyguard_requestsFaceAuth() {
         StatusBarStateController.StateListener statusBarStateListener =
                 mNotificationPanelViewController.getStatusBarStateListener();
@@ -1738,15 +975,6 @@
         int transitionDistance = mNotificationPanelViewController.getMaxPanelTransitionDistance();
         mNotificationPanelViewController.setExpandedHeight(transitionDistance);
         assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isFalse();
-
-        // set maxQsExpansion in NPVC
-        int maxQsExpansion = 123;
-        mNotificationPanelViewController.setQs(mQs);
-        when(mQs.getDesiredHeight()).thenReturn(maxQsExpansion);
-        triggerLayoutChange();
-
-        mNotificationPanelViewController.setQsExpansionHeight(maxQsExpansion);
-        assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isTrue();
     }
 
     @Test
@@ -1754,98 +982,4 @@
         mStatusBarStateController.setState(SHADE_LOCKED);
         assertThat(mNotificationPanelViewController.isShadeFullyOpen()).isTrue();
     }
-
-    private static MotionEvent createMotionEvent(int x, int y, int action) {
-        return MotionEvent.obtain(
-                /* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0);
-    }
-
-    private void triggerPositionClockAndNotifications() {
-        mNotificationPanelViewController.closeQs();
-    }
-
-    private FalsingManager.FalsingTapListener getFalsingTapListener() {
-        for (View.OnAttachStateChangeListener listener : mOnAttachStateChangeListeners) {
-            listener.onViewAttachedToWindow(mView);
-        }
-        assertThat(mFalsingManager.getTapListeners().size()).isEqualTo(1);
-        return mFalsingManager.getTapListeners().get(0);
-    }
-
-    private void givenViewAttached() {
-        for (View.OnAttachStateChangeListener listener : mOnAttachStateChangeListeners) {
-            listener.onViewAttachedToWindow(mView);
-        }
-    }
-
-    private ConstraintSet.Layout getConstraintSetLayout(@IdRes int id) {
-        ConstraintSet constraintSet = new ConstraintSet();
-        constraintSet.clone(mNotificationContainerParent);
-        return constraintSet.getConstraint(id).layout;
-    }
-
-    private void enableSplitShade(boolean enabled) {
-        when(mResources.getBoolean(R.bool.config_use_split_notification_shade)).thenReturn(enabled);
-        mNotificationPanelViewController.updateResources();
-    }
-
-    private void updateMultiUserSetting(boolean enabled) {
-        when(mResources.getBoolean(R.bool.qs_show_user_switcher_for_single_user)).thenReturn(false);
-        when(mUserManager.isUserSwitcherEnabled(false)).thenReturn(enabled);
-        final ArgumentCaptor<ContentObserver> observerCaptor =
-                ArgumentCaptor.forClass(ContentObserver.class);
-        verify(mContentResolver)
-                .registerContentObserver(any(), anyBoolean(), observerCaptor.capture());
-        observerCaptor.getValue().onChange(/* selfChange */ false);
-    }
-
-    private void updateSmallestScreenWidth(int smallestScreenWidthDp) {
-        Configuration configuration = new Configuration();
-        configuration.smallestScreenWidthDp = smallestScreenWidthDp;
-        mConfigurationController.onConfigurationChanged(configuration);
-    }
-
-    private void onTouchEvent(MotionEvent ev) {
-        mTouchHandler.onTouch(mView, ev);
-    }
-
-    private void setDozing(boolean dozing, boolean dozingAlwaysOn) {
-        when(mDozeParameters.getAlwaysOn()).thenReturn(dozingAlwaysOn);
-        mNotificationPanelViewController.setDozing(
-                /* dozing= */ dozing,
-                /* animate= */ false
-        );
-    }
-
-    private void assertKeyguardStatusViewCentered() {
-        mNotificationPanelViewController.updateResources();
-        assertThat(getConstraintSetLayout(R.id.keyguard_status_view).endToEnd).isAnyOf(
-                ConstraintSet.PARENT_ID, ConstraintSet.UNSET);
-    }
-
-    private void assertKeyguardStatusViewNotCentered() {
-        mNotificationPanelViewController.updateResources();
-        assertThat(getConstraintSetLayout(R.id.keyguard_status_view).endToEnd).isEqualTo(
-                R.id.qs_edge_guideline);
-    }
-
-    private void setIsFullWidth(boolean fullWidth) {
-        float nsslWidth = fullWidth ? PANEL_WIDTH : PANEL_WIDTH / 2f;
-        when(mNotificationStackScrollLayoutController.getWidth()).thenReturn(nsslWidth);
-        triggerLayoutChange();
-    }
-
-    private void triggerLayoutChange() {
-        mLayoutChangeListener.onLayoutChange(
-                mView,
-                /* left= */ 0,
-                /* top= */ 0,
-                /* right= */ 0,
-                /* bottom= */ 0,
-                /* oldLeft= */ 0,
-                /* oldTop= */ 0,
-                /* oldRight= */ 0,
-                /* oldBottom= */ 0
-        );
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
new file mode 100644
index 0000000..0c046e9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shade
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.View
+import android.view.ViewStub
+import androidx.test.filters.SmallTest
+import com.android.internal.util.CollectionUtils
+import com.android.keyguard.KeyguardClockSwitch.LARGE
+import com.android.systemui.R
+import com.android.systemui.statusbar.StatusBarState.KEYGUARD
+import com.android.systemui.statusbar.StatusBarState.SHADE
+import com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.cancelChildren
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.advanceUntilIdle
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Captor
+import org.mockito.Mockito.atLeastOnce
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class NotificationPanelViewControllerWithCoroutinesTest :
+    NotificationPanelViewControllerBaseTest() {
+
+    @Captor private lateinit var viewCaptor: ArgumentCaptor<View>
+
+    override fun getMainDispatcher() = Dispatchers.Main.immediate
+
+    @Test
+    fun testDisableUserSwitcherAfterEnabling_returnsViewStubToTheViewHierarchy() = runTest {
+        launch(Dispatchers.Main.immediate) { givenViewAttached() }
+        advanceUntilIdle()
+
+        whenever(mResources.getBoolean(com.android.internal.R.bool.config_keyguardUserSwitcher))
+            .thenReturn(true)
+        updateMultiUserSetting(true)
+        clearInvocations(mView)
+
+        updateMultiUserSetting(false)
+
+        verify(mView, atLeastOnce()).addView(viewCaptor.capture(), anyInt())
+        val userSwitcherStub =
+            CollectionUtils.find(
+                viewCaptor.getAllValues(),
+                { view -> view.getId() == R.id.keyguard_user_switcher_stub }
+            )
+        assertThat(userSwitcherStub).isNotNull()
+        assertThat(userSwitcherStub).isInstanceOf(ViewStub::class.java)
+    }
+
+    @Test
+    fun testChangeSmallestScreenWidthAndUserSwitchEnabled_inflatesUserSwitchView() = runTest {
+        launch(Dispatchers.Main.immediate) { givenViewAttached() }
+        advanceUntilIdle()
+
+        whenever(mView.findViewById<View>(R.id.keyguard_user_switcher_view)).thenReturn(null)
+        updateSmallestScreenWidth(300)
+        whenever(mResources.getBoolean(com.android.internal.R.bool.config_keyguardUserSwitcher))
+            .thenReturn(true)
+        whenever(mResources.getBoolean(R.bool.qs_show_user_switcher_for_single_user))
+            .thenReturn(false)
+        whenever(mUserManager.isUserSwitcherEnabled(false)).thenReturn(true)
+
+        updateSmallestScreenWidth(800)
+
+        verify(mUserSwitcherStubView).inflate()
+    }
+
+    @Test
+    fun testFinishInflate_userSwitcherDisabled_doNotInflateUserSwitchView_initClock() = runTest {
+        launch(Dispatchers.Main.immediate) { givenViewAttached() }
+        advanceUntilIdle()
+
+        whenever(mResources.getBoolean(com.android.internal.R.bool.config_keyguardUserSwitcher))
+            .thenReturn(true)
+        whenever(mResources.getBoolean(R.bool.qs_show_user_switcher_for_single_user))
+            .thenReturn(false)
+        whenever(mUserManager.isUserSwitcherEnabled(false /* showEvenIfNotActionable */))
+            .thenReturn(false)
+
+        mNotificationPanelViewController.onFinishInflate()
+
+        verify(mUserSwitcherStubView, never()).inflate()
+        verify(mKeyguardStatusViewController, times(3)).displayClock(LARGE, /* animate */ true)
+
+        coroutineContext.cancelChildren()
+    }
+
+    @Test
+    fun testReInflateViews_userSwitcherDisabled_doNotInflateUserSwitchView() = runTest {
+        launch(Dispatchers.Main.immediate) { givenViewAttached() }
+        advanceUntilIdle()
+
+        whenever(mResources.getBoolean(com.android.internal.R.bool.config_keyguardUserSwitcher))
+            .thenReturn(true)
+        whenever(mResources.getBoolean(R.bool.qs_show_user_switcher_for_single_user))
+            .thenReturn(false)
+        whenever(mUserManager.isUserSwitcherEnabled(false /* showEvenIfNotActionable */))
+            .thenReturn(false)
+
+        mNotificationPanelViewController.reInflateViews()
+
+        verify(mUserSwitcherStubView, never()).inflate()
+
+        coroutineContext.cancelChildren()
+    }
+
+    @Test
+    fun testDoubleTapRequired_Keyguard() = runTest {
+        launch(Dispatchers.Main.immediate) {
+            val listener = getFalsingTapListener()
+            mStatusBarStateController.setState(KEYGUARD)
+
+            listener.onAdditionalTapRequired()
+
+            verify(mKeyguardIndicationController).showTransientIndication(anyInt())
+        }
+        advanceUntilIdle()
+    }
+
+    @Test
+    fun testDoubleTapRequired_ShadeLocked() = runTest {
+        launch(Dispatchers.Main.immediate) {
+            val listener = getFalsingTapListener()
+            mStatusBarStateController.setState(SHADE_LOCKED)
+
+            listener.onAdditionalTapRequired()
+
+            verify(mTapAgainViewController).show()
+        }
+        advanceUntilIdle()
+    }
+
+    @Test
+    fun testOnAttachRefreshStatusBarState() = runTest {
+        launch(Dispatchers.Main.immediate) {
+            mStatusBarStateController.setState(KEYGUARD)
+            whenever(mKeyguardStateController.isKeyguardFadingAway()).thenReturn(false)
+            mOnAttachStateChangeListeners.forEach { it.onViewAttachedToWindow(mView) }
+            verify(mKeyguardStatusViewController)
+                .setKeyguardStatusViewVisibility(
+                    KEYGUARD /*statusBarState*/,
+                    false /*keyguardFadingAway*/,
+                    false /*goingToFullShade*/,
+                    SHADE /*oldStatusBarState*/
+                )
+        }
+        advanceUntilIdle()
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt
index c915502a..dfb1bce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt
@@ -12,7 +12,6 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.fragments.FragmentHostManager
 import com.android.systemui.fragments.FragmentService
 import com.android.systemui.navigationbar.NavigationModeController
@@ -40,8 +39,8 @@
 import org.mockito.Mockito.never
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -68,12 +67,10 @@
     @Mock
     private lateinit var notificationsQSContainer: NotificationsQuickSettingsContainer
     @Mock
-    private lateinit var largeScreenShadeHeaderController: LargeScreenShadeHeaderController
+    private lateinit var mShadeHeaderController: ShadeHeaderController
     @Mock
     private lateinit var shadeExpansionStateManager: ShadeExpansionStateManager
     @Mock
-    private lateinit var featureFlags: FeatureFlags
-    @Mock
     private lateinit var fragmentService: FragmentService
     @Mock
     private lateinit var fragmentHostManager: FragmentHostManager
@@ -109,9 +106,8 @@
                 notificationsQSContainer,
                 navigationModeController,
                 overviewProxyService,
-                largeScreenShadeHeaderController,
+                mShadeHeaderController,
                 shadeExpansionStateManager,
-                featureFlags,
                 fragmentService,
                 delayableExecutor
         )
@@ -396,9 +392,8 @@
                 container,
                 navigationModeController,
                 overviewProxyService,
-                largeScreenShadeHeaderController,
+                mShadeHeaderController,
                 shadeExpansionStateManager,
-                featureFlags,
                 fragmentService,
                 delayableExecutor
         )
@@ -429,16 +424,16 @@
     @Test
     fun testStartCustomizingWithDuration() {
         controller.setCustomizerShowing(true, 100L)
-        verify(largeScreenShadeHeaderController).startCustomizingAnimation(true, 100L)
+        verify(mShadeHeaderController).startCustomizingAnimation(true, 100L)
     }
 
     @Test
     fun testEndCustomizingWithDuration() {
         controller.setCustomizerShowing(true, 0L) // Only tracks changes
-        reset(largeScreenShadeHeaderController)
+        reset(mShadeHeaderController)
 
         controller.setCustomizerShowing(false, 100L)
-        verify(largeScreenShadeHeaderController).startCustomizingAnimation(false, 100L)
+        verify(mShadeHeaderController).startCustomizingAnimation(false, 100L)
     }
 
     @Test
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 e5d5e3b..0a401b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -21,17 +21,17 @@
 import android.view.MotionEvent
 import android.view.ViewGroup
 import androidx.test.filters.SmallTest
-import com.android.keyguard.KeyguardHostViewController
+import com.android.keyguard.KeyguardSecurityContainerController
 import com.android.keyguard.LockIconViewController
 import com.android.keyguard.dagger.KeyguardBouncerComponent
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollectorFake
 import com.android.systemui.dock.DockManager
-import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController
 import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
 import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
 import com.android.systemui.statusbar.LockscreenShadeTransitionController
@@ -47,6 +47,7 @@
 import com.android.systemui.statusbar.window.StatusBarWindowStateController
 import com.android.systemui.util.mockito.any
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.emptyFlow
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -81,8 +82,6 @@
     @Mock
     private lateinit var keyguardUnlockAnimationController: KeyguardUnlockAnimationController
     @Mock
-    private lateinit var featureFlags: FeatureFlags
-    @Mock
     private lateinit var ambientState: AmbientState
     @Mock
     private lateinit var keyguardBouncerViewModel: KeyguardBouncerViewModel
@@ -106,7 +105,7 @@
     private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
     @Mock lateinit var keyguardBouncerComponentFactory: KeyguardBouncerComponent.Factory
     @Mock lateinit var keyguardBouncerComponent: KeyguardBouncerComponent
-    @Mock lateinit var keyguardHostViewController: KeyguardHostViewController
+    @Mock lateinit var keyguardSecurityContainerController: KeyguardSecurityContainerController
     @Mock lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
 
     private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
@@ -122,8 +121,10 @@
                 .thenReturn(mock(ViewGroup::class.java))
         whenever(keyguardBouncerComponentFactory.create(any(ViewGroup::class.java)))
                 .thenReturn(keyguardBouncerComponent)
-        whenever(keyguardBouncerComponent.keyguardHostViewController)
-                .thenReturn(keyguardHostViewController)
+        whenever(keyguardBouncerComponent.securityContainerController)
+                .thenReturn(keyguardSecurityContainerController)
+        whenever(keyguardTransitionInteractor.lockscreenToDreamingTransition)
+                .thenReturn(emptyFlow<TransitionStep>())
         underTest = NotificationShadeWindowViewController(
             lockscreenShadeTransitionController,
             FalsingCollectorFake(),
@@ -143,7 +144,6 @@
             notificationInsetsController,
             ambientState,
             pulsingGestureListener,
-            featureFlags,
             keyguardBouncerViewModel,
             keyguardBouncerComponentFactory,
             alternateBouncerInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java
index 5cc3ef1..5d71979 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java
@@ -25,6 +25,8 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import static kotlinx.coroutines.flow.FlowKt.emptyFlow;
+
 import android.os.SystemClock;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -33,14 +35,13 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.keyguard.KeyguardHostViewController;
+import com.android.keyguard.KeyguardSecurityContainerController;
 import com.android.keyguard.LockIconViewController;
 import com.android.keyguard.dagger.KeyguardBouncerComponent;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingCollectorFake;
 import com.android.systemui.dock.DockManager;
-import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
@@ -93,11 +94,10 @@
     @Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
     @Mock private AmbientState mAmbientState;
     @Mock private PulsingGestureListener mPulsingGestureListener;
-    @Mock private FeatureFlags mFeatureFlags;
     @Mock private KeyguardBouncerViewModel mKeyguardBouncerViewModel;
     @Mock private KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
     @Mock private KeyguardBouncerComponent mKeyguardBouncerComponent;
-    @Mock private KeyguardHostViewController mKeyguardHostViewController;
+    @Mock private KeyguardSecurityContainerController mKeyguardSecurityContainerController;
     @Mock private NotificationInsetsController mNotificationInsetsController;
     @Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
     @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
@@ -117,14 +117,17 @@
         when(mView.findViewById(R.id.keyguard_bouncer_container)).thenReturn(mock(ViewGroup.class));
         when(mKeyguardBouncerComponentFactory.create(any(ViewGroup.class))).thenReturn(
                 mKeyguardBouncerComponent);
-        when(mKeyguardBouncerComponent.getKeyguardHostViewController()).thenReturn(
-                mKeyguardHostViewController);
+        when(mKeyguardBouncerComponent.getSecurityContainerController()).thenReturn(
+                mKeyguardSecurityContainerController);
 
         when(mStatusBarStateController.isDozing()).thenReturn(false);
         mDependency.injectTestDependency(ShadeController.class, mShadeController);
 
         when(mDockManager.isDocked()).thenReturn(false);
 
+        when(mKeyguardTransitionInteractor.getLockscreenToDreamingTransition())
+                .thenReturn(emptyFlow());
+
         mController = new NotificationShadeWindowViewController(
                 mLockscreenShadeTransitionController,
                 new FalsingCollectorFake(),
@@ -144,7 +147,6 @@
                 mNotificationInsetsController,
                 mAmbientState,
                 mPulsingGestureListener,
-                mFeatureFlags,
                 mKeyguardBouncerViewModel,
                 mKeyguardBouncerComponentFactory,
                 mAlternateBouncerInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
new file mode 100644
index 0000000..b547318
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
@@ -0,0 +1,100 @@
+package com.android.systemui.shade
+
+import android.content.Context
+import android.content.res.Resources
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.view.DisplayCutout
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.battery.BatteryMeterView
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnit
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class QsBatteryModeControllerTest : SysuiTestCase() {
+
+    private companion object {
+        val CENTER_TOP_CUTOUT: DisplayCutout =
+            mock<DisplayCutout>().also {
+                whenever(it.boundingRectTop).thenReturn(Rect(10, 0, 20, 10))
+            }
+
+        const val MOTION_LAYOUT_MAX_FRAME = 100
+        const val QQS_START_FRAME = 14
+        const val QS_END_FRAME = 58
+    }
+
+    @JvmField @Rule val mockitoRule = MockitoJUnit.rule()!!
+
+    @Mock private lateinit var insetsProvider: StatusBarContentInsetsProvider
+    @Mock private lateinit var mockedContext: Context
+    @Mock private lateinit var mockedResources: Resources
+
+    private lateinit var controller: QsBatteryModeController // under test
+
+    @Before
+    fun setup() {
+        whenever(mockedContext.resources).thenReturn(mockedResources)
+        whenever(mockedResources.getInteger(R.integer.fade_in_start_frame)).thenReturn(QS_END_FRAME)
+        whenever(mockedResources.getInteger(R.integer.fade_out_complete_frame))
+            .thenReturn(QQS_START_FRAME)
+
+        controller = QsBatteryModeController(mockedContext, insetsProvider)
+    }
+
+    @Test
+    fun `returns MODE_ON for qqs with center cutout`() {
+        assertThat(
+                controller.getBatteryMode(CENTER_TOP_CUTOUT, QQS_START_FRAME.prevFrameToFraction())
+            )
+            .isEqualTo(BatteryMeterView.MODE_ON)
+    }
+
+    @Test
+    fun `returns MODE_ESTIMATE for qs with center cutout`() {
+        assertThat(controller.getBatteryMode(CENTER_TOP_CUTOUT, QS_END_FRAME.nextFrameToFraction()))
+            .isEqualTo(BatteryMeterView.MODE_ESTIMATE)
+    }
+
+    @Test
+    fun `returns MODE_ON for qqs with corner cutout`() {
+        whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(true)
+
+        assertThat(
+                controller.getBatteryMode(CENTER_TOP_CUTOUT, QQS_START_FRAME.prevFrameToFraction())
+            )
+            .isEqualTo(BatteryMeterView.MODE_ESTIMATE)
+    }
+
+    @Test
+    fun `returns MODE_ESTIMATE for qs with corner cutout`() {
+        whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(true)
+
+        assertThat(controller.getBatteryMode(CENTER_TOP_CUTOUT, QS_END_FRAME.nextFrameToFraction()))
+            .isEqualTo(BatteryMeterView.MODE_ESTIMATE)
+    }
+
+    @Test
+    fun `returns null in-between`() {
+        assertThat(
+                controller.getBatteryMode(CENTER_TOP_CUTOUT, QQS_START_FRAME.nextFrameToFraction())
+            )
+            .isNull()
+        assertThat(controller.getBatteryMode(CENTER_TOP_CUTOUT, QS_END_FRAME.prevFrameToFraction()))
+            .isNull()
+    }
+
+    private fun Int.prevFrameToFraction(): Float = (this - 1) / MOTION_LAYOUT_MAX_FRAME.toFloat()
+    private fun Int.nextFrameToFraction(): Float = (this + 1) / MOTION_LAYOUT_MAX_FRAME.toFloat()
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
new file mode 100644
index 0000000..e3a3678
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
@@ -0,0 +1,565 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shade;
+
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_MOVE;
+import static android.view.MotionEvent.ACTION_POINTER_DOWN;
+import static android.view.MotionEvent.ACTION_UP;
+import static android.view.MotionEvent.BUTTON_SECONDARY;
+import static android.view.MotionEvent.BUTTON_STYLUS_PRIMARY;
+
+import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
+import static com.android.systemui.statusbar.StatusBarState.SHADE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.res.Resources;
+import android.os.Handler;
+import android.os.Looper;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.MotionEvent;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.view.accessibility.AccessibilityManager;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.keyguard.KeyguardStatusView;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.media.controls.pipeline.MediaDataManager;
+import com.android.systemui.media.controls.ui.MediaHierarchyManager;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.qs.QS;
+import com.android.systemui.qs.QSFragment;
+import com.android.systemui.screenrecord.RecordingController;
+import com.android.systemui.shade.transition.ShadeTransitionController;
+import com.android.systemui.statusbar.LockscreenShadeTransitionController;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationShadeDepthController;
+import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.QsFrameTranslateController;
+import com.android.systemui.statusbar.StatusBarStateControllerImpl;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.notification.stack.AmbientState;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
+import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
+import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import dagger.Lazy;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class QuickSettingsControllerTest extends SysuiTestCase {
+
+    private static final int SPLIT_SHADE_FULL_TRANSITION_DISTANCE = 400;
+    private static final float QS_FRAME_START_X = 0f;
+    private static final int QS_FRAME_WIDTH = 1000;
+    private static final int QS_FRAME_TOP = 0;
+    private static final int QS_FRAME_BOTTOM = 1000;
+
+
+    private QuickSettingsController mQsController;
+
+    @Mock private Resources mResources;
+    @Mock private KeyguardBottomAreaView mQsFrame;
+    @Mock private KeyguardStatusBarView mKeyguardStatusBar;
+    @Mock private QS mQs;
+    @Mock private QSFragment mQSFragment;
+
+    @Mock private Lazy<NotificationPanelViewController> mPanelViewControllerLazy;
+    @Mock private NotificationPanelViewController mNotificationPanelViewController;
+    @Mock private NotificationPanelView mPanelView;
+    @Mock private ViewGroup mQsHeader;
+    @Mock private ViewParent mPanelViewParent;
+    @Mock private QsFrameTranslateController mQsFrameTranslateController;
+    @Mock private ShadeTransitionController mShadeTransitionController;
+    @Mock private PulseExpansionHandler mPulseExpansionHandler;
+    @Mock private NotificationRemoteInputManager mNotificationRemoteInputManager;
+    @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    @Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
+    @Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
+    @Mock private NotificationShadeDepthController mNotificationShadeDepthController;
+    @Mock private ShadeHeaderController mShadeHeaderController;
+    @Mock private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+    @Mock private KeyguardStateController mKeyguardStateController;
+    @Mock private KeyguardBypassController mKeyguardBypassController;
+    @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    @Mock private ScrimController mScrimController;
+    @Mock private MediaDataManager mMediaDataManager;
+    @Mock private MediaHierarchyManager mMediaHierarchyManager;
+    @Mock private AmbientState mAmbientState;
+    @Mock private RecordingController mRecordingController;
+    @Mock private FalsingManager mFalsingManager;
+    @Mock private FalsingCollector mFalsingCollector;
+    @Mock private AccessibilityManager mAccessibilityManager;
+    @Mock private LockscreenGestureLogger mLockscreenGestureLogger;
+    @Mock private MetricsLogger mMetricsLogger;
+    @Mock private FeatureFlags mFeatureFlags;
+    @Mock private InteractionJankMonitor mInteractionJankMonitor;
+    @Mock private ShadeLogger mShadeLogger;
+
+    @Mock private DumpManager mDumpManager;
+
+    @Mock private HeadsUpManagerPhone mHeadsUpManager;
+    @Mock private UiEventLogger mUiEventLogger;
+
+    private SysuiStatusBarStateController mStatusBarStateController;
+
+    private Handler mMainHandler;
+    private LockscreenShadeTransitionController.Callback mLockscreenShadeTransitionCallback;
+
+    private final ShadeExpansionStateManager mShadeExpansionStateManager =
+            new ShadeExpansionStateManager();
+
+    private FragmentHostManager.FragmentListener mFragmentListener;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        when(mPanelViewControllerLazy.get()).thenReturn(mNotificationPanelViewController);
+        mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
+                mInteractionJankMonitor, mShadeExpansionStateManager);
+
+        KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext);
+        keyguardStatusView.setId(R.id.keyguard_status_view);
+
+        when(mPanelView.getResources()).thenReturn(mResources);
+        when(mPanelView.getContext()).thenReturn(getContext());
+        when(mPanelView.findViewById(R.id.keyguard_header)).thenReturn(mKeyguardStatusBar);
+        when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(1000);
+        when(mPanelView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame);
+        when(mQsFrame.getX()).thenReturn(QS_FRAME_START_X);
+        when(mQsFrame.getWidth()).thenReturn(QS_FRAME_WIDTH);
+        when(mQsHeader.getTop()).thenReturn(QS_FRAME_TOP);
+        when(mQsHeader.getBottom()).thenReturn(QS_FRAME_BOTTOM);
+        when(mPanelView.getY()).thenReturn((float) QS_FRAME_TOP);
+        when(mPanelView.getHeight()).thenReturn(QS_FRAME_BOTTOM);
+        when(mPanelView.findViewById(R.id.keyguard_status_view))
+                .thenReturn(mock(KeyguardStatusView.class));
+        when(mQs.getView()).thenReturn(mPanelView);
+        when(mQSFragment.getView()).thenReturn(mPanelView);
+
+        when(mNotificationRemoteInputManager.isRemoteInputActive())
+                .thenReturn(false);
+        when(mInteractionJankMonitor.begin(any(), anyInt()))
+                .thenReturn(true);
+        when(mInteractionJankMonitor.end(anyInt()))
+                .thenReturn(true);
+
+        when(mPanelView.getParent()).thenReturn(mPanelViewParent);
+        when(mQs.getHeader()).thenReturn(mQsHeader);
+
+        doAnswer(invocation -> {
+            mLockscreenShadeTransitionCallback = invocation.getArgument(0);
+            return null;
+        }).when(mLockscreenShadeTransitionController).addCallback(any());
+
+
+        mMainHandler = new Handler(Looper.getMainLooper());
+
+        mQsController = new QuickSettingsController(
+                mPanelViewControllerLazy,
+                mPanelView,
+                mQsFrameTranslateController,
+                mShadeTransitionController,
+                mPulseExpansionHandler,
+                mNotificationRemoteInputManager,
+                mShadeExpansionStateManager,
+                mStatusBarKeyguardViewManager,
+                mNotificationStackScrollLayoutController,
+                mLockscreenShadeTransitionController,
+                mNotificationShadeDepthController,
+                mShadeHeaderController,
+                mStatusBarTouchableRegionManager,
+                mKeyguardStateController,
+                mKeyguardBypassController,
+                mKeyguardUpdateMonitor,
+                mScrimController,
+                mMediaDataManager,
+                mMediaHierarchyManager,
+                mAmbientState,
+                mRecordingController,
+                mFalsingManager,
+                mFalsingCollector,
+                mAccessibilityManager,
+                mLockscreenGestureLogger,
+                mMetricsLogger,
+                mFeatureFlags,
+                mInteractionJankMonitor,
+                mShadeLogger
+        );
+
+        mFragmentListener = mQsController.getQsFragmentListener();
+    }
+
+    @After
+    public void tearDown() {
+        mMainHandler.removeCallbacksAndMessages(null);
+    }
+
+    @Test
+    public void testCloseQsSideEffects() {
+        enableSplitShade(true);
+        mQsController.setExpandImmediate(true);
+        mQsController.setExpanded(true);
+        mQsController.closeQs();
+
+        assertThat(mQsController.getExpanded()).isEqualTo(false);
+        assertThat(mQsController.isExpandImmediate()).isEqualTo(false);
+    }
+
+    @Test
+    public void testLargeScreenHeaderMadeActiveForLargeScreen() {
+        mStatusBarStateController.setState(SHADE);
+        when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(true);
+        mQsController.updateResources();
+        verify(mShadeHeaderController).setLargeScreenActive(true);
+
+        when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(false);
+        mQsController.updateResources();
+        verify(mShadeHeaderController).setLargeScreenActive(false);
+    }
+
+    @Test
+    public void testPanelStaysOpenWhenClosingQs() {
+        mShadeExpansionStateManager.onPanelExpansionChanged(/* fraction= */ 1,
+                /* expanded= */ true, /* tracking= */ false, /* dragDownPxAmount= */ 0);
+        mQsController.setShadeExpandedHeight(1);
+
+        float shadeExpandedHeight = mQsController.getShadeExpandedHeight();
+        mQsController.animateCloseQs(false);
+
+        assertThat(mQsController.getShadeExpandedHeight()).isEqualTo(shadeExpandedHeight);
+    }
+
+    @Test
+    public void interceptTouchEvent_withinQs_shadeExpanded_startsQsTracking() {
+        mQsController.setQs(mQs);
+
+        mQsController.setShadeExpandedHeight(1f);
+        mQsController.onIntercept(
+                createMotionEvent(0, 0, ACTION_DOWN));
+        mQsController.onIntercept(
+                createMotionEvent(0, 500, ACTION_MOVE));
+
+        assertThat(mQsController.isTracking()).isTrue();
+    }
+
+    @Test
+    public void interceptTouchEvent_withinQs_shadeExpanded_inSplitShade_doesNotStartQsTracking() {
+        enableSplitShade(true);
+        mQsController.setQs(mQs);
+
+        mQsController.setShadeExpandedHeight(1f);
+        mQsController.onIntercept(
+                createMotionEvent(0, 0, ACTION_DOWN));
+        mQsController.onIntercept(
+                createMotionEvent(0, 500, ACTION_MOVE));
+
+        assertThat(mQsController.isTracking()).isFalse();
+    }
+
+    @Test
+    public void interceptTouch_downBetweenFullyCollapsedAndExpanded() {
+        mQsController.setQs(mQs);
+        when(mQs.getDesiredHeight()).thenReturn(QS_FRAME_BOTTOM);
+        mQsController.onHeightChanged();
+        mQsController.setExpansionHeight(QS_FRAME_BOTTOM / 2f);
+
+        assertThat(mQsController.onIntercept(
+                createMotionEvent(0, QS_FRAME_BOTTOM / 2, ACTION_DOWN))).isTrue();
+    }
+
+    @Test
+    public void onTouch_moveActionSetsCorrectExpansionHeight() {
+        mQsController.setQs(mQs);
+        when(mQs.getDesiredHeight()).thenReturn(QS_FRAME_BOTTOM);
+        mQsController.onHeightChanged();
+        mQsController.setExpansionHeight(QS_FRAME_BOTTOM / 2f);
+        mQsController.handleTouch(
+                createMotionEvent(0, QS_FRAME_BOTTOM / 4, ACTION_DOWN), false, false);
+        assertThat(mQsController.isTracking()).isTrue();
+        mQsController.handleTouch(
+                createMotionEvent(0, QS_FRAME_BOTTOM / 4 + 1, ACTION_MOVE), false, false);
+
+        assertThat(mQsController.getExpansionHeight()).isEqualTo(QS_FRAME_BOTTOM / 2 + 1);
+    }
+
+    @Test
+    public void handleTouch_downActionInQsArea() {
+        mQsController.setQs(mQs);
+        mQsController.setBarState(SHADE);
+        mQsController.onPanelExpansionChanged(
+                new ShadeExpansionChangeEvent(
+                        0.5f,
+                        true,
+                        true,
+                        0
+                ));
+        MotionEvent event =
+                createMotionEvent(QS_FRAME_WIDTH / 2, QS_FRAME_BOTTOM / 2, ACTION_DOWN);
+        mQsController.handleTouch(event, false, false);
+
+        assertThat(mQsController.isTracking()).isTrue();
+        assertThat(mQsController.getInitialTouchY()).isEqualTo(QS_FRAME_BOTTOM / 2);
+    }
+
+    @Test
+    public void handleTouch_qsTouchedWhileCollapsingDisablesTracking() {
+        mQsController.handleTouch(
+                createMotionEvent(0, QS_FRAME_BOTTOM, ACTION_DOWN), false, false);
+        mQsController.setLastShadeFlingWasExpanding(false);
+        mQsController.handleTouch(
+                createMotionEvent(0, QS_FRAME_BOTTOM / 2, ACTION_MOVE), false, true);
+        MotionEvent secondTouch = createMotionEvent(0, QS_FRAME_TOP, ACTION_DOWN);
+        mQsController.handleTouch(secondTouch, false, true);
+        assertThat(mQsController.isTracking()).isFalse();
+    }
+
+    @Test
+    public void handleTouch_qsTouchedWhileExpanding() {
+        mQsController.setQs(mQs);
+        mQsController.handleTouch(
+                createMotionEvent(100, 100, ACTION_DOWN), false, false);
+        mQsController.handleTouch(
+                createMotionEvent(0, QS_FRAME_BOTTOM / 2, ACTION_MOVE), false, false);
+        mQsController.setLastShadeFlingWasExpanding(true);
+        mQsController.handleTouch(
+                createMotionEvent(0, QS_FRAME_TOP, ACTION_DOWN), false, false);
+        assertThat(mQsController.isTracking()).isTrue();
+    }
+
+    @Test
+    public void handleTouch_isConflictingExpansionGestureSet() {
+        assertThat(mQsController.isConflictingExpansionGesture()).isFalse();
+        mShadeExpansionStateManager.onPanelExpansionChanged(1f, true, false, 0f);
+        mQsController.handleTouch(MotionEvent.obtain(0L /* downTime */,
+                0L /* eventTime */, ACTION_DOWN, 0f /* x */, 0f /* y */,
+                0 /* metaState */), false, false);
+        assertThat(mQsController.isConflictingExpansionGesture()).isTrue();
+    }
+
+    @Test
+    public void handleTouch_isConflictingExpansionGestureSet_cancel() {
+        mShadeExpansionStateManager.onPanelExpansionChanged(1f, true, false, 0f);
+        mQsController.handleTouch(createMotionEvent(0, 0, ACTION_DOWN), false, false);
+        assertThat(mQsController.isConflictingExpansionGesture()).isTrue();
+        mQsController.handleTouch(createMotionEvent(0, 0, ACTION_UP), true, true);
+        assertThat(mQsController.isConflictingExpansionGesture()).isFalse();
+    }
+
+    @Test
+    public void handleTouch_twoFingerExpandPossibleConditions() {
+        assertThat(mQsController.isTwoFingerExpandPossible()).isFalse();
+        mQsController.handleTouch(createMotionEvent(0, 0, ACTION_DOWN), true, false);
+        assertThat(mQsController.isTwoFingerExpandPossible()).isTrue();
+    }
+
+    @Test
+    public void handleTouch_twoFingerDrag() {
+        mQsController.setQs(mQs);
+        mQsController.setStatusBarMinHeight(1);
+        mQsController.setTwoFingerExpandPossible(true);
+        mQsController.handleTouch(
+                createMultitouchMotionEvent(ACTION_POINTER_DOWN), false, false);
+        assertThat(mQsController.isExpandImmediate()).isTrue();
+        verify(mQs).setListening(true);
+    }
+
+    @Test
+    public void onQsFragmentAttached_fullWidth_setsFullWidthTrueOnQS() {
+        setIsFullWidth(true);
+        mFragmentListener.onFragmentViewCreated(QS.TAG, mQSFragment);
+
+        verify(mQSFragment).setIsNotificationPanelFullWidth(true);
+    }
+
+    @Test
+    public void onQsFragmentAttached_notFullWidth_setsFullWidthFalseOnQS() {
+        setIsFullWidth(false);
+        mFragmentListener.onFragmentViewCreated(QS.TAG, mQSFragment);
+
+        verify(mQSFragment).setIsNotificationPanelFullWidth(false);
+    }
+
+    @Test
+    public void setQsExpansion_lockscreenShadeTransitionInProgress_usesLockscreenSquishiness() {
+        float squishinessFraction = 0.456f;
+        mQsController.setQs(mQs);
+        when(mLockscreenShadeTransitionController.getQsSquishTransitionFraction())
+                .thenReturn(squishinessFraction);
+        when(mNotificationStackScrollLayoutController.getNotificationSquishinessFraction())
+                .thenReturn(0.987f);
+        // Call setTransitionToFullShadeAmount to get into the full shade transition in progress
+        // state.
+        mLockscreenShadeTransitionCallback.setTransitionToFullShadeAmount(234, false, 0);
+
+        mQsController.setExpansionHeight(123);
+
+        // First for setTransitionToFullShadeAmount and then setQsExpansion
+        verify(mQs, times(2)).setQsExpansion(anyFloat(), anyFloat(), anyFloat(),
+                eq(squishinessFraction)
+        );
+    }
+
+    @Test
+    public void setQsExpansion_lockscreenShadeTransitionNotInProgress_usesStandardSquishiness() {
+        float lsSquishinessFraction = 0.456f;
+        float nsslSquishinessFraction = 0.987f;
+        mQsController.setQs(mQs);
+        when(mLockscreenShadeTransitionController.getQsSquishTransitionFraction())
+                .thenReturn(lsSquishinessFraction);
+        when(mNotificationStackScrollLayoutController.getNotificationSquishinessFraction())
+                .thenReturn(nsslSquishinessFraction);
+
+        mQsController.setExpansionHeight(123);
+
+        verify(mQs).setQsExpansion(anyFloat(), anyFloat(), anyFloat(), eq(nsslSquishinessFraction)
+        );
+    }
+
+    @Test
+    public void updateExpansion_expandImmediateOrAlreadyExpanded_usesFullSquishiness() {
+        mQsController.setQs(mQs);
+        when(mQs.getDesiredHeight()).thenReturn(100);
+        mQsController.onHeightChanged();
+
+        mQsController.setExpandImmediate(true);
+        mQsController.setExpanded(false);
+        mQsController.updateExpansion();
+        mQsController.setExpandImmediate(false);
+        mQsController.setExpanded(true);
+        mQsController.updateExpansion();
+        verify(mQs, times(2)).setQsExpansion(0, 0, 0, 1);
+    }
+
+    @Test
+    public void shadeExpanded_onKeyguard() {
+        mStatusBarStateController.setState(KEYGUARD);
+        // set maxQsExpansion in NPVC
+        int maxQsExpansion = 123;
+        mQsController.setQs(mQs);
+        when(mQs.getDesiredHeight()).thenReturn(maxQsExpansion);
+
+        int oldMaxHeight = mQsController.updateHeightsOnShadeLayoutChange();
+        mQsController.handleShadeLayoutChanged(oldMaxHeight);
+
+        mQsController.setExpansionHeight(maxQsExpansion);
+        assertThat(mQsController.computeExpansionFraction()).isEqualTo(1f);
+    }
+
+    @Test
+    public void handleTouch_splitShadeAndtouchXOutsideQs() {
+        enableSplitShade(true);
+
+        assertThat(mQsController.handleTouch(createMotionEvent(
+                        QS_FRAME_WIDTH + 1, QS_FRAME_BOTTOM - 1, ACTION_DOWN),
+                false, false)).isFalse();
+    }
+
+    @Test
+    public void isOpenQsEvent_twoFingerDrag() {
+        assertThat(mQsController.isOpenQsEvent(
+                createMultitouchMotionEvent(ACTION_POINTER_DOWN))).isTrue();
+    }
+
+    @Test
+    public void isOpenQsEvent_stylusButtonClickDrag() {
+        MotionEvent event = createMotionEvent(0, 0, ACTION_DOWN);
+        event.setButtonState(BUTTON_STYLUS_PRIMARY);
+
+        assertThat(mQsController.isOpenQsEvent(event)).isTrue();
+    }
+
+    @Test
+    public void isOpenQsEvent_mouseButtonClickDrag() {
+        MotionEvent event = createMotionEvent(0, 0, ACTION_DOWN);
+        event.setButtonState(BUTTON_SECONDARY);
+
+        assertThat(mQsController.isOpenQsEvent(event)).isTrue();
+    }
+
+    private static MotionEvent createMotionEvent(int x, int y, int action) {
+        return MotionEvent.obtain(0, 0, action, x, y, 0);
+    }
+
+    // Creates an empty multitouch event for now
+    private static MotionEvent createMultitouchMotionEvent(int action) {
+        return MotionEvent.obtain(0, 0, action, 2,
+                new MotionEvent.PointerProperties[] {
+                        new MotionEvent.PointerProperties(),
+                        new MotionEvent.PointerProperties()
+                },
+                new MotionEvent.PointerCoords[] {
+                        new MotionEvent.PointerCoords(),
+                        new MotionEvent.PointerCoords()
+                }, 0, 0, 0, 0, 0, 0, 0, 0);
+    }
+
+    private void enableSplitShade(boolean enabled) {
+        when(mResources.getBoolean(R.bool.config_use_split_notification_shade)).thenReturn(enabled);
+        mQsController.updateResources();
+    }
+
+    private void setIsFullWidth(boolean fullWidth) {
+        mQsController.setNotificationPanelFullWidth(fullWidth);
+        triggerLayoutChange();
+    }
+
+    private void triggerLayoutChange() {
+        int oldMaxHeight = mQsController.updateHeightsOnShadeLayoutChange();
+        mQsController.handleShadeLayoutChanged(oldMaxHeight);
+    }
+
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt
new file mode 100644
index 0000000..d530829
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt
@@ -0,0 +1,933 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.shade
+
+import android.animation.Animator
+import android.app.StatusBarManager
+import android.content.Context
+import android.content.res.Resources
+import android.content.res.XmlResourceParser
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.view.Display
+import android.view.DisplayCutout
+import android.view.View
+import android.view.ViewPropertyAnimator
+import android.view.WindowInsets
+import android.widget.TextView
+import androidx.constraintlayout.motion.widget.MotionLayout
+import androidx.constraintlayout.widget.ConstraintSet
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.Interpolators
+import com.android.systemui.animation.ShadeInterpolation
+import com.android.systemui.battery.BatteryMeterView
+import com.android.systemui.battery.BatteryMeterViewController
+import com.android.systemui.demomode.DemoMode
+import com.android.systemui.demomode.DemoModeController
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.qs.ChipVisibilityListener
+import com.android.systemui.qs.HeaderPrivacyIconsController
+import com.android.systemui.qs.carrier.QSCarrierGroup
+import com.android.systemui.qs.carrier.QSCarrierGroupController
+import com.android.systemui.shade.ShadeHeaderController.Companion.LARGE_SCREEN_HEADER_CONSTRAINT
+import com.android.systemui.shade.ShadeHeaderController.Companion.QQS_HEADER_CONSTRAINT
+import com.android.systemui.shade.ShadeHeaderController.Companion.QS_HEADER_CONSTRAINT
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
+import com.android.systemui.statusbar.phone.StatusBarIconController
+import com.android.systemui.statusbar.phone.StatusIconContainer
+import com.android.systemui.statusbar.policy.Clock
+import com.android.systemui.statusbar.policy.FakeConfigurationController
+import com.android.systemui.statusbar.policy.VariableDateView
+import com.android.systemui.statusbar.policy.VariableDateViewController
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Answers
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.anyFloat
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.junit.MockitoJUnit
+
+private val EMPTY_CHANGES = ConstraintsChanges()
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class ShadeHeaderControllerTest : SysuiTestCase() {
+
+    @Mock(answer = Answers.RETURNS_MOCKS) private lateinit var view: MotionLayout
+    @Mock private lateinit var statusIcons: StatusIconContainer
+    @Mock private lateinit var statusBarIconController: StatusBarIconController
+    @Mock private lateinit var iconManagerFactory: StatusBarIconController.TintedIconManager.Factory
+    @Mock private lateinit var iconManager: StatusBarIconController.TintedIconManager
+    @Mock private lateinit var qsCarrierGroupController: QSCarrierGroupController
+    @Mock private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder
+    @Mock private lateinit var clock: Clock
+    @Mock private lateinit var date: VariableDateView
+    @Mock private lateinit var carrierGroup: QSCarrierGroup
+    @Mock private lateinit var batteryMeterView: BatteryMeterView
+    @Mock private lateinit var batteryMeterViewController: BatteryMeterViewController
+    @Mock private lateinit var privacyIconsController: HeaderPrivacyIconsController
+    @Mock private lateinit var insetsProvider: StatusBarContentInsetsProvider
+    @Mock private lateinit var variableDateViewControllerFactory: VariableDateViewController.Factory
+    @Mock private lateinit var variableDateViewController: VariableDateViewController
+    @Mock private lateinit var dumpManager: DumpManager
+    @Mock
+    private lateinit var combinedShadeHeadersConstraintManager:
+        CombinedShadeHeadersConstraintManager
+
+    @Mock private lateinit var mockedContext: Context
+    private lateinit var viewContext: Context
+
+    @Mock private lateinit var qqsConstraints: ConstraintSet
+    @Mock private lateinit var qsConstraints: ConstraintSet
+    @Mock private lateinit var largeScreenConstraints: ConstraintSet
+
+    @Mock private lateinit var demoModeController: DemoModeController
+    @Mock private lateinit var qsBatteryModeController: QsBatteryModeController
+
+    @JvmField @Rule val mockitoRule = MockitoJUnit.rule()
+    var viewVisibility = View.GONE
+    var viewAlpha = 1f
+
+    private lateinit var shadeHeaderController: ShadeHeaderController
+    private lateinit var carrierIconSlots: List<String>
+    private val configurationController = FakeConfigurationController()
+    @Captor private lateinit var demoModeControllerCapture: ArgumentCaptor<DemoMode>
+
+    @Before
+    fun setup() {
+        whenever<Clock>(view.findViewById(R.id.clock)).thenReturn(clock)
+        whenever(clock.context).thenReturn(mockedContext)
+
+        whenever<TextView>(view.findViewById(R.id.date)).thenReturn(date)
+        whenever(date.context).thenReturn(mockedContext)
+
+        whenever<QSCarrierGroup>(view.findViewById(R.id.carrier_group)).thenReturn(carrierGroup)
+
+        whenever<BatteryMeterView>(view.findViewById(R.id.batteryRemainingIcon))
+            .thenReturn(batteryMeterView)
+
+        whenever<StatusIconContainer>(view.findViewById(R.id.statusIcons)).thenReturn(statusIcons)
+
+        viewContext = Mockito.spy(context)
+        whenever(view.context).thenReturn(viewContext)
+        whenever(view.resources).thenReturn(context.resources)
+        whenever(statusIcons.context).thenReturn(context)
+        whenever(qsCarrierGroupControllerBuilder.setQSCarrierGroup(any()))
+            .thenReturn(qsCarrierGroupControllerBuilder)
+        whenever(qsCarrierGroupControllerBuilder.build()).thenReturn(qsCarrierGroupController)
+        whenever(view.setVisibility(anyInt())).then {
+            viewVisibility = it.arguments[0] as Int
+            null
+        }
+        whenever(view.visibility).thenAnswer { _ -> viewVisibility }
+
+        whenever(view.setAlpha(anyFloat())).then {
+            viewAlpha = it.arguments[0] as Float
+            null
+        }
+        whenever(view.alpha).thenAnswer { _ -> viewAlpha }
+
+        whenever(variableDateViewControllerFactory.create(any()))
+            .thenReturn(variableDateViewController)
+        whenever(iconManagerFactory.create(any(), any())).thenReturn(iconManager)
+
+        setUpDefaultInsets()
+        setUpMotionLayout(view)
+
+        shadeHeaderController =
+            ShadeHeaderController(
+                view,
+                statusBarIconController,
+                iconManagerFactory,
+                privacyIconsController,
+                insetsProvider,
+                configurationController,
+                variableDateViewControllerFactory,
+                batteryMeterViewController,
+                dumpManager,
+                qsCarrierGroupControllerBuilder,
+                combinedShadeHeadersConstraintManager,
+                demoModeController,
+                qsBatteryModeController,
+            )
+        whenever(view.isAttachedToWindow).thenReturn(true)
+        shadeHeaderController.init()
+        carrierIconSlots =
+            listOf(context.getString(com.android.internal.R.string.status_bar_mobile))
+    }
+
+    @Test
+    fun updateListeners_registersWhenVisible() {
+        makeShadeVisible()
+        verify(qsCarrierGroupController).setListening(true)
+        verify(statusBarIconController).addIconGroup(any())
+    }
+
+    @Test
+    fun statusIconsAddedWhenAttached() {
+        verify(statusBarIconController).addIconGroup(any())
+    }
+
+    @Test
+    fun statusIconsRemovedWhenDettached() {
+        shadeHeaderController.simulateViewDetached()
+        verify(statusBarIconController).removeIconGroup(any())
+    }
+
+    @Test
+    fun shadeExpandedFraction_updatesAlpha() {
+        makeShadeVisible()
+        shadeHeaderController.shadeExpandedFraction = 0.5f
+        verify(view).setAlpha(ShadeInterpolation.getContentAlpha(0.5f))
+    }
+
+    @Test
+    fun singleCarrier_enablesCarrierIconsInStatusIcons() {
+        whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(true)
+
+        makeShadeVisible()
+
+        verify(statusIcons).removeIgnoredSlots(carrierIconSlots)
+    }
+
+    @Test
+    fun dualCarrier_disablesCarrierIconsInStatusIcons() {
+        whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(false)
+
+        makeShadeVisible()
+
+        verify(statusIcons).addIgnoredSlots(carrierIconSlots)
+    }
+
+    @Test
+    fun disableQS_notDisabled_visible() {
+        makeShadeVisible()
+        shadeHeaderController.disable(0, 0, false)
+
+        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
+    }
+
+    @Test
+    fun disableQS_disabled_gone() {
+        makeShadeVisible()
+        shadeHeaderController.disable(0, StatusBarManager.DISABLE2_QUICK_SETTINGS, false)
+
+        assertThat(viewVisibility).isEqualTo(View.GONE)
+    }
+
+    private fun makeShadeVisible() {
+        shadeHeaderController.largeScreenActive = true
+        shadeHeaderController.qsVisible = true
+    }
+
+    @Test
+    fun updateConfig_changesFontStyle() {
+        configurationController.notifyDensityOrFontScaleChanged()
+
+        verify(clock).setTextAppearance(R.style.TextAppearance_QS_Status)
+        verify(date).setTextAppearance(R.style.TextAppearance_QS_Status)
+        verify(carrierGroup).updateTextAppearance(R.style.TextAppearance_QS_Status_Carriers)
+    }
+
+    @Test
+    fun animateOutOnStartCustomizing() {
+        val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
+        val duration = 1000L
+        whenever(view.animate()).thenReturn(animator)
+
+        shadeHeaderController.startCustomizingAnimation(show = true, duration)
+
+        verify(animator).setDuration(duration)
+        verify(animator).alpha(0f)
+        verify(animator).setInterpolator(Interpolators.ALPHA_OUT)
+        verify(animator).start()
+    }
+
+    @Test
+    fun animateInOnEndCustomizing() {
+        val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
+        val duration = 1000L
+        whenever(view.animate()).thenReturn(animator)
+
+        shadeHeaderController.startCustomizingAnimation(show = false, duration)
+
+        verify(animator).setDuration(duration)
+        verify(animator).alpha(1f)
+        verify(animator).setInterpolator(Interpolators.ALPHA_IN)
+        verify(animator).start()
+    }
+
+    @Test
+    fun customizerAnimatorChangesViewVisibility() {
+        makeShadeVisible()
+
+        val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
+        val duration = 1000L
+        whenever(view.animate()).thenReturn(animator)
+        val listenerCaptor = argumentCaptor<Animator.AnimatorListener>()
+
+        shadeHeaderController.startCustomizingAnimation(show = true, duration)
+        verify(animator).setListener(capture(listenerCaptor))
+        // Start and end the animation
+        listenerCaptor.value.onAnimationStart(mock())
+        listenerCaptor.value.onAnimationEnd(mock())
+        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
+
+        reset(animator)
+        shadeHeaderController.startCustomizingAnimation(show = false, duration)
+        verify(animator).setListener(capture(listenerCaptor))
+        // Start and end the animation
+        listenerCaptor.value.onAnimationStart(mock())
+        listenerCaptor.value.onAnimationEnd(mock())
+        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
+    }
+
+    @Test
+    fun animatorListenersClearedAtEnd() {
+        val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
+        whenever(view.animate()).thenReturn(animator)
+
+        shadeHeaderController.startCustomizingAnimation(show = true, 0L)
+        val listenerCaptor = argumentCaptor<Animator.AnimatorListener>()
+        verify(animator).setListener(capture(listenerCaptor))
+
+        listenerCaptor.value.onAnimationEnd(mock())
+        verify(animator).setListener(null)
+    }
+
+    @Test
+    fun demoMode_attachDemoMode() {
+        val cb = argumentCaptor<DemoMode>()
+        verify(demoModeController).addCallback(capture(cb))
+        cb.value.onDemoModeStarted()
+        verify(clock).onDemoModeStarted()
+    }
+
+    @Test
+    fun demoMode_detachDemoMode() {
+        shadeHeaderController.simulateViewDetached()
+        val cb = argumentCaptor<DemoMode>()
+        verify(demoModeController).removeCallback(capture(cb))
+        cb.value.onDemoModeFinished()
+        verify(clock).onDemoModeFinished()
+    }
+
+    @Test
+    fun testControllersCreatedAndInitialized() {
+        verify(variableDateViewController).init()
+
+        verify(batteryMeterViewController).init()
+        verify(batteryMeterViewController).ignoreTunerUpdates()
+
+        val inOrder = Mockito.inOrder(qsCarrierGroupControllerBuilder)
+        inOrder.verify(qsCarrierGroupControllerBuilder).setQSCarrierGroup(carrierGroup)
+        inOrder.verify(qsCarrierGroupControllerBuilder).build()
+    }
+
+    @Test
+    fun `battery mode controller called when qsExpandedFraction changes`() {
+        whenever(qsBatteryModeController.getBatteryMode(Mockito.same(null), eq(0f)))
+            .thenReturn(BatteryMeterView.MODE_ON)
+        whenever(qsBatteryModeController.getBatteryMode(Mockito.same(null), eq(1f)))
+            .thenReturn(BatteryMeterView.MODE_ESTIMATE)
+        shadeHeaderController.qsVisible = true
+
+        val times = 10
+        repeat(times) { shadeHeaderController.qsExpandedFraction = it / (times - 1).toFloat() }
+
+        verify(batteryMeterView).setPercentShowMode(BatteryMeterView.MODE_ON)
+        verify(batteryMeterView).setPercentShowMode(BatteryMeterView.MODE_ESTIMATE)
+    }
+
+    @Test
+    fun testClockPivotLtr() {
+        val width = 200
+        whenever(clock.width).thenReturn(width)
+        whenever(clock.isLayoutRtl).thenReturn(false)
+
+        val captor = ArgumentCaptor.forClass(View.OnLayoutChangeListener::class.java)
+        verify(clock).addOnLayoutChangeListener(capture(captor))
+
+        captor.value.onLayoutChange(clock, 0, 1, 2, 3, 4, 5, 6, 7)
+        verify(clock).pivotX = 0f
+    }
+
+    @Test
+    fun testClockPivotRtl() {
+        val width = 200
+        whenever(clock.width).thenReturn(width)
+        whenever(clock.isLayoutRtl).thenReturn(true)
+
+        val captor = ArgumentCaptor.forClass(View.OnLayoutChangeListener::class.java)
+        verify(clock).addOnLayoutChangeListener(capture(captor))
+
+        captor.value.onLayoutChange(clock, 0, 1, 2, 3, 4, 5, 6, 7)
+        verify(clock).pivotX = width.toFloat()
+    }
+
+    @Test
+    fun testShadeExpanded_true() {
+        // When shade is expanded, view should be visible regardless of largeScreenActive
+        shadeHeaderController.largeScreenActive = false
+        shadeHeaderController.qsVisible = true
+        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
+
+        shadeHeaderController.largeScreenActive = true
+        assertThat(viewVisibility).isEqualTo(View.VISIBLE)
+    }
+
+    @Test
+    fun testShadeExpanded_false() {
+        // When shade is not expanded, view should be invisible regardless of largeScreenActive
+        shadeHeaderController.largeScreenActive = false
+        shadeHeaderController.qsVisible = false
+        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
+
+        shadeHeaderController.largeScreenActive = true
+        assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
+    }
+
+    @Test
+    fun testLargeScreenActive_false() {
+        shadeHeaderController.largeScreenActive = true // Make sure there's a change
+        Mockito.clearInvocations(view)
+
+        shadeHeaderController.largeScreenActive = false
+
+        verify(view).setTransition(ShadeHeaderController.HEADER_TRANSITION_ID)
+    }
+
+    @Test
+    fun testShadeExpandedFraction() {
+        // View needs to be visible for this to actually take effect
+        shadeHeaderController.qsVisible = true
+
+        Mockito.clearInvocations(view)
+        shadeHeaderController.shadeExpandedFraction = 0.3f
+        verify(view).alpha = ShadeInterpolation.getContentAlpha(0.3f)
+
+        Mockito.clearInvocations(view)
+        shadeHeaderController.shadeExpandedFraction = 1f
+        verify(view).alpha = ShadeInterpolation.getContentAlpha(1f)
+
+        Mockito.clearInvocations(view)
+        shadeHeaderController.shadeExpandedFraction = 0f
+        verify(view).alpha = ShadeInterpolation.getContentAlpha(0f)
+    }
+
+    @Test
+    fun testQsExpandedFraction_headerTransition() {
+        shadeHeaderController.qsVisible = true
+        shadeHeaderController.largeScreenActive = false
+
+        Mockito.clearInvocations(view)
+        shadeHeaderController.qsExpandedFraction = 0.3f
+        verify(view).progress = 0.3f
+    }
+
+    @Test
+    fun testQsExpandedFraction_largeScreen() {
+        shadeHeaderController.qsVisible = true
+        shadeHeaderController.largeScreenActive = true
+
+        Mockito.clearInvocations(view)
+        shadeHeaderController.qsExpandedFraction = 0.3f
+        verify(view, Mockito.never()).progress = anyFloat()
+    }
+
+    @Test
+    fun testScrollY_headerTransition() {
+        shadeHeaderController.largeScreenActive = false
+
+        Mockito.clearInvocations(view)
+        shadeHeaderController.qsScrollY = 20
+        verify(view).scrollY = 20
+    }
+
+    @Test
+    fun testScrollY_largeScreen() {
+        shadeHeaderController.largeScreenActive = true
+
+        Mockito.clearInvocations(view)
+        shadeHeaderController.qsScrollY = 20
+        verify(view, Mockito.never()).scrollY = anyInt()
+    }
+
+    @Test
+    fun testPrivacyChipVisibilityChanged_visible_changesCorrectConstraints() {
+        val chipVisibleChanges = createMockConstraintChanges()
+        val chipNotVisibleChanges = createMockConstraintChanges()
+
+        whenever(combinedShadeHeadersConstraintManager.privacyChipVisibilityConstraints(true))
+            .thenReturn(chipVisibleChanges)
+        whenever(combinedShadeHeadersConstraintManager.privacyChipVisibilityConstraints(false))
+            .thenReturn(chipNotVisibleChanges)
+
+        val captor = ArgumentCaptor.forClass(ChipVisibilityListener::class.java)
+        verify(privacyIconsController).chipVisibilityListener = capture(captor)
+
+        captor.value.onChipVisibilityRefreshed(true)
+
+        verify(chipVisibleChanges.qqsConstraintsChanges)!!.invoke(qqsConstraints)
+        verify(chipVisibleChanges.qsConstraintsChanges)!!.invoke(qsConstraints)
+        verify(chipVisibleChanges.largeScreenConstraintsChanges)!!.invoke(largeScreenConstraints)
+
+        verify(chipNotVisibleChanges.qqsConstraintsChanges, Mockito.never())!!.invoke(any())
+        verify(chipNotVisibleChanges.qsConstraintsChanges, Mockito.never())!!.invoke(any())
+        verify(chipNotVisibleChanges.largeScreenConstraintsChanges, Mockito.never())!!.invoke(any())
+    }
+
+    @Test
+    fun testPrivacyChipVisibilityChanged_notVisible_changesCorrectConstraints() {
+        val chipVisibleChanges = createMockConstraintChanges()
+        val chipNotVisibleChanges = createMockConstraintChanges()
+
+        whenever(combinedShadeHeadersConstraintManager.privacyChipVisibilityConstraints(true))
+            .thenReturn(chipVisibleChanges)
+        whenever(combinedShadeHeadersConstraintManager.privacyChipVisibilityConstraints(false))
+            .thenReturn(chipNotVisibleChanges)
+
+        val captor = ArgumentCaptor.forClass(ChipVisibilityListener::class.java)
+        verify(privacyIconsController).chipVisibilityListener = capture(captor)
+
+        captor.value.onChipVisibilityRefreshed(false)
+
+        verify(chipVisibleChanges.qqsConstraintsChanges, Mockito.never())!!.invoke(qqsConstraints)
+        verify(chipVisibleChanges.qsConstraintsChanges, Mockito.never())!!.invoke(qsConstraints)
+        verify(chipVisibleChanges.largeScreenConstraintsChanges, Mockito.never())!!.invoke(
+            largeScreenConstraints
+        )
+
+        verify(chipNotVisibleChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(chipNotVisibleChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(chipNotVisibleChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testInsetsGuides_ltr() {
+        whenever(view.isLayoutRtl).thenReturn(false)
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        val (insetLeft, insetRight) = 30 to 40
+        val (paddingStart, paddingEnd) = 10 to 20
+        whenever(view.paddingStart).thenReturn(paddingStart)
+        whenever(view.paddingEnd).thenReturn(paddingEnd)
+
+        mockInsetsProvider(insetLeft to insetRight, false)
+
+        whenever(
+                combinedShadeHeadersConstraintManager.edgesGuidelinesConstraints(
+                    anyInt(),
+                    anyInt(),
+                    anyInt(),
+                    anyInt()
+                )
+            )
+            .thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets())
+
+        verify(combinedShadeHeadersConstraintManager)
+            .edgesGuidelinesConstraints(insetLeft, paddingStart, insetRight, paddingEnd)
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testInsetsGuides_rtl() {
+        whenever(view.isLayoutRtl).thenReturn(true)
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        val (insetLeft, insetRight) = 30 to 40
+        val (paddingStart, paddingEnd) = 10 to 20
+        whenever(view.paddingStart).thenReturn(paddingStart)
+        whenever(view.paddingEnd).thenReturn(paddingEnd)
+
+        mockInsetsProvider(insetLeft to insetRight, false)
+
+        whenever(
+                combinedShadeHeadersConstraintManager.edgesGuidelinesConstraints(
+                    anyInt(),
+                    anyInt(),
+                    anyInt(),
+                    anyInt()
+                )
+            )
+            .thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets())
+
+        verify(combinedShadeHeadersConstraintManager)
+            .edgesGuidelinesConstraints(insetRight, paddingStart, insetLeft, paddingEnd)
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testNullCutout() {
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        whenever(combinedShadeHeadersConstraintManager.emptyCutoutConstraints())
+            .thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets(null))
+
+        verify(combinedShadeHeadersConstraintManager).emptyCutoutConstraints()
+        verify(combinedShadeHeadersConstraintManager, Mockito.never())
+            .centerCutoutConstraints(Mockito.anyBoolean(), anyInt())
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testEmptyCutout() {
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        whenever(combinedShadeHeadersConstraintManager.emptyCutoutConstraints())
+            .thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets())
+
+        verify(combinedShadeHeadersConstraintManager).emptyCutoutConstraints()
+        verify(combinedShadeHeadersConstraintManager, Mockito.never())
+            .centerCutoutConstraints(Mockito.anyBoolean(), anyInt())
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testCornerCutout_emptyRect() {
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        mockInsetsProvider(0 to 0, true)
+
+        whenever(combinedShadeHeadersConstraintManager.emptyCutoutConstraints())
+            .thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets())
+
+        verify(combinedShadeHeadersConstraintManager).emptyCutoutConstraints()
+        verify(combinedShadeHeadersConstraintManager, Mockito.never())
+            .centerCutoutConstraints(Mockito.anyBoolean(), anyInt())
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testCornerCutout_nonEmptyRect() {
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        mockInsetsProvider(0 to 0, true)
+
+        whenever(combinedShadeHeadersConstraintManager.emptyCutoutConstraints())
+            .thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets(Rect(1, 2, 3, 4)))
+
+        verify(combinedShadeHeadersConstraintManager).emptyCutoutConstraints()
+        verify(combinedShadeHeadersConstraintManager, Mockito.never())
+            .centerCutoutConstraints(Mockito.anyBoolean(), anyInt())
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testTopCutout_ltr() {
+        val width = 100
+        val paddingLeft = 10
+        val paddingRight = 20
+        val cutoutWidth = 30
+
+        whenever(view.isLayoutRtl).thenReturn(false)
+        whenever(view.width).thenReturn(width)
+        whenever(view.paddingLeft).thenReturn(paddingLeft)
+        whenever(view.paddingRight).thenReturn(paddingRight)
+
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        mockInsetsProvider(0 to 0, false)
+
+        whenever(
+                combinedShadeHeadersConstraintManager.centerCutoutConstraints(
+                    Mockito.anyBoolean(),
+                    anyInt()
+                )
+            )
+            .thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets(Rect(0, 0, cutoutWidth, 1)))
+
+        verify(combinedShadeHeadersConstraintManager, Mockito.never()).emptyCutoutConstraints()
+        val offset = (width - paddingLeft - paddingRight - cutoutWidth) / 2
+        verify(combinedShadeHeadersConstraintManager).centerCutoutConstraints(false, offset)
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun testTopCutout_rtl() {
+        val width = 100
+        val paddingLeft = 10
+        val paddingRight = 20
+        val cutoutWidth = 30
+
+        whenever(view.isLayoutRtl).thenReturn(true)
+        whenever(view.width).thenReturn(width)
+        whenever(view.paddingLeft).thenReturn(paddingLeft)
+        whenever(view.paddingRight).thenReturn(paddingRight)
+
+        val captor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java)
+        verify(view).setOnApplyWindowInsetsListener(capture(captor))
+        val mockConstraintsChanges = createMockConstraintChanges()
+
+        mockInsetsProvider(0 to 0, false)
+
+        whenever(
+                combinedShadeHeadersConstraintManager.centerCutoutConstraints(
+                    Mockito.anyBoolean(),
+                    anyInt()
+                )
+            )
+            .thenReturn(mockConstraintsChanges)
+
+        captor.value.onApplyWindowInsets(view, createWindowInsets(Rect(0, 0, cutoutWidth, 1)))
+
+        verify(combinedShadeHeadersConstraintManager, Mockito.never()).emptyCutoutConstraints()
+        val offset = (width - paddingLeft - paddingRight - cutoutWidth) / 2
+        verify(combinedShadeHeadersConstraintManager).centerCutoutConstraints(true, offset)
+
+        verify(mockConstraintsChanges.qqsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.qsConstraintsChanges)!!.invoke(any())
+        verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any())
+    }
+
+    @Test
+    fun alarmIconNotIgnored() {
+        verify(statusIcons, Mockito.never())
+            .addIgnoredSlot(context.getString(com.android.internal.R.string.status_bar_alarm_clock))
+    }
+
+    @Test
+    fun privacyChipParentVisibleFromStart() {
+        verify(privacyIconsController).onParentVisible()
+    }
+
+    @Test
+    fun privacyChipParentVisibleAlways() {
+        shadeHeaderController.largeScreenActive = true
+        shadeHeaderController.largeScreenActive = false
+        shadeHeaderController.largeScreenActive = true
+
+        verify(privacyIconsController, Mockito.never()).onParentInvisible()
+    }
+
+    @Test
+    fun clockPivotYInCenter() {
+        val captor = ArgumentCaptor.forClass(View.OnLayoutChangeListener::class.java)
+        verify(clock).addOnLayoutChangeListener(capture(captor))
+        var height = 100
+        val width = 50
+
+        clock.executeLayoutChange(0, 0, width, height, captor.value)
+        verify(clock).pivotY = height.toFloat() / 2
+
+        height = 150
+        clock.executeLayoutChange(0, 0, width, height, captor.value)
+        verify(clock).pivotY = height.toFloat() / 2
+    }
+
+    @Test
+    fun onDensityOrFontScaleChanged_reloadConstraints() {
+        // After density or font scale change, constraints need to be reloaded to reflect new
+        // dimensions.
+        Mockito.reset(qqsConstraints)
+        Mockito.reset(qsConstraints)
+        Mockito.reset(largeScreenConstraints)
+
+        configurationController.notifyDensityOrFontScaleChanged()
+
+        val captor = ArgumentCaptor.forClass(XmlResourceParser::class.java)
+        verify(qqsConstraints).load(eq(viewContext), capture(captor))
+        assertThat(captor.value.getResId()).isEqualTo(R.xml.qqs_header)
+        verify(qsConstraints).load(eq(viewContext), capture(captor))
+        assertThat(captor.value.getResId()).isEqualTo(R.xml.qs_header)
+        verify(largeScreenConstraints).load(eq(viewContext), capture(captor))
+        assertThat(captor.value.getResId()).isEqualTo(R.xml.large_screen_shade_header)
+    }
+
+    @Test
+    fun `carrier left padding is set when clock layout changes`() {
+        val width = 200
+        whenever(clock.width).thenReturn(width)
+        whenever(clock.scaleX).thenReturn(2.57f) // 2.57 comes from qs_header.xml
+        val captor = ArgumentCaptor.forClass(View.OnLayoutChangeListener::class.java)
+
+        verify(clock).addOnLayoutChangeListener(capture(captor))
+        captor.value.onLayoutChange(clock, 0, 0, width, 0, 0, 0, 0, 0)
+
+        verify(carrierGroup).setPaddingRelative(514, 0, 0, 0)
+    }
+
+    private fun View.executeLayoutChange(
+        left: Int,
+        top: Int,
+        right: Int,
+        bottom: Int,
+        listener: View.OnLayoutChangeListener
+    ) {
+        val oldLeft = this.left
+        val oldTop = this.top
+        val oldRight = this.right
+        val oldBottom = this.bottom
+        whenever(this.left).thenReturn(left)
+        whenever(this.top).thenReturn(top)
+        whenever(this.right).thenReturn(right)
+        whenever(this.bottom).thenReturn(bottom)
+        whenever(this.height).thenReturn(bottom - top)
+        whenever(this.width).thenReturn(right - left)
+        listener.onLayoutChange(
+            this,
+            oldLeft,
+            oldTop,
+            oldRight,
+            oldBottom,
+            left,
+            top,
+            right,
+            bottom
+        )
+    }
+
+    private fun createWindowInsets(topCutout: Rect? = Rect()): WindowInsets {
+        val windowInsets: WindowInsets = mock()
+        val displayCutout: DisplayCutout = mock()
+        whenever(windowInsets.displayCutout)
+            .thenReturn(if (topCutout != null) displayCutout else null)
+        whenever(displayCutout.boundingRectTop).thenReturn(topCutout)
+
+        return windowInsets
+    }
+
+    private fun mockInsetsProvider(
+        insets: Pair<Int, Int> = 0 to 0,
+        cornerCutout: Boolean = false,
+    ) {
+        whenever(insetsProvider.getStatusBarContentInsetsForCurrentRotation())
+            .thenReturn(insets.toAndroidPair())
+        whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(cornerCutout)
+    }
+
+    private fun createMockConstraintChanges(): ConstraintsChanges {
+        return ConstraintsChanges(mock(), mock(), mock())
+    }
+
+    private fun XmlResourceParser.getResId(): Int {
+        return Resources.getAttributeSetSourceResId(this)
+    }
+
+    private fun setUpMotionLayout(motionLayout: MotionLayout) {
+        whenever(motionLayout.getConstraintSet(QQS_HEADER_CONSTRAINT)).thenReturn(qqsConstraints)
+        whenever(motionLayout.getConstraintSet(QS_HEADER_CONSTRAINT)).thenReturn(qsConstraints)
+        whenever(motionLayout.getConstraintSet(LARGE_SCREEN_HEADER_CONSTRAINT))
+            .thenReturn(largeScreenConstraints)
+    }
+
+    private fun setUpDefaultInsets() {
+        whenever(
+                combinedShadeHeadersConstraintManager.edgesGuidelinesConstraints(
+                    anyInt(),
+                    anyInt(),
+                    anyInt(),
+                    anyInt()
+                )
+            )
+            .thenReturn(EMPTY_CHANGES)
+        whenever(combinedShadeHeadersConstraintManager.emptyCutoutConstraints())
+            .thenReturn(EMPTY_CHANGES)
+        whenever(
+                combinedShadeHeadersConstraintManager.centerCutoutConstraints(
+                    Mockito.anyBoolean(),
+                    anyInt()
+                )
+            )
+            .thenReturn(EMPTY_CHANGES)
+        whenever(
+                combinedShadeHeadersConstraintManager.privacyChipVisibilityConstraints(
+                    Mockito.anyBoolean()
+                )
+            )
+            .thenReturn(EMPTY_CHANGES)
+        whenever(insetsProvider.getStatusBarContentInsetsForCurrentRotation())
+            .thenReturn(Pair(0, 0).toAndroidPair())
+        whenever(insetsProvider.currentRotationHasCornerCutout()).thenReturn(false)
+        setupCurrentInsets(null)
+    }
+
+    private fun setupCurrentInsets(cutout: DisplayCutout?) {
+        val mockedDisplay =
+            mock<Display>().also { display -> whenever(display.cutout).thenReturn(cutout) }
+        whenever(viewContext.display).thenReturn(mockedDisplay)
+    }
+
+    private fun <T, U> Pair<T, U>.toAndroidPair(): android.util.Pair<T, U> {
+        return android.util.Pair(first, second)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
index 7cac854..d5a1f80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
@@ -2,37 +2,24 @@
 
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
-import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
-import com.android.systemui.plugins.qs.QS
-import com.android.systemui.shade.NotificationPanelViewController
 import com.android.systemui.shade.STATE_OPENING
 import com.android.systemui.shade.ShadeExpansionChangeEvent
 import com.android.systemui.shade.ShadeExpansionStateManager
-import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.SysuiStatusBarStateController
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.statusbar.policy.FakeConfigurationController
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
-import org.mockito.Mockito.reset
 import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
 
 @RunWith(AndroidTestingRunner::class)
 @SmallTest
 class ShadeTransitionControllerTest : SysuiTestCase() {
 
-    @Mock private lateinit var npvc: NotificationPanelViewController
-    @Mock private lateinit var nsslController: NotificationStackScrollLayoutController
-    @Mock private lateinit var qs: QS
-    @Mock private lateinit var noOpOverScroller: NoOpOverScroller
-    @Mock private lateinit var splitShadeOverScroller: SplitShadeOverScroller
     @Mock private lateinit var scrimShadeTransitionController: ScrimShadeTransitionController
     @Mock private lateinit var dumpManager: DumpManager
     @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
@@ -52,119 +39,19 @@
                 shadeExpansionStateManager,
                 dumpManager,
                 context,
-                splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller },
-                noOpOverScroller,
                 scrimShadeTransitionController,
                 statusBarStateController,
             )
-
-        // Resetting as they are notified upon initialization.
-        reset(noOpOverScroller, splitShadeOverScroller)
-    }
-
-    @Test
-    fun onPanelExpansionChanged_inSplitShade_forwardsToSplitShadeOverScroller() {
-        initLateProperties()
-        enableSplitShade()
-
-        startPanelExpansion()
-
-        verify(splitShadeOverScroller).onPanelStateChanged(STATE_OPENING)
-        verify(splitShadeOverScroller).onDragDownAmountChanged(DEFAULT_DRAG_DOWN_AMOUNT)
-        verifyZeroInteractions(noOpOverScroller)
-    }
-
-    @Test
-    fun onPanelStateChanged_inSplitShade_propertiesNotInitialized_forwardsToNoOpOverScroller() {
-        enableSplitShade()
-
-        startPanelExpansion()
-
-        verify(noOpOverScroller).onPanelStateChanged(STATE_OPENING)
-        verify(noOpOverScroller).onDragDownAmountChanged(DEFAULT_DRAG_DOWN_AMOUNT)
-        verifyZeroInteractions(splitShadeOverScroller)
-    }
-
-    @Test
-    fun onPanelStateChanged_inSplitShade_onKeyguard_forwardsToNoOpOverScroller() {
-        initLateProperties()
-        enableSplitShade()
-        setOnKeyguard()
-
-        startPanelExpansion()
-
-        verify(noOpOverScroller).onPanelStateChanged(STATE_OPENING)
-        verify(noOpOverScroller).onDragDownAmountChanged(DEFAULT_DRAG_DOWN_AMOUNT)
-        verifyZeroInteractions(splitShadeOverScroller)
-    }
-
-    @Test
-    fun onPanelStateChanged_inSplitShade_onLockedShade_forwardsToNoOpOverScroller() {
-        initLateProperties()
-        enableSplitShade()
-        setOnLockedShade()
-
-        startPanelExpansion()
-
-        verify(noOpOverScroller).onPanelStateChanged(STATE_OPENING)
-        verify(noOpOverScroller).onDragDownAmountChanged(DEFAULT_DRAG_DOWN_AMOUNT)
-        verifyZeroInteractions(splitShadeOverScroller)
-    }
-
-    @Test
-    fun onPanelExpansionChanged_inSplitShade_onUnlockedShade_forwardsToSplitShadeOverScroller() {
-        initLateProperties()
-        enableSplitShade()
-        setOnUnlockedShade()
-
-        startPanelExpansion()
-
-        verify(splitShadeOverScroller).onPanelStateChanged(STATE_OPENING)
-        verify(splitShadeOverScroller).onDragDownAmountChanged(DEFAULT_DRAG_DOWN_AMOUNT)
-        verifyZeroInteractions(noOpOverScroller)
-    }
-
-    @Test
-    fun onPanelStateChanged_notInSplitShade_forwardsToNoOpOverScroller() {
-        initLateProperties()
-        disableSplitShade()
-
-        startPanelExpansion()
-
-        verify(noOpOverScroller).onPanelStateChanged(STATE_OPENING)
-        verify(noOpOverScroller).onDragDownAmountChanged(DEFAULT_DRAG_DOWN_AMOUNT)
-        verifyZeroInteractions(splitShadeOverScroller)
     }
 
     @Test
     fun onPanelStateChanged_forwardsToScrimTransitionController() {
-        initLateProperties()
-
         startPanelExpansion()
 
         verify(scrimShadeTransitionController).onPanelStateChanged(STATE_OPENING)
         verify(scrimShadeTransitionController).onPanelExpansionChanged(DEFAULT_EXPANSION_EVENT)
     }
 
-    private fun initLateProperties() {
-        controller.qs = qs
-        controller.notificationStackScrollLayoutController = nsslController
-        controller.notificationPanelViewController = npvc
-    }
-
-    private fun disableSplitShade() {
-        setSplitShadeEnabled(false)
-    }
-
-    private fun enableSplitShade() {
-        setSplitShadeEnabled(true)
-    }
-
-    private fun setSplitShadeEnabled(enabled: Boolean) {
-        overrideResource(R.bool.config_use_split_notification_shade, enabled)
-        configurationController.notifyConfigurationChanged()
-    }
-
     private fun startPanelExpansion() {
         shadeExpansionStateManager.onPanelExpansionChanged(
             DEFAULT_EXPANSION_EVENT.fraction,
@@ -174,23 +61,6 @@
         )
     }
 
-    private fun setOnKeyguard() {
-        setShadeState(StatusBarState.KEYGUARD)
-    }
-
-    private fun setOnLockedShade() {
-        setShadeState(StatusBarState.SHADE_LOCKED)
-    }
-
-    private fun setOnUnlockedShade() {
-        setShadeState(StatusBarState.SHADE)
-    }
-
-    private fun setShadeState(state: Int) {
-        whenever(statusBarStateController.state).thenReturn(state)
-        whenever(statusBarStateController.currentOrUpcomingState).thenReturn(state)
-    }
-
     companion object {
         private const val DEFAULT_DRAG_DOWN_AMOUNT = 123f
         private val DEFAULT_EXPANSION_EVENT =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/SplitShadeOverScrollerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/SplitShadeOverScrollerTest.kt
deleted file mode 100644
index 0e48b48..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/SplitShadeOverScrollerTest.kt
+++ /dev/null
@@ -1,112 +0,0 @@
-package com.android.systemui.shade.transition
-
-import android.testing.AndroidTestingRunner
-import android.testing.TestableLooper
-import androidx.test.filters.SmallTest
-import com.android.systemui.R
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.dump.DumpManager
-import com.android.systemui.plugins.qs.QS
-import com.android.systemui.shade.STATE_CLOSED
-import com.android.systemui.shade.STATE_OPEN
-import com.android.systemui.shade.STATE_OPENING
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
-import com.android.systemui.statusbar.phone.ScrimController
-import com.android.systemui.statusbar.policy.FakeConfigurationController
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito.atLeastOnce
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.Mockito.`when` as whenever
-import org.mockito.MockitoAnnotations
-
-@RunWith(AndroidTestingRunner::class)
-@TestableLooper.RunWithLooper(setAsMainLooper = true)
-@SmallTest
-class SplitShadeOverScrollerTest : SysuiTestCase() {
-
-    @Mock private lateinit var dumpManager: DumpManager
-    @Mock private lateinit var scrimController: ScrimController
-    @Mock private lateinit var qs: QS
-    @Mock private lateinit var nsslController: NotificationStackScrollLayoutController
-
-    private val configurationController = FakeConfigurationController()
-    private lateinit var overScroller: SplitShadeOverScroller
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-
-        whenever(nsslController.height).thenReturn(1000)
-        overScroller =
-            SplitShadeOverScroller(
-                configurationController,
-                dumpManager,
-                context,
-                scrimController,
-                { qs },
-                { nsslController })
-    }
-
-    @Test
-    fun onDragDownAmountChanged_panelOpening_overScrolls_basedOnHeightAndMaxAmount() {
-        val maxOverScrollAmount = 50
-        val dragDownAmount = 100f
-        overrideResource(R.dimen.shade_max_over_scroll_amount, maxOverScrollAmount)
-        configurationController.notifyConfigurationChanged()
-
-        overScroller.onPanelStateChanged(STATE_OPENING)
-        overScroller.onDragDownAmountChanged(dragDownAmount)
-
-        val expectedOverScrollAmount =
-            (dragDownAmount / nsslController.height * maxOverScrollAmount).toInt()
-        verify(qs).setOverScrollAmount(expectedOverScrollAmount)
-        verify(nsslController).setOverScrollAmount(expectedOverScrollAmount)
-        verify(scrimController).setNotificationsOverScrollAmount(expectedOverScrollAmount)
-    }
-
-    @Test
-    fun onDragDownAmountChanged_panelClosed_doesNotOverScroll() {
-        overScroller.onPanelStateChanged(STATE_CLOSED)
-        overScroller.onDragDownAmountChanged(100f)
-
-        verifyZeroInteractions(qs, scrimController, nsslController)
-    }
-
-    @Test
-    fun onDragDownAmountChanged_panelOpen_doesNotOverScroll() {
-        overScroller.onPanelStateChanged(STATE_OPEN)
-        overScroller.onDragDownAmountChanged(100f)
-
-        verifyZeroInteractions(qs, scrimController, nsslController)
-    }
-
-    @Test
-    fun onPanelStateChanged_opening_thenOpen_releasesOverScroll() {
-        overScroller.onPanelStateChanged(STATE_OPENING)
-        overScroller.onDragDownAmountChanged(100f)
-
-        overScroller.onPanelStateChanged(STATE_OPEN)
-        overScroller.finishAnimations()
-
-        verify(qs, atLeastOnce()).setOverScrollAmount(0)
-        verify(scrimController, atLeastOnce()).setNotificationsOverScrollAmount(0)
-        verify(nsslController, atLeastOnce()).setOverScrollAmount(0)
-    }
-
-    @Test
-    fun onPanelStateChanged_opening_thenClosed_releasesOverScroll() {
-        overScroller.onPanelStateChanged(STATE_OPENING)
-        overScroller.onDragDownAmountChanged(100f)
-
-        overScroller.onPanelStateChanged(STATE_CLOSED)
-        overScroller.finishAnimations()
-
-        verify(qs, atLeastOnce()).setOverScrollAmount(0)
-        verify(scrimController, atLeastOnce()).setNotificationsOverScrollAmount(0)
-        verify(nsslController, atLeastOnce()).setOverScrollAmount(0)
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
index 26eff61..1fdb364 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
@@ -35,7 +35,6 @@
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
-import org.json.JSONException
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -271,10 +270,14 @@
 
     @Test
     fun jsonDeserialization_gotExpectedObject() {
-        val expected = ClockSettings("ID", null).apply { _applied_timestamp = 500 }
+        val expected = ClockSettings("ID", null).apply {
+            metadata.put("appliedTimestamp", 500)
+        }
         val actual = ClockSettings.deserialize("""{
             "clockId":"ID",
-            "_applied_timestamp":500
+            "metadata": {
+                "appliedTimestamp":500
+            }
         }""")
         assertEquals(expected, actual)
     }
@@ -291,29 +294,32 @@
         val expected = ClockSettings("ID", null)
         val actual = ClockSettings.deserialize("""{
             "clockId":"ID",
-            "_applied_timestamp":null
+            "metadata":null
         }""")
         assertEquals(expected, actual)
     }
 
-    @Test(expected = JSONException::class)
-    fun jsonDeserialization_noId_threwException() {
-        val expected = ClockSettings(null, null).apply { _applied_timestamp = 500 }
-        val actual = ClockSettings.deserialize("{\"_applied_timestamp\":500}")
+    @Test
+    fun jsonDeserialization_noId_deserializedEmpty() {
+        val expected = ClockSettings(null, null).apply {
+            metadata.put("appliedTimestamp", 500)
+        }
+        val actual = ClockSettings.deserialize("{\"metadata\":{\"appliedTimestamp\":500}}")
         assertEquals(expected, actual)
     }
 
     @Test
     fun jsonSerialization_gotExpectedString() {
-        val expected = "{\"clockId\":\"ID\",\"_applied_timestamp\":500}"
-        val actual = ClockSettings.serialize(ClockSettings("ID", null)
-            .apply { _applied_timestamp = 500 })
+        val expected = "{\"clockId\":\"ID\",\"metadata\":{\"appliedTimestamp\":500}}"
+        val actual = ClockSettings.serialize(ClockSettings("ID", null).apply {
+            metadata.put("appliedTimestamp", 500)
+        })
         assertEquals(expected, actual)
     }
 
     @Test
     fun jsonSerialization_noTimestamp_gotExpectedString() {
-        val expected = "{\"clockId\":\"ID\"}"
+        val expected = "{\"clockId\":\"ID\",\"metadata\":{}}"
         val actual = ClockSettings.serialize(ClockSettings("ID", null))
         assertEquals(expected, actual)
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
index cd2efc0..7fa27f3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
@@ -26,6 +26,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.plugins.ClockSettings
 import com.android.systemui.shared.clocks.DefaultClockController.Companion.DOZE_COLOR
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
@@ -40,7 +41,6 @@
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.ArgumentMatchers.anyFloat
-import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.notNull
 import org.mockito.Mock
 import org.mockito.Mockito.never
@@ -97,13 +97,14 @@
     @Test
     fun defaultClock_initialize() {
         val clock = provider.createClock(DEFAULT_CLOCK_ID)
-        verify(mockSmallClockView).setColors(Color.MAGENTA, Color.MAGENTA)
-        verify(mockLargeClockView).setColors(Color.MAGENTA, Color.MAGENTA)
+        verify(mockSmallClockView).setColors(DOZE_COLOR, Color.MAGENTA)
+        verify(mockLargeClockView).setColors(DOZE_COLOR, Color.MAGENTA)
 
         clock.initialize(resources, 0f, 0f)
 
-        verify(mockSmallClockView).setColors(eq(DOZE_COLOR), anyInt())
-        verify(mockLargeClockView).setColors(eq(DOZE_COLOR), anyInt())
+        val expectedColor = 0
+        verify(mockSmallClockView).setColors(DOZE_COLOR, expectedColor)
+        verify(mockLargeClockView).setColors(DOZE_COLOR, expectedColor)
         verify(mockSmallClockView).onTimeZoneChanged(notNull())
         verify(mockLargeClockView).onTimeZoneChanged(notNull())
         verify(mockSmallClockView).refreshTime()
@@ -159,15 +160,31 @@
 
     @Test
     fun defaultClock_events_onColorPaletteChanged() {
+        val expectedColor = 0
         val clock = provider.createClock(DEFAULT_CLOCK_ID)
 
-        verify(mockSmallClockView).setColors(Color.MAGENTA, Color.MAGENTA)
-        verify(mockLargeClockView).setColors(Color.MAGENTA, Color.MAGENTA)
+        verify(mockSmallClockView).setColors(DOZE_COLOR, Color.MAGENTA)
+        verify(mockLargeClockView).setColors(DOZE_COLOR, Color.MAGENTA)
 
         clock.events.onColorPaletteChanged(resources)
 
-        verify(mockSmallClockView).setColors(eq(DOZE_COLOR), anyInt())
-        verify(mockLargeClockView).setColors(eq(DOZE_COLOR), anyInt())
+        verify(mockSmallClockView).setColors(DOZE_COLOR, expectedColor)
+        verify(mockLargeClockView).setColors(DOZE_COLOR, expectedColor)
+    }
+
+    @Test
+    fun defaultClock_events_onSeedColorChanged() {
+        val initSeedColor = 10
+        val newSeedColor = 20
+        val clock = provider.createClock(ClockSettings(DEFAULT_CLOCK_ID, initSeedColor))
+
+        verify(mockSmallClockView).setColors(DOZE_COLOR, initSeedColor)
+        verify(mockLargeClockView).setColors(DOZE_COLOR, initSeedColor)
+
+        clock.events.onSeedColorChanged(newSeedColor)
+
+        verify(mockSmallClockView).setColors(DOZE_COLOR, newSeedColor)
+        verify(mockLargeClockView).setColors(DOZE_COLOR, newSeedColor)
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
index c5432c5..a280510 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
@@ -99,8 +99,6 @@
 
         override fun setPrimaryTextColor(color: Int) {}
 
-        override fun setIsDreaming(isDreaming: Boolean) {}
-
         override fun setUiSurface(uiSurface: String) {}
 
         override fun setDozeAmount(amount: Float) {}
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 702f278..d99cdd51 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -79,6 +79,7 @@
     @Mock lateinit var singleShadeOverScroller: SingleShadeLockScreenOverScroller
     @Mock lateinit var splitShadeOverScroller: SplitShadeLockScreenOverScroller
     @Mock lateinit var qsTransitionController: LockscreenShadeQsTransitionController
+    @Mock lateinit var transitionControllerCallback: LockscreenShadeTransitionController.Callback
     @JvmField @Rule val mockito = MockitoJUnit.rule()
 
     private val configurationController = FakeConfigurationController()
@@ -124,6 +125,7 @@
                 },
                 qsTransitionControllerFactory = { qsTransitionController },
             )
+        transitionController.addCallback(transitionControllerCallback)
         whenever(nsslController.view).thenReturn(stackscroller)
         whenever(nsslController.expandHelperCallback).thenReturn(expandHelperCallback)
         transitionController.notificationPanelController = notificationPanelController
@@ -258,7 +260,7 @@
         verify(nsslController, never()).setTransitionToFullShadeAmount(anyFloat())
         verify(mediaHierarchyManager, never()).setTransitionToFullShadeAmount(anyFloat())
         verify(scrimController, never()).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
-        verify(notificationPanelController, never()).setTransitionToFullShadeAmount(anyFloat(),
+        verify(transitionControllerCallback, never()).setTransitionToFullShadeAmount(anyFloat(),
                 anyBoolean(), anyLong())
         verify(qsTransitionController, never()).dragDownAmount = anyFloat()
     }
@@ -269,7 +271,7 @@
         verify(nsslController).setTransitionToFullShadeAmount(anyFloat())
         verify(mediaHierarchyManager).setTransitionToFullShadeAmount(anyFloat())
         verify(scrimController).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
-        verify(notificationPanelController).setTransitionToFullShadeAmount(anyFloat(),
+        verify(transitionControllerCallback).setTransitionToFullShadeAmount(anyFloat(),
                 anyBoolean(), anyLong())
         verify(qsTransitionController).dragDownAmount = 10f
         verify(depthController).transitionToFullShadeProgress = anyFloat()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index 452606d..8ee1ea8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -44,6 +44,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.widget.LockPatternUtils;
 import com.android.systemui.Dependency;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -354,7 +355,8 @@
                     mDeviceProvisionedController,
                     mKeyguardStateController,
                     mSettings,
-                    mock(DumpManager.class));
+                    mock(DumpManager.class),
+                    mock(LockPatternUtils.class));
         }
 
         public BroadcastReceiver getBaseBroadcastReceiverForTest() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt
new file mode 100644
index 0000000..cd06465
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/FakeStatusEvent.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.events
+
+/**
+ * This is a freely configurable implementation of [StatusEvent]. It is intended to be used in
+ * tests.
+ */
+class FakeStatusEvent(
+    override val viewCreator: ViewCreator,
+    override val priority: Int = 50,
+    override var forceVisible: Boolean = false,
+    override val showAnimation: Boolean = true,
+    override var contentDescription: String? = "",
+) : StatusEvent
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
new file mode 100644
index 0000000..08a9f31
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt
@@ -0,0 +1,470 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.events
+
+import android.graphics.Rect
+import android.os.Process
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.view.View
+import android.widget.FrameLayout
+import androidx.core.animation.AnimatorTestRule
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.privacy.OngoingPrivacyChip
+import com.android.systemui.statusbar.BatteryStatusChip
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
+import com.android.systemui.statusbar.window.StatusBarWindowController
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.time.FakeSystemClock
+import junit.framework.Assert.assertEquals
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.anyBoolean
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+class SystemStatusAnimationSchedulerImplTest : SysuiTestCase() {
+
+    @Mock private lateinit var systemEventCoordinator: SystemEventCoordinator
+    @Mock private lateinit var statusBarWindowController: StatusBarWindowController
+    @Mock private lateinit var statusBarContentInsetProvider: StatusBarContentInsetsProvider
+    @Mock private lateinit var dumpManager: DumpManager
+    @Mock private lateinit var listener: SystemStatusAnimationCallback
+
+    private lateinit var systemClock: FakeSystemClock
+    private lateinit var chipAnimationController: SystemEventChipAnimationController
+    private lateinit var systemStatusAnimationScheduler: SystemStatusAnimationScheduler
+    private val fakeFeatureFlags = FakeFeatureFlags()
+
+    @get:Rule val animatorTestRule = AnimatorTestRule()
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+
+        fakeFeatureFlags.set(Flags.PLUG_IN_STATUS_BAR_CHIP, true)
+
+        systemClock = FakeSystemClock()
+        chipAnimationController =
+            SystemEventChipAnimationController(
+                mContext,
+                statusBarWindowController,
+                statusBarContentInsetProvider,
+                fakeFeatureFlags
+            )
+
+        // ensure that isTooEarly() check in SystemStatusAnimationScheduler does not return true
+        systemClock.advanceTime(Process.getStartUptimeMillis() + MIN_UPTIME)
+
+        // StatusBarContentInsetProvider is mocked. Ensure that it returns some mocked values.
+        whenever(statusBarContentInsetProvider.getStatusBarContentInsetsForCurrentRotation())
+            .thenReturn(android.util.Pair(10, 10))
+        whenever(statusBarContentInsetProvider.getStatusBarContentAreaForCurrentRotation())
+            .thenReturn(Rect(10, 0, 990, 100))
+
+        // StatusBarWindowController is mocked. The addViewToWindow function needs to be mocked to
+        // ensure that the chip view is added to a parent view
+        whenever(statusBarWindowController.addViewToWindow(any(), any())).then {
+            val statusbarFake = FrameLayout(mContext)
+            statusbarFake.layout(0, 0, 1000, 100)
+            statusbarFake.addView(
+                it.arguments[0] as View,
+                it.arguments[1] as FrameLayout.LayoutParams
+            )
+        }
+    }
+
+    @Test
+    fun testBatteryStatusEvent_standardAnimationLifecycle() = runTest {
+        // Instantiate class under test with TestScope from runTest
+        initializeSystemStatusAnimationScheduler(testScope = this)
+
+        val batteryChip = createAndScheduleFakeBatteryEvent()
+
+        // assert that animation is queued
+        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+
+        // skip debounce delay
+        advanceTimeBy(DEBOUNCE_DELAY + 1)
+        // status chip starts animating in after debounce delay
+        assertEquals(ANIMATING_IN, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(0f, batteryChip.contentView.alpha)
+        assertEquals(0f, batteryChip.view.alpha)
+        verify(listener, times(1)).onSystemEventAnimationBegin()
+
+        // skip appear animation
+        animatorTestRule.advanceTimeBy(APPEAR_ANIMATION_DURATION)
+        advanceTimeBy(APPEAR_ANIMATION_DURATION)
+        // assert that status chip is visible
+        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(1f, batteryChip.contentView.alpha)
+        assertEquals(1f, batteryChip.view.alpha)
+
+        // skip status chip display time
+        advanceTimeBy(DISPLAY_LENGTH + 1)
+        // assert that it is still visible but switched to the ANIMATING_OUT state
+        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(1f, batteryChip.contentView.alpha)
+        assertEquals(1f, batteryChip.view.alpha)
+        verify(listener, times(1)).onSystemEventAnimationFinish(false)
+
+        // skip disappear animation
+        animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
+        // assert that it is not visible anymore
+        assertEquals(IDLE, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(0f, batteryChip.contentView.alpha)
+        assertEquals(0f, batteryChip.view.alpha)
+    }
+
+    @Test
+    fun testPrivacyStatusEvent_standardAnimationLifecycle() = runTest {
+        // Instantiate class under test with TestScope from runTest
+        initializeSystemStatusAnimationScheduler(testScope = this)
+
+        val privacyChip = createAndScheduleFakePrivacyEvent()
+
+        // assert that animation is queued
+        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+
+        // skip debounce delay
+        advanceTimeBy(DEBOUNCE_DELAY + 1)
+        // status chip starts animating in after debounce delay
+        assertEquals(ANIMATING_IN, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(0f, privacyChip.view.alpha)
+        verify(listener, times(1)).onSystemEventAnimationBegin()
+
+        // skip appear animation
+        animatorTestRule.advanceTimeBy(APPEAR_ANIMATION_DURATION)
+        advanceTimeBy(APPEAR_ANIMATION_DURATION + 1)
+        // assert that status chip is visible
+        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(1f, privacyChip.view.alpha)
+
+        // skip status chip display time
+        advanceTimeBy(DISPLAY_LENGTH + 1)
+        // assert that it is still visible but switched to the ANIMATING_OUT state
+        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(1f, privacyChip.view.alpha)
+        verify(listener, times(1)).onSystemEventAnimationFinish(true)
+        verify(listener, times(1)).onSystemStatusAnimationTransitionToPersistentDot(any())
+
+        // skip transition to persistent dot
+        advanceTimeBy(DISAPPEAR_ANIMATION_DURATION + 1)
+        animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
+        // assert that it the dot is now visible
+        assertEquals(SHOWING_PERSISTENT_DOT, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(1f, privacyChip.view.alpha)
+
+        // notify SystemStatusAnimationScheduler to remove persistent dot
+        systemStatusAnimationScheduler.removePersistentDot()
+        // assert that IDLE state is entered
+        assertEquals(IDLE, systemStatusAnimationScheduler.getAnimationState())
+        verify(listener, times(1)).onHidePersistentDot()
+    }
+
+    @Test
+    fun testHighPriorityEvent_takesPrecedenceOverScheduledLowPriorityEvent() = runTest {
+        // Instantiate class under test with TestScope from runTest
+        initializeSystemStatusAnimationScheduler(testScope = this)
+
+        // create and schedule low priority event
+        val batteryChip = createAndScheduleFakeBatteryEvent()
+        batteryChip.view.alpha = 0f
+
+        // assert that animation is queued
+        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+
+        // create and schedule high priority event
+        val privacyChip = createAndScheduleFakePrivacyEvent()
+
+        // assert that animation is queued
+        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+
+        // skip debounce delay and appear animation duration
+        fastForwardAnimationToState(RUNNING_CHIP_ANIM)
+
+        // high priority status chip is visible while low priority status chip is not visible
+        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(1f, privacyChip.view.alpha)
+        assertEquals(0f, batteryChip.view.alpha)
+    }
+
+    @Test
+    fun testHighPriorityEvent_cancelsCurrentlyDisplayedLowPriorityEvent() = runTest {
+        // Instantiate class under test with TestScope from runTest
+        initializeSystemStatusAnimationScheduler(testScope = this)
+
+        // create and schedule low priority event
+        val batteryChip = createAndScheduleFakeBatteryEvent()
+
+        // fast forward to RUNNING_CHIP_ANIM state
+        fastForwardAnimationToState(RUNNING_CHIP_ANIM)
+
+        // assert that chip is displayed
+        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(1f, batteryChip.view.alpha)
+
+        // create and schedule high priority event
+        val privacyChip = createAndScheduleFakePrivacyEvent()
+
+        // ensure that the event cancellation coroutine is started by the test scope
+        testScheduler.runCurrent()
+
+        // assert that currently displayed chip is immediately animated out
+        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+
+        // skip disappear animation
+        animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
+
+        // assert that high priority privacy chip animation is queued
+        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+
+        // skip debounce delay and appear animation
+        advanceTimeBy(DEBOUNCE_DELAY + APPEAR_ANIMATION_DURATION + 1)
+        animatorTestRule.advanceTimeBy(APPEAR_ANIMATION_DURATION)
+
+        // high priority status chip is visible while low priority status chip is not visible
+        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(1f, privacyChip.view.alpha)
+        assertEquals(0f, batteryChip.view.alpha)
+    }
+
+    @Test
+    fun testHighPriorityEvent_cancelsCurrentlyAnimatedLowPriorityEvent() = runTest {
+        // Instantiate class under test with TestScope from runTest
+        initializeSystemStatusAnimationScheduler(testScope = this)
+
+        // create and schedule low priority event
+        val batteryChip = createAndScheduleFakeBatteryEvent()
+
+        // skip debounce delay
+        advanceTimeBy(DEBOUNCE_DELAY + 1)
+
+        // assert that chip is animated in
+        assertEquals(ANIMATING_IN, systemStatusAnimationScheduler.getAnimationState())
+
+        // create and schedule high priority event
+        val privacyChip = createAndScheduleFakePrivacyEvent()
+
+        // ensure that the event cancellation coroutine is started by the test scope
+        testScheduler.runCurrent()
+
+        // assert that currently animated chip keeps animating
+        assertEquals(ANIMATING_IN, systemStatusAnimationScheduler.getAnimationState())
+
+        // skip appear animation
+        animatorTestRule.advanceTimeBy(APPEAR_ANIMATION_DURATION)
+        advanceTimeBy(APPEAR_ANIMATION_DURATION + 1)
+
+        // assert that low priority chip is animated out immediately after finishing the appear
+        // animation
+        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+
+        // skip disappear animation
+        animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
+
+        // assert that high priority privacy chip animation is queued
+        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+
+        // skip debounce delay and appear animation
+        advanceTimeBy(DEBOUNCE_DELAY + APPEAR_ANIMATION_DURATION + 1)
+        animatorTestRule.advanceTimeBy(APPEAR_ANIMATION_DURATION)
+
+        // high priority status chip is visible while low priority status chip is not visible
+        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(1f, privacyChip.view.alpha)
+        assertEquals(0f, batteryChip.view.alpha)
+    }
+
+    @Test
+    fun testHighPriorityEvent_isNotReplacedByLowPriorityEvent() = runTest {
+        // Instantiate class under test with TestScope from runTest
+        initializeSystemStatusAnimationScheduler(testScope = this)
+
+        // create and schedule high priority event
+        val privacyChip = createAndScheduleFakePrivacyEvent()
+
+        // create and schedule low priority event
+        val batteryChip = createAndScheduleFakeBatteryEvent()
+        batteryChip.view.alpha = 0f
+
+        // skip debounce delay and appear animation
+        advanceTimeBy(DEBOUNCE_DELAY + APPEAR_ANIMATION_DURATION + 1)
+        animatorTestRule.advanceTimeBy(APPEAR_ANIMATION_DURATION)
+
+        // high priority status chip is visible while low priority status chip is not visible
+        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        assertEquals(1f, privacyChip.view.alpha)
+        assertEquals(0f, batteryChip.view.alpha)
+    }
+
+    @Test
+    fun testPrivacyDot_isRemoved() = runTest {
+        // Instantiate class under test with TestScope from runTest
+        initializeSystemStatusAnimationScheduler(testScope = this)
+
+        // create and schedule high priority event
+        createAndScheduleFakePrivacyEvent()
+
+        // skip chip animation lifecycle and fast forward to SHOWING_PERSISTENT_DOT state
+        fastForwardAnimationToState(SHOWING_PERSISTENT_DOT)
+        assertEquals(SHOWING_PERSISTENT_DOT, systemStatusAnimationScheduler.getAnimationState())
+        verify(listener, times(1)).onSystemStatusAnimationTransitionToPersistentDot(any())
+
+        // remove persistent dot and verify that animationState changes to IDLE
+        systemStatusAnimationScheduler.removePersistentDot()
+        assertEquals(IDLE, systemStatusAnimationScheduler.getAnimationState())
+        verify(listener, times(1)).onHidePersistentDot()
+    }
+
+    @Test
+    fun testPrivacyDot_isRemovedDuringChipAnimation() = runTest {
+        // Instantiate class under test with TestScope from runTest
+        initializeSystemStatusAnimationScheduler(testScope = this)
+
+        // create and schedule high priority event
+        createAndScheduleFakePrivacyEvent()
+
+        // skip chip animation lifecycle and fast forward to RUNNING_CHIP_ANIM state
+        fastForwardAnimationToState(RUNNING_CHIP_ANIM)
+        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+
+        // request removal of persistent dot
+        systemStatusAnimationScheduler.removePersistentDot()
+
+        // skip display time and verify that disappear animation is run
+        advanceTimeBy(DISPLAY_LENGTH + 1)
+        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+
+        // skip disappear animation and verify that animationState changes to IDLE instead of
+        // SHOWING_PERSISTENT_DOT
+        animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
+        assertEquals(IDLE, systemStatusAnimationScheduler.getAnimationState())
+        // verify that the persistent dot callbacks are not invoked
+        verify(listener, never()).onSystemStatusAnimationTransitionToPersistentDot(any())
+        verify(listener, never()).onHidePersistentDot()
+    }
+
+    @Test
+    fun testNewEvent_isScheduled_whenPostedDuringRemovalAnimation() = runTest {
+        // Instantiate class under test with TestScope from runTest
+        initializeSystemStatusAnimationScheduler(testScope = this)
+
+        // create and schedule high priority event
+        createAndScheduleFakePrivacyEvent()
+
+        // skip chip animation lifecycle and fast forward to ANIMATING_OUT state
+        fastForwardAnimationToState(ANIMATING_OUT)
+        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        verify(listener, times(1)).onSystemStatusAnimationTransitionToPersistentDot(any())
+
+        // request removal of persistent dot
+        systemStatusAnimationScheduler.removePersistentDot()
+        testScheduler.runCurrent()
+
+        // schedule another high priority event while the event is animating out
+        createAndScheduleFakePrivacyEvent()
+
+        // verify that the state is still ANIMATING_OUT
+        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+
+        // skip disappear animation duration and verify that new state is ANIMATION_QUEUED
+        animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
+        testScheduler.runCurrent()
+        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+        // also verify that onHidePersistentDot callback is called
+        verify(listener, times(1)).onHidePersistentDot()
+    }
+
+    private fun TestScope.fastForwardAnimationToState(@SystemAnimationState animationState: Int) {
+        // this function should only be called directly after posting a status event
+        assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState())
+        if (animationState == IDLE || animationState == ANIMATION_QUEUED) return
+        // skip debounce delay
+        advanceTimeBy(DEBOUNCE_DELAY + 1)
+
+        // status chip starts animating in after debounce delay
+        assertEquals(ANIMATING_IN, systemStatusAnimationScheduler.getAnimationState())
+        verify(listener, times(1)).onSystemEventAnimationBegin()
+        if (animationState == ANIMATING_IN) return
+
+        // skip appear animation
+        animatorTestRule.advanceTimeBy(APPEAR_ANIMATION_DURATION)
+        advanceTimeBy(APPEAR_ANIMATION_DURATION)
+        assertEquals(RUNNING_CHIP_ANIM, systemStatusAnimationScheduler.getAnimationState())
+        if (animationState == RUNNING_CHIP_ANIM) return
+
+        // skip status chip display time
+        advanceTimeBy(DISPLAY_LENGTH + 1)
+        assertEquals(ANIMATING_OUT, systemStatusAnimationScheduler.getAnimationState())
+        verify(listener, times(1)).onSystemEventAnimationFinish(anyBoolean())
+        if (animationState == ANIMATING_OUT) return
+
+        // skip disappear animation
+        animatorTestRule.advanceTimeBy(DISAPPEAR_ANIMATION_DURATION)
+    }
+
+    private fun createAndScheduleFakePrivacyEvent(): OngoingPrivacyChip {
+        val privacyChip = OngoingPrivacyChip(mContext)
+        val fakePrivacyStatusEvent =
+            FakeStatusEvent(viewCreator = { privacyChip }, priority = 100, forceVisible = true)
+        systemStatusAnimationScheduler.onStatusEvent(fakePrivacyStatusEvent)
+        return privacyChip
+    }
+
+    private fun createAndScheduleFakeBatteryEvent(): BatteryStatusChip {
+        val batteryChip = BatteryStatusChip(mContext)
+        val fakeBatteryEvent =
+            FakeStatusEvent(viewCreator = { batteryChip }, priority = 50, forceVisible = false)
+        systemStatusAnimationScheduler.onStatusEvent(fakeBatteryEvent)
+        return batteryChip
+    }
+
+    private fun initializeSystemStatusAnimationScheduler(testScope: TestScope) {
+        systemStatusAnimationScheduler =
+            SystemStatusAnimationSchedulerImpl(
+                systemEventCoordinator,
+                chipAnimationController,
+                statusBarWindowController,
+                dumpManager,
+                systemClock,
+                CoroutineScope(StandardTestDispatcher(testScope.testScheduler))
+            )
+        // add a mock listener
+        systemStatusAnimationScheduler.addCallback(listener)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
index d6225c6..2de5705 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.lockscreen
 
+import android.app.smartspace.SmartspaceAction
 import android.app.smartspace.SmartspaceManager
 import android.app.smartspace.SmartspaceSession
 import android.app.smartspace.SmartspaceSession.OnTargetsAvailableListener
@@ -26,6 +27,7 @@
 import android.database.ContentObserver
 import android.graphics.drawable.Drawable
 import android.net.Uri
+import android.os.Bundle
 import android.os.Handler
 import android.os.UserHandle
 import android.provider.Settings
@@ -43,6 +45,7 @@
 import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener
 import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceView
 import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.plugins.WeatherData
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener
 import com.android.systemui.settings.UserTracker
@@ -54,6 +57,7 @@
 import com.android.systemui.util.concurrency.FakeExecution
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argThat
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.settings.SecureSettings
@@ -69,6 +73,7 @@
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.spy
+import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 import java.util.Optional
@@ -76,6 +81,13 @@
 
 @SmallTest
 class LockscreenSmartspaceControllerTest : SysuiTestCase() {
+    companion object {
+        const val SMARTSPACE_TIME_TOO_EARLY = 1000L
+        const val SMARTSPACE_TIME_JUST_RIGHT = 4000L
+        const val SMARTSPACE_TIME_TOO_LATE = 9000L
+        const val SMARTSPACE_CREATION_TIME = 1234L
+        const val SMARTSPACE_EXPIRY_TIME = 5678L
+    }
     @Mock
     private lateinit var featureFlags: FeatureFlags
     @Mock
@@ -224,6 +236,7 @@
                 smartspaceManager,
                 activityStarter,
                 falsingManager,
+                clock,
                 secureSettings,
                 userTracker,
                 contentResolver,
@@ -529,6 +542,190 @@
     }
 
     @Test
+    fun testSessionListener_ifWeatherExtraMissing_thenWeatherDataNotSent() {
+        connectSession()
+        clock.setCurrentTimeMillis(SMARTSPACE_TIME_JUST_RIGHT)
+        // WHEN we receive a list of targets
+        val targets = listOf(
+                makeTarget(1, userHandlePrimary, isSensitive = true),
+                makeTarget(2, userHandlePrimary, featureType = SmartspaceTarget.FEATURE_WEATHER)
+
+        )
+        sessionListener.onTargetsAvailable(targets)
+        verify(keyguardUpdateMonitor, times(0)).sendWeatherData(any())
+    }
+
+    @Test
+    fun testSessionListener_ifWeatherExtraIsMissingValues_thenWeatherDataNotSent() {
+        connectSession()
+
+        clock.setCurrentTimeMillis(SMARTSPACE_TIME_JUST_RIGHT)
+        // WHEN we receive a list of targets
+        val targets = listOf(
+                makeTarget(1, userHandlePrimary, isSensitive = true),
+                makeWeatherTargetWithExtras(
+                        id = 2,
+                        userHandle = userHandlePrimary,
+                        description = null,
+                        state = WeatherData.WeatherStateIcon.SUNNY.id,
+                        temperature = "32",
+                        useCelsius = null)
+
+        )
+
+        sessionListener.onTargetsAvailable(targets)
+
+        verify(keyguardUpdateMonitor, times(0)).sendWeatherData(any())
+    }
+
+    @Test
+    fun testSessionListener_ifTooEarly_thenWeatherDataNotSent() {
+        connectSession()
+
+        clock.setCurrentTimeMillis(SMARTSPACE_TIME_TOO_EARLY)
+        // WHEN we receive a list of targets
+        val targets = listOf(
+                makeWeatherTargetWithExtras(
+                        id = 1,
+                        userHandle = userHandleManaged,
+                        description = "Sunny",
+                        state = WeatherData.WeatherStateIcon.SUNNY.id,
+                        temperature = "32",
+                        useCelsius = false)
+        )
+        sessionListener.onTargetsAvailable(targets)
+        verify(keyguardUpdateMonitor, times(0)).sendWeatherData(any())
+    }
+
+    @Test
+    fun testSessionListener_ifOnTime_thenWeatherDataSent() {
+        connectSession()
+
+        clock.setCurrentTimeMillis(SMARTSPACE_TIME_JUST_RIGHT)
+        // WHEN we receive a list of targets
+        val targets = listOf(
+                makeWeatherTargetWithExtras(
+                        id = 1,
+                        userHandle = userHandleManaged,
+                        description = "Snow Showers",
+                        state = WeatherData.WeatherStateIcon.SNOW_SHOWERS_SNOW.id,
+                        temperature = "-1",
+                        useCelsius = false)
+        )
+        sessionListener.onTargetsAvailable(targets)
+        verify(keyguardUpdateMonitor).sendWeatherData(argThat { w ->
+            w.description == "Snow Showers" &&
+                    w.state == WeatherData.WeatherStateIcon.SNOW_SHOWERS_SNOW &&
+                    w.temperature == -1 && !w.useCelsius
+        })
+    }
+
+    @Test
+    fun testSessionListener_ifTooLate_thenWeatherDataNotSent() {
+        connectSession()
+
+        clock.setCurrentTimeMillis(SMARTSPACE_TIME_TOO_LATE)
+        // WHEN we receive a list of targets
+        val targets = listOf(
+                makeWeatherTargetWithExtras(
+                        id = 1,
+                        userHandle = userHandleManaged,
+                        description = "Sunny",
+                        state = WeatherData.WeatherStateIcon.SUNNY.id,
+                        temperature = "72",
+                        useCelsius = false)
+        )
+        sessionListener.onTargetsAvailable(targets)
+        verify(keyguardUpdateMonitor, times(0)).sendWeatherData(any())
+    }
+
+    @Test
+    fun testSessionListener_onlyFirstWeatherDataSent() {
+        connectSession()
+
+        clock.setCurrentTimeMillis(SMARTSPACE_TIME_JUST_RIGHT)
+        // WHEN we receive a list of targets
+        val targets = listOf(
+                makeWeatherTargetWithExtras(
+                        id = 1,
+                        userHandle = userHandleManaged,
+                        description = "Sunny",
+                        state = WeatherData.WeatherStateIcon.SUNNY.id,
+                        temperature = "72",
+                        useCelsius = false),
+                makeWeatherTargetWithExtras(
+                        id = 2,
+                        userHandle = userHandleManaged,
+                        description = "Showers",
+                        state = WeatherData.WeatherStateIcon.SHOWERS_RAIN.id,
+                        temperature = "62",
+                        useCelsius = true)
+        )
+        sessionListener.onTargetsAvailable(targets)
+        verify(keyguardUpdateMonitor).sendWeatherData(argThat { w ->
+            w.description == "Sunny" &&
+                    w.state == WeatherData.WeatherStateIcon.SUNNY &&
+                    w.temperature == 72 && !w.useCelsius
+        })
+    }
+
+    @Test
+    fun testSessionListener_ifDecouplingEnabled_weatherDataUpdates() {
+        `when`(featureFlags.isEnabled(Flags.SMARTSPACE_DATE_WEATHER_DECOUPLED)).thenReturn(true)
+        connectSession()
+
+        clock.setCurrentTimeMillis(SMARTSPACE_TIME_JUST_RIGHT)
+        // WHEN we receive a list of targets
+        val targets = listOf(
+                makeTarget(1, userHandlePrimary, isSensitive = true),
+                makeTarget(2, userHandlePrimary),
+                makeTarget(3, userHandleManaged),
+                makeWeatherTargetWithExtras(
+                        id = 4,
+                        userHandle = userHandlePrimary,
+                        description = "Flurries",
+                        state = WeatherData.WeatherStateIcon.FLURRIES.id,
+                        temperature = "0",
+                        useCelsius = true)
+        )
+
+        sessionListener.onTargetsAvailable(targets)
+
+        verify(keyguardUpdateMonitor).sendWeatherData(argThat { w ->
+            w.description == "Flurries" &&
+                    w.state == WeatherData.WeatherStateIcon.FLURRIES &&
+                    w.temperature == 0 && w.useCelsius
+        })
+    }
+
+    @Test
+    fun testSessionListener_ifDecouplingDisabled_weatherDataUpdates() {
+        `when`(featureFlags.isEnabled(Flags.SMARTSPACE_DATE_WEATHER_DECOUPLED)).thenReturn(false)
+        connectSession()
+
+        clock.setCurrentTimeMillis(SMARTSPACE_TIME_JUST_RIGHT)
+        // WHEN we receive a list of targets
+        val targets = listOf(
+                makeWeatherTargetWithExtras(
+                        id = 1,
+                        userHandle = userHandlePrimary,
+                        description = "Sunny",
+                        state = WeatherData.WeatherStateIcon.SUNNY.id,
+                        temperature = "32",
+                        useCelsius = false),
+                makeTarget(2, userHandlePrimary, isSensitive = true)
+        )
+
+        sessionListener.onTargetsAvailable(targets)
+
+        verify(keyguardUpdateMonitor).sendWeatherData(argThat { w ->
+            w.description == "Sunny" &&
+                    w.state == WeatherData.WeatherStateIcon.SUNNY &&
+                    w.temperature == 32 && !w.useCelsius
+        })
+    }
+
+    @Test
     fun testSettingsAreReloaded() {
         // GIVEN a connected session where the privacy settings later flip to false
         connectSession()
@@ -740,7 +937,7 @@
         return userInfo
     }
 
-    fun makeTarget(
+    private fun makeTarget(
         id: Int,
         userHandle: UserHandle,
         isSensitive: Boolean = false,
@@ -755,6 +952,38 @@
                 .build()
     }
 
+    private fun makeWeatherTargetWithExtras(
+            id: Int,
+            userHandle: UserHandle,
+            description: String?,
+            state: Int?,
+            temperature: String?,
+            useCelsius: Boolean?
+    ): SmartspaceTarget {
+        val mockWeatherBundle = mock(Bundle::class.java).apply {
+            `when`(getString(WeatherData.DESCRIPTION_KEY)).thenReturn(description)
+            if (state != null)
+                `when`(getInt(eq(WeatherData.STATE_KEY), any())).thenReturn(state)
+            `when`(getString(WeatherData.TEMPERATURE_KEY)).thenReturn(temperature)
+            `when`(containsKey(WeatherData.USE_CELSIUS_KEY)).thenReturn(useCelsius != null)
+            if (useCelsius != null)
+                `when`(getBoolean(WeatherData.USE_CELSIUS_KEY)).thenReturn(useCelsius)
+        }
+
+        val mockBaseAction = mock(SmartspaceAction::class.java)
+        `when`(mockBaseAction.extras).thenReturn(mockWeatherBundle)
+        return SmartspaceTarget.Builder(
+                "targetWithWeatherExtras$id",
+                ComponentName("testpackage", "testclass$id"),
+                userHandle)
+                .setSensitive(false)
+                .setFeatureType(SmartspaceTarget.FEATURE_WEATHER)
+                .setBaseAction(mockBaseAction)
+                .setExpiryTimeMillis(SMARTSPACE_EXPIRY_TIME)
+                .setCreationTimeMillis(SMARTSPACE_CREATION_TIME)
+                .build()
+    }
+
     private fun setAllowPrivateNotifications(user: UserHandle, value: Boolean) {
         `when`(secureSettings.getIntForUser(
                 eq(PRIVATE_LOCKSCREEN_SETTING),
@@ -780,9 +1009,6 @@
             override fun setPrimaryTextColor(color: Int) {
             }
 
-            override fun setIsDreaming(isDreaming: Boolean) {
-            }
-
             override fun setUiSurface(uiSurface: String) {
             }
 
@@ -811,9 +1037,6 @@
             override fun setPrimaryTextColor(color: Int) {
             }
 
-            override fun setIsDreaming(isDreaming: Boolean) {
-            }
-
             override fun setUiSurface(uiSurface: String) {
             }
 
@@ -838,9 +1061,6 @@
             override fun setPrimaryTextColor(color: Int) {
             }
 
-            override fun setIsDreaming(isDreaming: Boolean) {
-            }
-
             override fun setUiSurface(uiSurface: String) {
             }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt
new file mode 100644
index 0000000..7a67796
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLoggerTest.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel
+import com.android.systemui.plugins.log.LogcatEchoTracker
+import com.android.systemui.statusbar.StatusBarState
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class NotificationWakeUpCoordinatorLoggerTest : SysuiTestCase() {
+
+    private val logBufferCounter = LogBufferCounter()
+    private lateinit var logger: NotificationWakeUpCoordinatorLogger
+
+    private fun verifyDidLog(times: Int) {
+        logBufferCounter.verifyDidLog(times)
+    }
+
+    @Before
+    fun setup() {
+        logger = NotificationWakeUpCoordinatorLogger(logBufferCounter.logBuffer)
+    }
+
+    @Test
+    fun setDozeAmountWillThrottleFractionalUpdates() {
+        logger.logSetDozeAmount(0f, 0f, "source1", StatusBarState.SHADE, changed = false)
+        verifyDidLog(1)
+        logger.logSetDozeAmount(0.1f, 0.1f, "source1", StatusBarState.SHADE, changed = true)
+        verifyDidLog(1)
+        logger.logSetDozeAmount(0.2f, 0.2f, "source1", StatusBarState.SHADE, changed = true)
+        logger.logSetDozeAmount(0.3f, 0.3f, "source1", StatusBarState.SHADE, changed = true)
+        logger.logSetDozeAmount(0.4f, 0.4f, "source1", StatusBarState.SHADE, changed = true)
+        logger.logSetDozeAmount(0.5f, 0.5f, "source1", StatusBarState.SHADE, changed = true)
+        verifyDidLog(0)
+        logger.logSetDozeAmount(1f, 1f, "source1", StatusBarState.SHADE, changed = true)
+        verifyDidLog(1)
+    }
+
+    @Test
+    fun setDozeAmountWillIncludeFractionalUpdatesWhenStateChanges() {
+        logger.logSetDozeAmount(0f, 0f, "source1", StatusBarState.SHADE, changed = false)
+        verifyDidLog(1)
+        logger.logSetDozeAmount(0.1f, 0.1f, "source1", StatusBarState.SHADE, changed = true)
+        verifyDidLog(1)
+        logger.logSetDozeAmount(0.2f, 0.2f, "source1", StatusBarState.SHADE, changed = true)
+        logger.logSetDozeAmount(0.3f, 0.3f, "source1", StatusBarState.SHADE, changed = true)
+        logger.logSetDozeAmount(0.4f, 0.4f, "source1", StatusBarState.SHADE, changed = true)
+        logger.logSetDozeAmount(0.5f, 0.5f, "source1", StatusBarState.SHADE, changed = true)
+        verifyDidLog(0)
+        logger.logSetDozeAmount(0.5f, 0.5f, "source1", StatusBarState.KEYGUARD, changed = false)
+        verifyDidLog(1)
+    }
+
+    @Test
+    fun setDozeAmountWillIncludeFractionalUpdatesWhenSourceChanges() {
+        logger.logSetDozeAmount(0f, 0f, "source1", StatusBarState.SHADE, changed = false)
+        verifyDidLog(1)
+        logger.logSetDozeAmount(0.1f, 0.1f, "source1", StatusBarState.SHADE, changed = true)
+        verifyDidLog(1)
+        logger.logSetDozeAmount(0.2f, 0.2f, "source1", StatusBarState.SHADE, changed = true)
+        logger.logSetDozeAmount(0.3f, 0.3f, "source1", StatusBarState.SHADE, changed = true)
+        logger.logSetDozeAmount(0.4f, 0.4f, "source1", StatusBarState.SHADE, changed = true)
+        logger.logSetDozeAmount(0.5f, 0.5f, "source1", StatusBarState.SHADE, changed = true)
+        verifyDidLog(0)
+        logger.logSetDozeAmount(0.5f, 0.5f, "source2", StatusBarState.SHADE, changed = false)
+        verifyDidLog(1)
+    }
+
+    class LogBufferCounter {
+        val recentLogs = mutableListOf<Pair<String, LogLevel>>()
+        val tracker =
+            object : LogcatEchoTracker {
+                override val logInBackgroundThread: Boolean = false
+                override fun isBufferLoggable(bufferName: String, level: LogLevel): Boolean = false
+                override fun isTagLoggable(tagName: String, level: LogLevel): Boolean {
+                    recentLogs.add(tagName to level)
+                    return true
+                }
+            }
+        val logBuffer =
+            LogBuffer(name = "test", maxSize = 1, logcatEchoTracker = tracker, systrace = false)
+
+        fun verifyDidLog(times: Int) {
+            assertThat(recentLogs).hasSize(times)
+            recentLogs.clear()
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
index 94e3e6c..edb2965 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
@@ -105,6 +105,7 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.Spy;
+import org.mockito.stubbing.Answer;
 
 import java.util.Arrays;
 import java.util.Collection;
@@ -376,6 +377,90 @@
     }
 
     @Test
+    public void testScheduleBuildNotificationListWhenChannelChanged() {
+        // GIVEN
+        final NotificationEntryBuilder neb = buildNotif(TEST_PACKAGE, 48);
+        final NotificationChannel channel = new NotificationChannel(
+                "channelId",
+                "channelName",
+                NotificationManager.IMPORTANCE_DEFAULT);
+        neb.setChannel(channel);
+
+        final NotifEvent notif = mNoMan.postNotif(neb);
+        final NotificationEntry entry = mCollectionListener.getEntry(notif.key);
+
+        when(mMainHandler.hasCallbacks(any())).thenReturn(false);
+
+        clearInvocations(mBuildListener);
+
+        // WHEN
+        mNotifHandler.onNotificationChannelModified(TEST_PACKAGE,
+                entry.getSbn().getUser(), channel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
+
+        // THEN
+        verify(mMainHandler).postDelayed(any(), eq(1000L));
+    }
+
+    @Test
+    public void testCancelScheduledBuildNotificationListEventWhenNotifUpdatedSynchronously() {
+        // GIVEN
+        final NotificationEntry entry1 = buildNotif(TEST_PACKAGE, 1)
+                .setGroup(mContext, "group_1")
+                .build();
+        final NotificationEntry entry2 = buildNotif(TEST_PACKAGE, 2)
+                .setGroup(mContext, "group_1")
+                .setContentTitle(mContext, "New version")
+                .build();
+        final NotificationEntry entry3 = buildNotif(TEST_PACKAGE, 3)
+                .setGroup(mContext, "group_1")
+                .build();
+
+        final List<CoalescedEvent> entriesToBePosted = Arrays.asList(
+                new CoalescedEvent(entry1.getKey(), 0, entry1.getSbn(), entry1.getRanking(), null),
+                new CoalescedEvent(entry2.getKey(), 1, entry2.getSbn(), entry2.getRanking(), null),
+                new CoalescedEvent(entry3.getKey(), 2, entry3.getSbn(), entry3.getRanking(), null)
+        );
+
+        when(mMainHandler.hasCallbacks(any())).thenReturn(true);
+
+        // WHEN
+        mNotifHandler.onNotificationBatchPosted(entriesToBePosted);
+
+        // THEN
+        verify(mMainHandler).removeCallbacks(any());
+    }
+
+    @Test
+    public void testBuildNotificationListWhenChannelChanged() {
+        // GIVEN
+        final NotificationEntryBuilder neb = buildNotif(TEST_PACKAGE, 48);
+        final NotificationChannel channel = new NotificationChannel(
+                "channelId",
+                "channelName",
+                NotificationManager.IMPORTANCE_DEFAULT);
+        neb.setChannel(channel);
+
+        final NotifEvent notif = mNoMan.postNotif(neb);
+        final NotificationEntry entry = mCollectionListener.getEntry(notif.key);
+
+        when(mMainHandler.hasCallbacks(any())).thenReturn(false);
+        when(mMainHandler.postDelayed(any(), eq(1000L))).thenAnswer((Answer) invocation -> {
+            final Runnable runnable = invocation.getArgument(0);
+            runnable.run();
+            return null;
+        });
+
+        clearInvocations(mBuildListener);
+
+        // WHEN
+        mNotifHandler.onNotificationChannelModified(TEST_PACKAGE,
+                entry.getSbn().getUser(), channel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
+
+        // THEN
+        verifyBuiltList(List.of(entry));
+    }
+
+    @Test
     public void testRankingsAreUpdatedForOtherNotifs() {
         // GIVEN a collection with one notif
         NotifEvent notif1 = mNoMan.postNotif(buildNotif(TEST_PACKAGE, 3)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt
index bd03903..33a838e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt
@@ -20,6 +20,7 @@
 import android.app.StatsManager
 import android.graphics.Bitmap
 import android.graphics.drawable.Icon
+import android.stats.sysui.NotificationEnums
 import android.testing.AndroidTestingRunner
 import android.util.StatsEvent
 import androidx.test.filters.SmallTest
@@ -31,10 +32,12 @@
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Expect
 import com.google.common.truth.Truth.assertThat
 import java.lang.RuntimeException
 import kotlinx.coroutines.Dispatchers
 import org.junit.Before
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
@@ -45,6 +48,8 @@
 @RunWith(AndroidTestingRunner::class)
 class NotificationMemoryLoggerTest : SysuiTestCase() {
 
+    @Rule @JvmField val expect = Expect.create()
+
     private val bgExecutor = FakeExecutor(FakeSystemClock())
     private val immediate = Dispatchers.Main.immediate
 
@@ -132,6 +137,123 @@
             .isEqualTo(StatsManager.PULL_SKIP)
     }
 
+    @Test
+    fun aggregateMemoryUsageData_returnsCorrectlyAggregatedSamePackageData() {
+        val usage = getPresetMemoryUsages()
+        val aggregateUsage = aggregateMemoryUsageData(usage)
+
+        assertThat(aggregateUsage).hasSize(3)
+        assertThat(aggregateUsage)
+            .containsKey(Pair("package 1", NotificationEnums.STYLE_BIG_PICTURE))
+
+        // Aggregated fields
+        val aggregatedData =
+            aggregateUsage[Pair("package 1", NotificationEnums.STYLE_BIG_PICTURE)]!!
+        val presetUsage1 = usage[0]
+        val presetUsage2 = usage[1]
+        assertAggregatedData(
+            aggregatedData,
+            2,
+            2,
+            smallIconObject =
+                presetUsage1.objectUsage.smallIcon + presetUsage2.objectUsage.smallIcon,
+            smallIconBitmapCount = 2,
+            largeIconObject =
+                presetUsage1.objectUsage.largeIcon + presetUsage2.objectUsage.largeIcon,
+            largeIconBitmapCount = 2,
+            bigPictureObject =
+                presetUsage1.objectUsage.bigPicture + presetUsage2.objectUsage.bigPicture,
+            bigPictureBitmapCount = 2,
+            extras = presetUsage1.objectUsage.extras + presetUsage2.objectUsage.extras,
+            extenders = presetUsage1.objectUsage.extender + presetUsage2.objectUsage.extender,
+            // Only totals need to be summarized.
+            smallIconViews =
+                presetUsage1.viewUsage[0].smallIcon + presetUsage2.viewUsage[0].smallIcon,
+            largeIconViews =
+                presetUsage1.viewUsage[0].largeIcon + presetUsage2.viewUsage[0].largeIcon,
+            systemIconViews =
+                presetUsage1.viewUsage[0].systemIcons + presetUsage2.viewUsage[0].systemIcons,
+            styleViews = presetUsage1.viewUsage[0].style + presetUsage2.viewUsage[0].style,
+            customViews =
+                presetUsage1.viewUsage[0].customViews + presetUsage2.viewUsage[0].customViews,
+            softwareBitmaps =
+                presetUsage1.viewUsage[0].softwareBitmapsPenalty +
+                    presetUsage2.viewUsage[0].softwareBitmapsPenalty,
+            seenCount = 0
+        )
+    }
+
+    @Test
+    fun aggregateMemoryUsageData_correctlySeparatesDifferentStyles() {
+        val usage = getPresetMemoryUsages()
+        val aggregateUsage = aggregateMemoryUsageData(usage)
+
+        assertThat(aggregateUsage).hasSize(3)
+        assertThat(aggregateUsage)
+            .containsKey(Pair("package 1", NotificationEnums.STYLE_BIG_PICTURE))
+        assertThat(aggregateUsage).containsKey(Pair("package 1", NotificationEnums.STYLE_BIG_TEXT))
+
+        // Different style should be separate
+        val separateStyleData =
+            aggregateUsage[Pair("package 1", NotificationEnums.STYLE_BIG_TEXT)]!!
+        val presetUsage = usage[2]
+        assertAggregatedData(
+            separateStyleData,
+            1,
+            1,
+            presetUsage.objectUsage.smallIcon,
+            1,
+            presetUsage.objectUsage.largeIcon,
+            1,
+            presetUsage.objectUsage.bigPicture,
+            1,
+            presetUsage.objectUsage.extras,
+            presetUsage.objectUsage.extender,
+            presetUsage.viewUsage[0].smallIcon,
+            presetUsage.viewUsage[0].largeIcon,
+            presetUsage.viewUsage[0].systemIcons,
+            presetUsage.viewUsage[0].style,
+            presetUsage.viewUsage[0].customViews,
+            presetUsage.viewUsage[0].softwareBitmapsPenalty,
+            0
+        )
+    }
+
+    @Test
+    fun aggregateMemoryUsageData_correctlySeparatesDifferentProcess() {
+        val usage = getPresetMemoryUsages()
+        val aggregateUsage = aggregateMemoryUsageData(usage)
+
+        assertThat(aggregateUsage).hasSize(3)
+        assertThat(aggregateUsage)
+            .containsKey(Pair("package 2", NotificationEnums.STYLE_BIG_PICTURE))
+
+        // Different UID/package should also be separate
+        val separatePackageData =
+            aggregateUsage[Pair("package 2", NotificationEnums.STYLE_BIG_PICTURE)]!!
+        val presetUsage = usage[3]
+        assertAggregatedData(
+            separatePackageData,
+            1,
+            1,
+            presetUsage.objectUsage.smallIcon,
+            1,
+            presetUsage.objectUsage.largeIcon,
+            1,
+            presetUsage.objectUsage.bigPicture,
+            1,
+            presetUsage.objectUsage.extras,
+            presetUsage.objectUsage.extender,
+            presetUsage.viewUsage[0].smallIcon,
+            presetUsage.viewUsage[0].largeIcon,
+            presetUsage.viewUsage[0].systemIcons,
+            presetUsage.viewUsage[0].style,
+            presetUsage.viewUsage[0].customViews,
+            presetUsage.viewUsage[0].softwareBitmapsPenalty,
+            0
+        )
+    }
+
     private fun createLoggerWithNotifications(
         notifications: List<Notification>
     ): NotificationMemoryLogger {
@@ -143,4 +265,182 @@
         whenever(pipeline.allNotifs).thenReturn(notifications)
         return NotificationMemoryLogger(pipeline, statsManager, immediate, bgExecutor)
     }
+
+    /**
+     * Short hand for making sure the passed NotificationMemoryUseAtomBuilder object contains
+     * expected values.
+     */
+    private fun assertAggregatedData(
+        value: NotificationMemoryLogger.NotificationMemoryUseAtomBuilder,
+        count: Int,
+        countWithInflatedViews: Int,
+        smallIconObject: Int,
+        smallIconBitmapCount: Int,
+        largeIconObject: Int,
+        largeIconBitmapCount: Int,
+        bigPictureObject: Int,
+        bigPictureBitmapCount: Int,
+        extras: Int,
+        extenders: Int,
+        smallIconViews: Int,
+        largeIconViews: Int,
+        systemIconViews: Int,
+        styleViews: Int,
+        customViews: Int,
+        softwareBitmaps: Int,
+        seenCount: Int
+    ) {
+        expect.withMessage("count").that(value.count).isEqualTo(count)
+        expect
+            .withMessage("countWithInflatedViews")
+            .that(value.countWithInflatedViews)
+            .isEqualTo(countWithInflatedViews)
+        expect.withMessage("smallIconObject").that(value.smallIconObject).isEqualTo(smallIconObject)
+        expect
+            .withMessage("smallIconBitmapCount")
+            .that(value.smallIconBitmapCount)
+            .isEqualTo(smallIconBitmapCount)
+        expect.withMessage("largeIconObject").that(value.largeIconObject).isEqualTo(largeIconObject)
+        expect
+            .withMessage("largeIconBitmapCount")
+            .that(value.largeIconBitmapCount)
+            .isEqualTo(largeIconBitmapCount)
+        expect
+            .withMessage("bigPictureObject")
+            .that(value.bigPictureObject)
+            .isEqualTo(bigPictureObject)
+        expect
+            .withMessage("bigPictureBitmapCount")
+            .that(value.bigPictureBitmapCount)
+            .isEqualTo(bigPictureBitmapCount)
+        expect.withMessage("extras").that(value.extras).isEqualTo(extras)
+        expect.withMessage("extenders").that(value.extenders).isEqualTo(extenders)
+        expect.withMessage("smallIconViews").that(value.smallIconViews).isEqualTo(smallIconViews)
+        expect.withMessage("largeIconViews").that(value.largeIconViews).isEqualTo(largeIconViews)
+        expect.withMessage("systemIconViews").that(value.systemIconViews).isEqualTo(systemIconViews)
+        expect.withMessage("styleViews").that(value.styleViews).isEqualTo(styleViews)
+        expect.withMessage("customViews").that(value.customViews).isEqualTo(customViews)
+        expect.withMessage("softwareBitmaps").that(value.softwareBitmaps).isEqualTo(softwareBitmaps)
+        expect.withMessage("seenCount").that(value.seenCount).isEqualTo(seenCount)
+    }
+
+    /** Generates a static set of [NotificationMemoryUsage] objects. */
+    private fun getPresetMemoryUsages() =
+        listOf(
+            // A pair of notifications that have to be aggregated, same UID and style
+            NotificationMemoryUsage(
+                "package 1",
+                384,
+                "key1",
+                Notification.Builder(context).setStyle(Notification.BigPictureStyle()).build(),
+                NotificationObjectUsage(
+                    23,
+                    45,
+                    67,
+                    NotificationEnums.STYLE_BIG_PICTURE,
+                    12,
+                    483,
+                    4382,
+                    true
+                ),
+                listOf(
+                    NotificationViewUsage(ViewType.TOTAL, 493, 584, 4833, 584, 4888, 5843),
+                    NotificationViewUsage(
+                        ViewType.PRIVATE_CONTRACTED_VIEW,
+                        100,
+                        250,
+                        300,
+                        594,
+                        6000,
+                        5843
+                    )
+                )
+            ),
+            NotificationMemoryUsage(
+                "package 1",
+                384,
+                "key2",
+                Notification.Builder(context).setStyle(Notification.BigPictureStyle()).build(),
+                NotificationObjectUsage(
+                    77,
+                    54,
+                    34,
+                    NotificationEnums.STYLE_BIG_PICTURE,
+                    77,
+                    432,
+                    2342,
+                    true
+                ),
+                listOf(
+                    NotificationViewUsage(ViewType.TOTAL, 3245, 1234, 7653, 543, 765, 7655),
+                    NotificationViewUsage(
+                        ViewType.PRIVATE_CONTRACTED_VIEW,
+                        160,
+                        350,
+                        300,
+                        5544,
+                        66500,
+                        5433
+                    )
+                )
+            ),
+            // Different style is different aggregation
+            NotificationMemoryUsage(
+                "package 1",
+                384,
+                "key2",
+                Notification.Builder(context).setStyle(Notification.BigTextStyle()).build(),
+                NotificationObjectUsage(
+                    77,
+                    54,
+                    34,
+                    NotificationEnums.STYLE_BIG_TEXT,
+                    77,
+                    432,
+                    2342,
+                    true
+                ),
+                listOf(
+                    NotificationViewUsage(ViewType.TOTAL, 3245, 1234, 7653, 543, 765, 7655),
+                    NotificationViewUsage(
+                        ViewType.PRIVATE_CONTRACTED_VIEW,
+                        160,
+                        350,
+                        300,
+                        5544,
+                        66500,
+                        5433
+                    )
+                )
+            ),
+            // Different package is also different aggregation
+            NotificationMemoryUsage(
+                "package 2",
+                684,
+                "key2",
+                Notification.Builder(context).setStyle(Notification.BigPictureStyle()).build(),
+                NotificationObjectUsage(
+                    32,
+                    654,
+                    234,
+                    NotificationEnums.STYLE_BIG_PICTURE,
+                    211,
+                    776,
+                    435,
+                    true
+                ),
+                listOf(
+                    NotificationViewUsage(ViewType.TOTAL, 4355, 6543, 4322, 5435, 6546, 65485),
+                    NotificationViewUsage(
+                        ViewType.PRIVATE_CONTRACTED_VIEW,
+                        6546,
+                        7657,
+                        4353,
+                        6546,
+                        76575,
+                        54654
+                    )
+                )
+            )
+        )
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
index 680a323..78da782 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
@@ -20,6 +20,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
@@ -227,14 +228,154 @@
     }
 
     @Test
-    public void testHandleUpEvent_menuRow() {
-        when(mSwipeHelper.getCurrentMenuRow()).thenReturn(mMenuRow);
-        doNothing().when(mSwipeHelper).handleMenuRowSwipe(mEvent, mView, 0, mMenuRow);
+    public void testHandleUpEvent_menuRowWithoutMenu_dismiss() {
+        doNothing().when(mSwipeHelper).dismiss(any(), anyFloat());
+        doReturn(true).when(mSwipeHelper).isDismissGesture(any());
+        doReturn(true).when(mSwipeHelper).swipedFarEnough();
+        when(mMenuRow.shouldShowMenu()).thenReturn(true);
+        mSwipeHelper.setCurrentMenuRow(mMenuRow);
 
         assertTrue("Menu row exists",
                 mSwipeHelper.handleUpEvent(mEvent, mView, 0, 0));
         verify(mMenuRow, times(1)).onTouchEnd();
-        verify(mSwipeHelper, times(1)).handleMenuRowSwipe(mEvent, mView, 0, mMenuRow);
+        verify(mSwipeHelper, times(1)).isDismissGesture(mEvent);
+        verify(mSwipeHelper, times(1)).dismiss(mView, 0);
+        verify(mSwipeHelper, never()).isFalseGesture();
+    }
+
+    @Test
+    public void testHandleUpEvent_menuRowWithoutMenu_snapback() {
+        doNothing().when(mSwipeHelper).snapChild(any(), anyInt(), anyFloat());
+        doReturn(false).when(mSwipeHelper).isDismissGesture(any());
+        doReturn(true).when(mSwipeHelper).swipedFarEnough();
+        when(mMenuRow.shouldShowMenu()).thenReturn(true);
+        mSwipeHelper.setCurrentMenuRow(mMenuRow);
+
+        assertTrue("Menu row exists",
+                mSwipeHelper.handleUpEvent(mEvent, mView, 0, 0));
+        verify(mMenuRow, times(1)).onTouchEnd();
+        verify(mSwipeHelper, times(1)).isDismissGesture(mEvent);
+        verify(mSwipeHelper, times(1)).snapClosed(mView, 0);
+        verify(mMenuRow, times(1)).onSnapClosed();
+        verify(mSwipeHelper, never()).isFalseGesture();
+    }
+
+    @Test
+    public void testHandleUpEvent_menuRowWithOpenMenu_dismissed() {
+        doNothing().when(mSwipeHelper).dismiss(any(), anyFloat());
+        doReturn(true).when(mSwipeHelper).isDismissGesture(any());
+        doReturn(true).when(mSwipeHelper).swipedFarEnough();
+        when(mMenuRow.shouldShowMenu()).thenReturn(true);
+        when(mMenuRow.isSnappedAndOnSameSide()).thenReturn(true);
+        mSwipeHelper.setCurrentMenuRow(mMenuRow);
+
+        assertTrue("Menu row exists",
+                mSwipeHelper.handleUpEvent(mEvent, mView, 0, 0));
+        verify(mMenuRow, times(1)).onTouchEnd();
+        verify(mSwipeHelper, times(1)).isDismissGesture(mEvent);
+        verify(mSwipeHelper, times(1)).dismiss(mView, 0);
+        verify(mSwipeHelper, never()).isFalseGesture();
+    }
+
+    @Test
+    public void testHandleUpEvent_menuRowWithOpenMenu_snapback() {
+        doNothing().when(mSwipeHelper).snapChild(any(), anyInt(), anyFloat());
+        doReturn(false).when(mSwipeHelper).isDismissGesture(any());
+        doReturn(true).when(mSwipeHelper).swipedFarEnough();
+        when(mMenuRow.shouldShowMenu()).thenReturn(true);
+        when(mMenuRow.isSnappedAndOnSameSide()).thenReturn(true);
+        mSwipeHelper.setCurrentMenuRow(mMenuRow);
+
+        assertTrue("Menu row exists",
+                mSwipeHelper.handleUpEvent(mEvent, mView, 0, 0));
+        verify(mMenuRow, times(1)).onTouchEnd();
+        verify(mSwipeHelper, times(1)).isDismissGesture(mEvent);
+        verify(mSwipeHelper, times(1)).snapClosed(mView, 0);
+        verify(mMenuRow, times(1)).onSnapClosed();
+        verify(mSwipeHelper, never()).isFalseGesture();
+    }
+
+    @Test
+    public void testHandleUpEvent_menuRowWithClosedMenu_dismissed() {
+        doNothing().when(mSwipeHelper).dismiss(any(), anyFloat());
+        doReturn(true).when(mSwipeHelper).isDismissGesture(any());
+        doReturn(true).when(mSwipeHelper).swipedFarEnough();
+        when(mMenuRow.shouldShowMenu()).thenReturn(true);
+        when(mMenuRow.isSnappedAndOnSameSide()).thenReturn(false);
+        mSwipeHelper.setCurrentMenuRow(mMenuRow);
+
+        assertTrue("Menu row exists",
+                mSwipeHelper.handleUpEvent(mEvent, mView, 0, 0));
+        verify(mMenuRow, times(1)).onTouchEnd();
+        verify(mSwipeHelper, times(1)).isDismissGesture(mEvent);
+        verify(mSwipeHelper, times(1)).dismiss(mView, 0);
+        verify(mSwipeHelper, never()).isFalseGesture();
+    }
+
+    @Test
+    public void testHandleUpEvent_menuRowWithClosedMenu_snapback() {
+        doNothing().when(mSwipeHelper).snapChild(any(), anyInt(), anyFloat());
+        doReturn(false).when(mSwipeHelper).isDismissGesture(any());
+        doReturn(true).when(mSwipeHelper).swipedFarEnough();
+        when(mMenuRow.shouldShowMenu()).thenReturn(true);
+        when(mMenuRow.isSnappedAndOnSameSide()).thenReturn(false);
+        mSwipeHelper.setCurrentMenuRow(mMenuRow);
+
+        assertTrue("Menu row exists",
+                mSwipeHelper.handleUpEvent(mEvent, mView, 0, 0));
+        verify(mMenuRow, times(1)).onTouchEnd();
+        verify(mSwipeHelper, times(1)).isDismissGesture(mEvent);
+        verify(mSwipeHelper, times(1)).snapClosed(mView, 0);
+        verify(mMenuRow, times(1)).onSnapClosed();
+        verify(mSwipeHelper, never()).isFalseGesture();
+    }
+
+    @Test
+    public void testIsDismissGesture() {
+        doReturn(false).when(mSwipeHelper).isFalseGesture();
+        doReturn(true).when(mSwipeHelper).swipedFarEnough();
+        doReturn(true).when(mSwipeHelper).swipedFastEnough();
+        when(mCallback.canChildBeDismissedInDirection(any(), anyBoolean())).thenReturn(true);
+        when(mEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_UP);
+
+        assertTrue("Should be a dismiss gesture", mSwipeHelper.isDismissGesture(mEvent));
+        verify(mSwipeHelper, times(1)).isFalseGesture();
+    }
+
+    @Test
+    public void testIsDismissGesture_falseGesture() {
+        doReturn(true).when(mSwipeHelper).isFalseGesture();
+        doReturn(true).when(mSwipeHelper).swipedFarEnough();
+        doReturn(true).when(mSwipeHelper).swipedFastEnough();
+        when(mCallback.canChildBeDismissedInDirection(any(), anyBoolean())).thenReturn(true);
+        when(mEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_UP);
+
+        assertFalse("False gesture should stop dismissal", mSwipeHelper.isDismissGesture(mEvent));
+        verify(mSwipeHelper, times(1)).isFalseGesture();
+    }
+
+    @Test
+    public void testIsDismissGesture_farEnough() {
+        doReturn(false).when(mSwipeHelper).isFalseGesture();
+        doReturn(true).when(mSwipeHelper).swipedFarEnough();
+        doReturn(false).when(mSwipeHelper).swipedFastEnough();
+        when(mCallback.canChildBeDismissedInDirection(any(), anyBoolean())).thenReturn(true);
+        when(mEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_UP);
+
+        assertTrue("Should be a dismissal", mSwipeHelper.isDismissGesture(mEvent));
+        verify(mSwipeHelper, times(1)).isFalseGesture();
+    }
+
+    @Test
+    public void testIsDismissGesture_notFarOrFastEnough() {
+        doReturn(false).when(mSwipeHelper).isFalseGesture();
+        doReturn(false).when(mSwipeHelper).swipedFarEnough();
+        doReturn(false).when(mSwipeHelper).swipedFastEnough();
+        when(mCallback.canChildBeDismissedInDirection(any(), anyBoolean())).thenReturn(true);
+        when(mEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_UP);
+
+        assertFalse("Should not be a dismissal", mSwipeHelper.isDismissGesture(mEvent));
+        verify(mSwipeHelper, times(1)).isFalseGesture();
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index f568547..e680a4e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -53,7 +53,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.qs.AutoAddTracker;
-import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.ReduceBrightColorsController;
 import com.android.systemui.qs.SettingObserver;
 import com.android.systemui.qs.external.CustomTile;
@@ -104,7 +104,7 @@
 
     private static final int USER = 0;
 
-    @Mock private QSTileHost mQsTileHost;
+    @Mock private QSHost mQsHost;
     @Mock private AutoAddTracker mAutoAddTracker;
     @Mock private CastController mCastController;
     @Mock private HotspotController mHotspotController;
@@ -144,7 +144,7 @@
                 R.string.safety_quick_settings_tile_class, TEST_CUSTOM_SAFETY_CLASS);
 
         when(mAutoAddTrackerBuilder.build()).thenReturn(mAutoAddTracker);
-        when(mQsTileHost.getUserContext()).thenReturn(mUserContext);
+        when(mQsHost.getUserContext()).thenReturn(mUserContext);
         when(mUserContext.getUser()).thenReturn(UserHandle.of(USER));
         mPackageManager = Mockito.spy(mContext.getPackageManager());
         when(mPackageManager.getPermissionControllerPackageName())
@@ -174,7 +174,7 @@
             WalletController walletController,
             SafetyController safetyController,
             @Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) {
-        return new AutoTileManager(context, autoAddTrackerBuilder, mQsTileHost,
+        return new AutoTileManager(context, autoAddTrackerBuilder, mQsHost,
                 Handler.createAsync(TestableLooper.get(this).getLooper()),
                 mSecureSettings,
                 hotspotController,
@@ -359,7 +359,7 @@
             return;
         }
         mAutoTileManager.mNightDisplayCallback.onActivated(true);
-        verify(mQsTileHost).addTile("night");
+        verify(mQsHost).addTile("night");
     }
 
     @Test
@@ -368,7 +368,7 @@
             return;
         }
         mAutoTileManager.mNightDisplayCallback.onActivated(false);
-        verify(mQsTileHost, never()).addTile("night");
+        verify(mQsHost, never()).addTile("night");
     }
 
     @Test
@@ -378,7 +378,7 @@
         }
         mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
                 ColorDisplayManager.AUTO_MODE_TWILIGHT);
-        verify(mQsTileHost).addTile("night");
+        verify(mQsHost).addTile("night");
     }
 
     @Test
@@ -388,7 +388,7 @@
         }
         mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
                 ColorDisplayManager.AUTO_MODE_CUSTOM_TIME);
-        verify(mQsTileHost).addTile("night");
+        verify(mQsHost).addTile("night");
     }
 
     @Test
@@ -398,19 +398,19 @@
         }
         mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
                 ColorDisplayManager.AUTO_MODE_DISABLED);
-        verify(mQsTileHost, never()).addTile("night");
+        verify(mQsHost, never()).addTile("night");
     }
 
     @Test
     public void reduceBrightColorsTileAdded_whenActivated() {
         mAutoTileManager.mReduceBrightColorsCallback.onActivated(true);
-        verify(mQsTileHost).addTile("reduce_brightness");
+        verify(mQsHost).addTile("reduce_brightness");
     }
 
     @Test
     public void reduceBrightColorsTileNotAdded_whenDeactivated() {
         mAutoTileManager.mReduceBrightColorsCallback.onActivated(false);
-        verify(mQsTileHost, never()).addTile("reduce_brightness");
+        verify(mQsHost, never()).addTile("reduce_brightness");
     }
 
     private static List<CastDevice> buildFakeCastDevice(boolean isCasting) {
@@ -423,28 +423,28 @@
     public void castTileAdded_whenDeviceIsCasting() {
         doReturn(buildFakeCastDevice(true)).when(mCastController).getCastDevices();
         mAutoTileManager.mCastCallback.onCastDevicesChanged();
-        verify(mQsTileHost).addTile("cast");
+        verify(mQsHost).addTile("cast");
     }
 
     @Test
     public void castTileNotAdded_whenDeviceIsNotCasting() {
         doReturn(buildFakeCastDevice(false)).when(mCastController).getCastDevices();
         mAutoTileManager.mCastCallback.onCastDevicesChanged();
-        verify(mQsTileHost, never()).addTile("cast");
+        verify(mQsHost, never()).addTile("cast");
     }
 
     @Test
     public void testSettingTileAdded_onChanged() {
         changeValue(TEST_SETTING, 1);
         verify(mAutoAddTracker).setTileAdded(TEST_SPEC);
-        verify(mQsTileHost).addTile(TEST_SPEC);
+        verify(mQsHost).addTile(TEST_SPEC);
     }
 
     @Test
     public void testSettingTileAddedComponentAtEnd_onChanged() {
         changeValue(TEST_SETTING_COMPONENT, 1);
         verify(mAutoAddTracker).setTileAdded(TEST_CUSTOM_SPEC);
-        verify(mQsTileHost).addTile(ComponentName.unflattenFromString(TEST_COMPONENT)
+        verify(mQsHost).addTile(ComponentName.unflattenFromString(TEST_COMPONENT)
             , /* end */ true);
     }
 
@@ -453,14 +453,14 @@
         changeValue(TEST_SETTING, 1);
         changeValue(TEST_SETTING, 2);
         verify(mAutoAddTracker).setTileAdded(TEST_SPEC);
-        verify(mQsTileHost).addTile(TEST_SPEC);
+        verify(mQsHost).addTile(TEST_SPEC);
     }
 
     @Test
     public void testSettingTileNotAdded_onChangedTo0() {
         changeValue(TEST_SETTING, 0);
         verify(mAutoAddTracker, never()).setTileAdded(TEST_SPEC);
-        verify(mQsTileHost, never()).addTile(TEST_SPEC);
+        verify(mQsHost, never()).addTile(TEST_SPEC);
     }
 
     @Test
@@ -469,27 +469,27 @@
 
         changeValue(TEST_SETTING, 1);
         verify(mAutoAddTracker, never()).setTileAdded(TEST_SPEC);
-        verify(mQsTileHost, never()).addTile(TEST_SPEC);
+        verify(mQsHost, never()).addTile(TEST_SPEC);
     }
 
     @Test
     public void testSafetyTileNotAdded_ifPreviouslyAdded() {
         ComponentName safetyComponent = CustomTile.getComponentFromSpec(TEST_CUSTOM_SAFETY_SPEC);
         mAutoTileManager.init();
-        verify(mQsTileHost, times(1)).addTile(safetyComponent, true);
+        verify(mQsHost, times(1)).addTile(safetyComponent, true);
         when(mAutoAddTracker.isAdded(TEST_CUSTOM_SAFETY_SPEC)).thenReturn(true);
         mAutoTileManager.init();
-        verify(mQsTileHost, times(1)).addTile(safetyComponent, true);
+        verify(mQsHost, times(1)).addTile(safetyComponent, true);
     }
 
     @Test
     public void testSafetyTileAdded_onUserChange() {
         ComponentName safetyComponent = CustomTile.getComponentFromSpec(TEST_CUSTOM_SAFETY_SPEC);
         mAutoTileManager.init();
-        verify(mQsTileHost, times(1)).addTile(safetyComponent, true);
+        verify(mQsHost, times(1)).addTile(safetyComponent, true);
         when(mAutoAddTracker.isAdded(TEST_CUSTOM_SAFETY_SPEC)).thenReturn(false);
         mAutoTileManager.changeUser(UserHandle.of(USER + 1));
-        verify(mQsTileHost, times(2)).addTile(safetyComponent, true);
+        verify(mQsHost, times(2)).addTile(safetyComponent, true);
     }
 
     @Test
@@ -498,17 +498,17 @@
         mAutoTileManager.init();
         when(mAutoAddTracker.isAdded(TEST_CUSTOM_SAFETY_SPEC)).thenReturn(true);
         mAutoTileManager.mSafetyCallback.onSafetyCenterEnableChanged(false);
-        verify(mQsTileHost, times(1)).removeTile(TEST_CUSTOM_SAFETY_SPEC);
+        verify(mQsHost, times(1)).removeTile(TEST_CUSTOM_SAFETY_SPEC);
     }
 
     @Test
     public void testSafetyTileAdded_onSafetyCenterEnable() {
         ComponentName safetyComponent = CustomTile.getComponentFromSpec(TEST_CUSTOM_SAFETY_SPEC);
         mAutoTileManager.init();
-        verify(mQsTileHost, times(1)).addTile(safetyComponent, true);
+        verify(mQsHost, times(1)).addTile(safetyComponent, true);
         mAutoTileManager.mSafetyCallback.onSafetyCenterEnableChanged(false);
         mAutoTileManager.mSafetyCallback.onSafetyCenterEnableChanged(true);
-        verify(mQsTileHost, times(2)).addTile(safetyComponent, true);
+        verify(mQsHost, times(2)).addTile(safetyComponent, true);
     }
 
     @Test
@@ -525,7 +525,7 @@
 
         mManagedProfileCallback.onManagedProfileChanged();
 
-        verify(mQsTileHost, times(1)).addTile(eq("work"), eq(2));
+        verify(mQsHost, times(1)).addTile(eq("work"), eq(2));
         verify(mAutoAddTracker, times(1)).setTileAdded(eq("work"));
     }
 
@@ -542,7 +542,7 @@
 
         mManagedProfileCallback.onManagedProfileChanged();
 
-        verify(mQsTileHost, times(1)).removeTile(eq("work"));
+        verify(mQsHost, times(1)).removeTile(eq("work"));
         verify(mAutoAddTracker, times(1)).setTileRemoved(eq("work"));
     }
 
@@ -550,7 +550,7 @@
     public void testAddControlsTileIfNotPresent() {
         String spec = DEVICE_CONTROLS;
         when(mAutoAddTracker.isAdded(eq(spec))).thenReturn(false);
-        when(mQsTileHost.getTiles()).thenReturn(new ArrayList<>());
+        when(mQsHost.getTiles()).thenReturn(new ArrayList<>());
 
         mAutoTileManager.init();
         ArgumentCaptor<DeviceControlsController.Callback> captor =
@@ -559,7 +559,7 @@
         verify(mDeviceControlsController).setCallback(captor.capture());
 
         captor.getValue().onControlsUpdate(3);
-        verify(mQsTileHost).addTile(spec, 3);
+        verify(mQsHost).addTile(spec, 3);
         verify(mAutoAddTracker).setTileAdded(spec);
     }
 
@@ -567,7 +567,7 @@
     public void testDontAddControlsTileIfPresent() {
         String spec = DEVICE_CONTROLS;
         when(mAutoAddTracker.isAdded(eq(spec))).thenReturn(false);
-        when(mQsTileHost.getTiles()).thenReturn(new ArrayList<>());
+        when(mQsHost.getTiles()).thenReturn(new ArrayList<>());
 
         mAutoTileManager.init();
         ArgumentCaptor<DeviceControlsController.Callback> captor =
@@ -576,7 +576,7 @@
         verify(mDeviceControlsController).setCallback(captor.capture());
 
         captor.getValue().removeControlsAutoTracker();
-        verify(mQsTileHost, never()).addTile(spec, 3);
+        verify(mQsHost, never()).addTile(spec, 3);
         verify(mAutoAddTracker, never()).setTileAdded(spec);
         verify(mAutoAddTracker).setTileRemoved(spec);
     }
@@ -587,7 +587,7 @@
         when(mAutoAddTracker.isAdded(eq(spec))).thenReturn(true);
         QSTile mockTile = mock(QSTile.class);
         when(mockTile.getTileSpec()).thenReturn(spec);
-        when(mQsTileHost.getTiles()).thenReturn(List.of(mockTile));
+        when(mQsHost.getTiles()).thenReturn(List.of(mockTile));
 
         mAutoTileManager.init();
         ArgumentCaptor<DeviceControlsController.Callback> captor =
@@ -596,7 +596,7 @@
         verify(mDeviceControlsController).setCallback(captor.capture());
 
         captor.getValue().onControlsUpdate(3);
-        verify(mQsTileHost, never()).addTile(spec, 3);
+        verify(mQsHost, never()).addTile(spec, 3);
         verify(mAutoAddTracker, never()).setTileAdded(spec);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
index b879cf2..2e6f62c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
@@ -43,9 +43,11 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.CameraLauncher;
 import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.QuickSettingsController;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DisableFlagsLogger;
@@ -73,6 +75,7 @@
     @Mock private CentralSurfaces mCentralSurfaces;
     @Mock private ShadeController mShadeController;
     @Mock private CommandQueue mCommandQueue;
+    @Mock private QuickSettingsController mQuickSettingsController;
     @Mock private NotificationPanelViewController mNotificationPanelViewController;
     @Mock private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
     private final MetricsLogger mMetricsLogger = new FakeMetricsLogger();
@@ -92,6 +95,7 @@
     @Mock private SystemBarAttributesListener mSystemBarAttributesListener;
     @Mock private Lazy<CameraLauncher> mCameraLauncherLazy;
     @Mock private UserTracker mUserTracker;
+    @Mock private QSHost mQSHost;
 
     CentralSurfacesCommandQueueCallbacks mSbcqCallbacks;
 
@@ -101,6 +105,7 @@
 
         mSbcqCallbacks = new CentralSurfacesCommandQueueCallbacks(
                 mCentralSurfaces,
+                mQuickSettingsController,
                 mContext,
                 mContext.getResources(),
                 mShadeController,
@@ -125,7 +130,8 @@
                 DEFAULT_DISPLAY,
                 mSystemBarAttributesListener,
                 mCameraLauncherLazy,
-                mUserTracker);
+                mUserTracker,
+                mQSHost);
 
         when(mUserTracker.getUserHandle()).thenReturn(
                 UserHandle.of(ActivityManager.getCurrentUser()));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 0605398..dbf416e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -126,6 +126,7 @@
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.shade.NotificationShadeWindowViewController;
+import com.android.systemui.shade.QuickSettingsController;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.shade.ShadeControllerImpl;
 import com.android.systemui.shade.ShadeExpansionStateManager;
@@ -218,6 +219,7 @@
     @Mock private HeadsUpManagerPhone mHeadsUpManager;
     @Mock private NotificationPanelViewController mNotificationPanelViewController;
     @Mock private NotificationPanelView mNotificationPanelView;
+    @Mock private QuickSettingsController mQuickSettingsController;
     @Mock private IStatusBarService mBarService;
     @Mock private IDreamManager mDreamManager;
     @Mock private LightRevealScrimViewModel mLightRevealScrimViewModel;
@@ -546,6 +548,7 @@
         // initialized automatically and make NPVC private.
         mCentralSurfaces.mNotificationShadeWindowView = mNotificationShadeWindowView;
         mCentralSurfaces.mNotificationPanelViewController = mNotificationPanelViewController;
+        mCentralSurfaces.mQsController = mQuickSettingsController;
         mCentralSurfaces.mDozeScrimController = mDozeScrimController;
         mCentralSurfaces.mPresenter = mNotificationPresenter;
         mCentralSurfaces.mKeyguardIndicationController = mKeyguardIndicationController;
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 c0537a6..dc5a047 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
@@ -1356,33 +1356,10 @@
     }
 
     @Test
-    public void notificationAlpha_unnocclusionAnimating_bouncerActive_usesKeyguardNotifAlpha() {
-        when(mStatusBarKeyguardViewManager.isPrimaryBouncerInTransit()).thenReturn(true);
-        mScrimController.setClipsQsScrim(true);
-
-        mScrimController.transitionTo(ScrimState.KEYGUARD);
-        mScrimController.setUnocclusionAnimationRunning(true);
-
-        assertAlphaAfterExpansion(
-                mNotificationsScrim, ScrimState.KEYGUARD.getNotifAlpha(), /* expansion */ 0f);
-        assertAlphaAfterExpansion(
-                mNotificationsScrim, ScrimState.KEYGUARD.getNotifAlpha(), /* expansion */ 0.4f);
-        assertAlphaAfterExpansion(
-                mNotificationsScrim, ScrimState.KEYGUARD.getNotifAlpha(), /* expansion */ 1.0f);
-
-        // Verify normal behavior after
-        mScrimController.setUnocclusionAnimationRunning(false);
-        float expansion = 0.4f;
-        float alpha = 1 - BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion);
-        assertAlphaAfterExpansion(mNotificationsScrim, alpha, expansion);
-    }
-
-    @Test
     public void notificationAlpha_unnocclusionAnimating_bouncerNotActive_usesKeyguardNotifAlpha() {
         when(mStatusBarKeyguardViewManager.isPrimaryBouncerInTransit()).thenReturn(false);
 
         mScrimController.transitionTo(ScrimState.KEYGUARD);
-        mScrimController.setUnocclusionAnimationRunning(true);
 
         assertAlphaAfterExpansion(
                 mNotificationsScrim, ScrimState.KEYGUARD.getNotifAlpha(), /* expansion */ 0f);
@@ -1392,7 +1369,6 @@
                 mNotificationsScrim, ScrimState.KEYGUARD.getNotifAlpha(), /* expansion */ 1.0f);
 
         // Verify normal behavior after
-        mScrimController.setUnocclusionAnimationRunning(false);
         float expansion = 0.4f;
         float alpha = 1 - ShadeInterpolation.getNotificationScrimAlpha(expansion);
         assertAlphaAfterExpansion(mNotificationsScrim, alpha, expansion);
@@ -1598,7 +1574,6 @@
 
     @Test
     public void setUnOccludingAnimationKeyguard() {
-        mScrimController.setUnocclusionAnimationRunning(true);
         mScrimController.transitionTo(ScrimState.KEYGUARD);
         finishAnimationsImmediately();
         assertThat(mNotificationsScrim.getViewAlpha())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index d8446f4..158e9ad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -38,6 +38,8 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewRootImpl;
+import android.view.WindowInsets;
+import android.view.WindowInsetsController;
 import android.window.BackEvent;
 import android.window.OnBackAnimationCallback;
 import android.window.OnBackInvokedCallback;
@@ -65,8 +67,10 @@
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback;
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
 import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.TaskbarDelegate;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.shade.NotificationPanelViewController;
+import com.android.systemui.shade.NotificationShadeWindowView;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.shade.ShadeExpansionChangeEvent;
 import com.android.systemui.shade.ShadeExpansionStateManager;
@@ -123,6 +127,9 @@
     @Mock private BouncerView mBouncerView;
     @Mock private BouncerViewDelegate mBouncerViewDelegate;
     @Mock private OnBackAnimationCallback mBouncerViewDelegateBackCallback;
+    @Mock private NotificationShadeWindowView mNotificationShadeWindowView;
+    @Mock private WindowInsetsController mWindowInsetsController;
+    @Mock private TaskbarDelegate mTaskbarDelegate;
 
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback
@@ -151,6 +158,11 @@
                 .isEnabled(Flags.WM_ENABLE_PREDICTIVE_BACK_BOUNCER_ANIM))
                 .thenReturn(true);
 
+        when(mCentralSurfaces.getNotificationShadeWindowView())
+                .thenReturn(mNotificationShadeWindowView);
+        when(mNotificationShadeWindowView.getWindowInsetsController())
+                .thenReturn(mWindowInsetsController);
+
         mStatusBarKeyguardViewManager =
                 new StatusBarKeyguardViewManager(
                         getContext(),
@@ -356,17 +368,6 @@
     }
 
     @Test
-    public void setOccluded_animatesPanelExpansion_onlyIfBouncerHidden() {
-        mStatusBarKeyguardViewManager.setOccluded(false /* occluded */, true /* animated */);
-        verify(mCentralSurfaces).animateKeyguardUnoccluding();
-
-        when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(true);
-        clearInvocations(mCentralSurfaces);
-        mStatusBarKeyguardViewManager.setOccluded(false /* occluded */, true /* animated */);
-        verify(mCentralSurfaces, never()).animateKeyguardUnoccluding();
-    }
-
-    @Test
     public void setOccluded_onKeyguardOccludedChangedCalled() {
         clearInvocations(mKeyguardStateController);
         clearInvocations(mKeyguardUpdateMonitor);
@@ -640,6 +641,14 @@
     }
 
     @Test
+    public void testHideTaskbar() {
+        when(mTaskbarDelegate.isInitialized()).thenReturn(true);
+        mStatusBarKeyguardViewManager.setTaskbarDelegate(mTaskbarDelegate);
+        mStatusBarKeyguardViewManager.updateNavigationBarVisibility(false);
+        verify(mWindowInsetsController).hide(WindowInsets.Type.navigationBars());
+    }
+
+    @Test
     public void hideAlternateBouncer_beforeCentralSurfacesRegistered() {
         mStatusBarKeyguardViewManager =
                 new StatusBarKeyguardViewManager(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
index 8841521..5bb25f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
@@ -43,6 +43,7 @@
 import com.android.systemui.settings.FakeDisplayTracker;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.NotificationShadeWindowView;
+import com.android.systemui.shade.QuickSettingsController;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -112,6 +113,7 @@
         mStatusBarNotificationPresenter = new StatusBarNotificationPresenter(
                 mContext,
                 mock(NotificationPanelViewController.class),
+                mock(QuickSettingsController.class),
                 mock(HeadsUpManagerPhone.class),
                 notificationShadeWindowView,
                 mock(ActivityStarter.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index 07e8d3c..1e5782b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -32,7 +32,6 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import android.animation.Animator;
 import android.app.Fragment;
 import android.app.StatusBarManager;
 import android.content.Context;
@@ -45,6 +44,7 @@
 import android.view.ViewPropertyAnimator;
 import android.widget.FrameLayout;
 
+import androidx.core.animation.Animator;
 import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleShaderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleShaderTest.kt
new file mode 100644
index 0000000..89cc18cc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleShaderTest.kt
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.surfaceeffects.ripple
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class RippleShaderTest : SysuiTestCase() {
+
+    private lateinit var rippleShader: RippleShader
+
+    @Before
+    fun setup() {
+        rippleShader = RippleShader()
+    }
+
+    @Test
+    fun setMaxSize_hasCorrectSizes() {
+        val expectedMaxWidth = 300f
+        val expectedMaxHeight = 500f
+
+        rippleShader.rippleSize.setMaxSize(expectedMaxWidth, expectedMaxHeight)
+
+        assertThat(rippleShader.rippleSize.sizes.size).isEqualTo(2)
+        assertThat(rippleShader.rippleSize.sizes[0]).isEqualTo(rippleShader.rippleSize.initialSize)
+        val maxSize = rippleShader.rippleSize.sizes[1]
+        assertThat(maxSize.t).isEqualTo(1f)
+        assertThat(maxSize.width).isEqualTo(expectedMaxWidth)
+        assertThat(maxSize.height).isEqualTo(expectedMaxHeight)
+    }
+
+    @Test
+    fun setSizeAtProgresses_hasCorrectSizes() {
+        val expectedSize0 = RippleShader.SizeAtProgress(t = 0f, width = 100f, height = 100f)
+        val expectedSize1 = RippleShader.SizeAtProgress(t = 0.2f, width = 1500f, height = 1200f)
+        val expectedSize2 = RippleShader.SizeAtProgress(t = 0.4f, width = 200f, height = 70f)
+
+        rippleShader.rippleSize.setSizeAtProgresses(expectedSize0, expectedSize1, expectedSize2)
+
+        assertThat(rippleShader.rippleSize.sizes.size).isEqualTo(3)
+        assertThat(rippleShader.rippleSize.sizes[0]).isEqualTo(expectedSize0)
+        assertThat(rippleShader.rippleSize.sizes[1]).isEqualTo(expectedSize1)
+        assertThat(rippleShader.rippleSize.sizes[2]).isEqualTo(expectedSize2)
+    }
+
+    @Test
+    fun setSizeAtProgresses_sizeListIsSortedByT() {
+        val expectedSize0 = RippleShader.SizeAtProgress(t = 0f, width = 100f, height = 100f)
+        val expectedSize1 = RippleShader.SizeAtProgress(t = 0.2f, width = 1500f, height = 1200f)
+        val expectedSize2 = RippleShader.SizeAtProgress(t = 0.4f, width = 200f, height = 70f)
+        val expectedSize3 = RippleShader.SizeAtProgress(t = 0.8f, width = 300f, height = 900f)
+        val expectedSize4 = RippleShader.SizeAtProgress(t = 1f, width = 500f, height = 300f)
+
+        // Add them in unsorted order
+        rippleShader.rippleSize.setSizeAtProgresses(
+            expectedSize0,
+            expectedSize3,
+            expectedSize2,
+            expectedSize4,
+            expectedSize1
+        )
+
+        assertThat(rippleShader.rippleSize.sizes.size).isEqualTo(5)
+        assertThat(rippleShader.rippleSize.sizes[0]).isEqualTo(expectedSize0)
+        assertThat(rippleShader.rippleSize.sizes[1]).isEqualTo(expectedSize1)
+        assertThat(rippleShader.rippleSize.sizes[2]).isEqualTo(expectedSize2)
+        assertThat(rippleShader.rippleSize.sizes[3]).isEqualTo(expectedSize3)
+        assertThat(rippleShader.rippleSize.sizes[4]).isEqualTo(expectedSize4)
+    }
+
+    @Test
+    fun update_getsCorrectNextTargetSize() {
+        val expectedSize0 = RippleShader.SizeAtProgress(t = 0f, width = 100f, height = 100f)
+        val expectedSize1 = RippleShader.SizeAtProgress(t = 0.2f, width = 1500f, height = 1200f)
+        val expectedSize2 = RippleShader.SizeAtProgress(t = 0.4f, width = 200f, height = 70f)
+        val expectedSize3 = RippleShader.SizeAtProgress(t = 0.8f, width = 300f, height = 900f)
+        val expectedSize4 = RippleShader.SizeAtProgress(t = 1f, width = 500f, height = 300f)
+
+        rippleShader.rippleSize.setSizeAtProgresses(
+            expectedSize0,
+            expectedSize1,
+            expectedSize2,
+            expectedSize3,
+            expectedSize4
+        )
+
+        rippleShader.rippleSize.update(0.5f)
+        // Progress is between 0.4 and 0.8 (expectedSize3 and 4), so the index should be 3.
+        assertThat(rippleShader.rippleSize.currentSizeIndex).isEqualTo(3)
+    }
+
+    @Test
+    fun update_sizeListIsEmpty_setsInitialSize() {
+        assertThat(rippleShader.rippleSize.sizes).isEmpty()
+
+        rippleShader.rippleSize.update(0.3f)
+
+        assertThat(rippleShader.rippleSize.sizes.size).isEqualTo(1)
+        assertThat(rippleShader.rippleSize.sizes[0]).isEqualTo(rippleShader.rippleSize.initialSize)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
index 5288608..0413d92 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
@@ -25,7 +25,6 @@
 import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_HALF_OPEN
 import com.android.systemui.unfold.updates.FOLD_UPDATE_START_CLOSING
 import com.android.systemui.unfold.updates.FOLD_UPDATE_START_OPENING
-import com.android.systemui.unfold.updates.FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE
 import com.android.systemui.unfold.util.TestFoldStateProvider
 import org.junit.Before
 import org.junit.Test
@@ -50,7 +49,7 @@
         runOnMainThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
             { foldStateProvider.sendHingeAngleUpdate(10f) },
-            { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE) },
+            { foldStateProvider.sendUnfoldedScreenAvailable() },
             { foldStateProvider.sendHingeAngleUpdate(90f) },
             { foldStateProvider.sendHingeAngleUpdate(180f) },
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) },
@@ -67,7 +66,7 @@
         runOnMainThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
             { foldStateProvider.sendHingeAngleUpdate(10f) },
-            { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE) },
+            { foldStateProvider.sendUnfoldedScreenAvailable() },
             { foldStateProvider.sendHingeAngleUpdate(90f) },
             { foldStateProvider.sendHingeAngleUpdate(180f) },
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) },
@@ -84,7 +83,7 @@
             { foldStateProvider.sendHingeAngleUpdate(90f) },
             { foldStateProvider.sendHingeAngleUpdate(180f) },
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) },
-            { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE) },
+            { foldStateProvider.sendUnfoldedScreenAvailable() },
         )
 
         with(listener.ensureTransitionFinished()) {
@@ -113,7 +112,7 @@
     fun testUnfoldAndStopUnfolding_finishesTheUnfoldTransition() {
         runOnMainThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
-            { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE) },
+            { foldStateProvider.sendUnfoldedScreenAvailable() },
             { foldStateProvider.sendHingeAngleUpdate(10f) },
             { foldStateProvider.sendHingeAngleUpdate(90f) },
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_HALF_OPEN) },
@@ -129,7 +128,7 @@
     fun testFoldImmediatelyAfterUnfold_runsFoldAnimation() {
         runOnMainThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
-            { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE) },
+            { foldStateProvider.sendUnfoldedScreenAvailable() },
             { foldStateProvider.sendHingeAngleUpdate(10f) },
             { foldStateProvider.sendHingeAngleUpdate(90f) },
             {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
index 6086e16..8476d0d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.unfold.system.ActivityManagerActivityTypeProvider
 import com.android.systemui.unfold.updates.FoldProvider.FoldCallback
 import com.android.systemui.unfold.updates.RotationChangeProvider.RotationListener
+import com.android.systemui.unfold.updates.hinge.FULLY_OPEN_DEGREES
 import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider.ScreenListener
@@ -71,6 +72,7 @@
 
     private val foldUpdates: MutableList<Int> = arrayListOf()
     private val hingeAngleUpdates: MutableList<Float> = arrayListOf()
+    private val unfoldedScreenAvailabilityUpdates: MutableList<Unit> = arrayListOf()
 
     private var scheduledRunnable: Runnable? = null
     private var scheduledRunnableDelay: Long? = null
@@ -106,6 +108,10 @@
                 override fun onFoldUpdate(update: Int) {
                     foldUpdates.add(update)
                 }
+
+                override fun onUnfoldedScreenAvailable() {
+                    unfoldedScreenAvailabilityUpdates.add(Unit)
+                }
             })
         foldStateProvider.start()
 
@@ -156,8 +162,8 @@
         sendHingeAngleEvent(10)
         screenOnStatusProvider.notifyScreenTurnedOn()
 
-        assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_OPENING,
-                FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE)
+        assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_OPENING)
+        assertThat(unfoldedScreenAvailabilityUpdates).hasSize(1)
     }
 
     @Test
@@ -174,8 +180,9 @@
         sendHingeAngleEvent(40)
         sendHingeAngleEvent(10)
 
-        assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_OPENING,
-                FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE, FOLD_UPDATE_START_CLOSING)
+        assertThat(foldUpdates)
+                .containsExactly(FOLD_UPDATE_START_OPENING, FOLD_UPDATE_START_CLOSING)
+        assertThat(unfoldedScreenAvailabilityUpdates).hasSize(1)
     }
 
     @Test
@@ -223,7 +230,7 @@
 
         fireScreenOnEvent()
 
-        assertThat(foldUpdates).containsExactly(FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE)
+        assertThat(unfoldedScreenAvailabilityUpdates).hasSize(1)
     }
 
     @Test
@@ -277,7 +284,7 @@
 
     @Test
     fun startClosingEvent_afterTimeout_finishHalfOpenEventEmitted() {
-        sendHingeAngleEvent(90)
+        setInitialHingeAngle(90)
         sendHingeAngleEvent(80)
 
         simulateTimeout(HALF_OPENED_TIMEOUT_MILLIS)
@@ -288,7 +295,7 @@
 
     @Test
     fun startClosingEvent_beforeTimeout_abortNotEmitted() {
-        sendHingeAngleEvent(90)
+        setInitialHingeAngle(90)
         sendHingeAngleEvent(80)
 
         simulateTimeout(HALF_OPENED_TIMEOUT_MILLIS - 1)
@@ -298,7 +305,7 @@
 
     @Test
     fun startClosingEvent_eventBeforeTimeout_oneEventEmitted() {
-        sendHingeAngleEvent(180)
+        setInitialHingeAngle(180)
         sendHingeAngleEvent(90)
 
         simulateTimeout(HALF_OPENED_TIMEOUT_MILLIS - 1)
@@ -309,7 +316,7 @@
 
     @Test
     fun startClosingEvent_timeoutAfterTimeoutRescheduled_finishHalfOpenStateEmitted() {
-        sendHingeAngleEvent(180)
+        setInitialHingeAngle(180)
         sendHingeAngleEvent(90)
 
         // The timeout should not trigger here.
@@ -323,7 +330,7 @@
 
     @Test
     fun startClosingEvent_shortTimeBetween_emitsOnlyOneEvents() {
-        sendHingeAngleEvent(180)
+        setInitialHingeAngle(180)
 
         sendHingeAngleEvent(90)
         sendHingeAngleEvent(80)
@@ -334,20 +341,19 @@
     @Test
     fun startClosingEvent_whileClosing_emittedDespiteInitialAngle() {
         val maxAngle = 180 - FULLY_OPEN_THRESHOLD_DEGREES.toInt()
-        for (i in 1..maxAngle) {
-            foldUpdates.clear()
-
-            simulateFolding(startAngle = i)
+        val minAngle = Math.ceil(HINGE_ANGLE_CHANGE_THRESHOLD_DEGREES.toDouble()).toInt() + 1
+        for (startAngle in minAngle..maxAngle) {
+            setInitialHingeAngle(startAngle)
+            sendHingeAngleEvent(startAngle - HINGE_ANGLE_CHANGE_THRESHOLD_DEGREES.toInt() - 1)
 
             assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
-            simulateTimeout() // Timeout to set the state to aborted.
         }
     }
 
     @Test
     fun startClosingEvent_whileNotOnLauncher_doesNotTriggerBeforeThreshold() {
         setupForegroundActivityType(isHomeActivity = false)
-        sendHingeAngleEvent(180)
+        setInitialHingeAngle(180)
 
         sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
 
@@ -357,7 +363,7 @@
     @Test
     fun startClosingEvent_whileActivityTypeNotAvailable_triggerBeforeThreshold() {
         setupForegroundActivityType(isHomeActivity = null)
-        sendHingeAngleEvent(180)
+        setInitialHingeAngle(180)
 
         sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
 
@@ -367,7 +373,7 @@
     @Test
     fun startClosingEvent_whileOnLauncher_doesTriggerBeforeThreshold() {
         setupForegroundActivityType(isHomeActivity = true)
-        sendHingeAngleEvent(180)
+        setInitialHingeAngle(180)
 
         sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
 
@@ -377,9 +383,11 @@
     @Test
     fun startClosingEvent_whileNotOnLauncher_triggersAfterThreshold() {
         setupForegroundActivityType(isHomeActivity = false)
-        sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES)
+        setInitialHingeAngle(START_CLOSING_ON_APPS_THRESHOLD_DEGREES)
 
-        sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES - 1)
+        sendHingeAngleEvent(
+                START_CLOSING_ON_APPS_THRESHOLD_DEGREES -
+                        HINGE_ANGLE_CHANGE_THRESHOLD_DEGREES.toInt() - 1)
 
         assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
     }
@@ -388,7 +396,7 @@
     fun startClosingEvent_whileNotOnKeyguardAndNotOnLauncher_doesNotTriggerBeforeThreshold() {
         setKeyguardVisibility(visible = false)
         setupForegroundActivityType(isHomeActivity = false)
-        sendHingeAngleEvent(180)
+        setInitialHingeAngle(180)
 
         sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
 
@@ -398,7 +406,7 @@
     @Test
     fun startClosingEvent_whileKeyguardStateNotAvailable_triggerBeforeThreshold() {
         setKeyguardVisibility(visible = null)
-        sendHingeAngleEvent(180)
+        setInitialHingeAngle(180)
 
         sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
 
@@ -408,7 +416,7 @@
     @Test
     fun startClosingEvent_whileonKeyguard_doesTriggerBeforeThreshold() {
         setKeyguardVisibility(visible = true)
-        sendHingeAngleEvent(180)
+        setInitialHingeAngle(180)
 
         sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
 
@@ -418,9 +426,59 @@
     @Test
     fun startClosingEvent_whileNotOnKeyguard_triggersAfterThreshold() {
         setKeyguardVisibility(visible = false)
-        sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES)
+        setInitialHingeAngle(START_CLOSING_ON_APPS_THRESHOLD_DEGREES)
 
-        sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES - 1)
+        sendHingeAngleEvent(
+                START_CLOSING_ON_APPS_THRESHOLD_DEGREES -
+                        HINGE_ANGLE_CHANGE_THRESHOLD_DEGREES.toInt() - 1)
+
+        assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+    }
+
+    @Test
+    fun startClosingEvent_doesNotTriggerBelowThreshold() {
+        val thresholdAngle = (FULLY_OPEN_DEGREES - FULLY_OPEN_THRESHOLD_DEGREES).toInt()
+        setInitialHingeAngle(180)
+        sendHingeAngleEvent(thresholdAngle + 1)
+
+        assertThat(foldUpdates).isEmpty()
+    }
+
+    @Test
+    fun startClosingEvent_triggersAfterThreshold() {
+        val thresholdAngle = (FULLY_OPEN_DEGREES - FULLY_OPEN_THRESHOLD_DEGREES).toInt()
+        setInitialHingeAngle(180)
+        sendHingeAngleEvent(thresholdAngle + 1)
+        sendHingeAngleEvent(thresholdAngle - 1)
+
+        assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+    }
+
+    @Test
+    fun startClosingEvent_triggersAfterThreshold_fromHalfOpen() {
+        setInitialHingeAngle(120)
+        sendHingeAngleEvent((120 - HINGE_ANGLE_CHANGE_THRESHOLD_DEGREES + 1).toInt())
+        assertThat(foldUpdates).isEmpty()
+        sendHingeAngleEvent((120 - HINGE_ANGLE_CHANGE_THRESHOLD_DEGREES - 1).toInt())
+
+        assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+    }
+
+    @Test
+    fun startOpeningAndClosingEvents_triggerWithOpenAndClose() {
+        setInitialHingeAngle(120)
+        sendHingeAngleEvent(130)
+        sendHingeAngleEvent(120)
+        assertThat(foldUpdates)
+                .containsExactly(FOLD_UPDATE_START_OPENING, FOLD_UPDATE_START_CLOSING)
+    }
+
+    @Test
+    fun startClosingEvent_notInterrupted_whenAngleIsSlightlyIncreased() {
+        setInitialHingeAngle(120)
+        sendHingeAngleEvent(110)
+        sendHingeAngleEvent(111)
+        sendHingeAngleEvent(100)
 
         assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
     }
@@ -504,11 +562,6 @@
         }
     }
 
-    private fun simulateFolding(startAngle: Int) {
-        sendHingeAngleEvent(startAngle)
-        sendHingeAngleEvent(startAngle - 1)
-    }
-
     private fun setFoldState(folded: Boolean) {
         foldProvider.notifyFolded(folded)
     }
@@ -521,6 +574,17 @@
         testHingeAngleProvider.notifyAngle(angle.toFloat())
     }
 
+    private fun setInitialHingeAngle(angle: Int) {
+        setFoldState(angle == 0)
+        sendHingeAngleEvent(angle)
+        if (scheduledRunnableDelay != null) {
+            simulateTimeout()
+        }
+        hingeAngleUpdates.clear()
+        foldUpdates.clear()
+        unfoldedScreenAvailabilityUpdates.clear()
+    }
+
     private class TestFoldProvider : FoldProvider {
         private val callbacks = arrayListOf<FoldCallback>()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldStateProvider.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldStateProvider.kt
index a064e8c..fbb0e5a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldStateProvider.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldStateProvider.kt
@@ -57,4 +57,8 @@
     fun sendHingeAngleUpdate(angle: Float) {
         listeners.forEach { it.onHingeAngleUpdate(angle) }
     }
+
+    fun sendUnfoldedScreenAvailable() {
+        listeners.forEach { it.onUnfoldedScreenAvailable() }
+    }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBiometricSettingsRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBiometricSettingsRepository.kt
index 01dac36..d4b1701 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBiometricSettingsRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeBiometricSettingsRepository.kt
@@ -21,6 +21,7 @@
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.flowOf
 
 class FakeBiometricSettingsRepository : BiometricSettingsRepository {
 
@@ -42,6 +43,9 @@
     override val isFingerprintEnabledByDevicePolicy =
         _isFingerprintEnabledByDevicePolicy.asStateFlow()
 
+    override val isFaceAuthSupportedInCurrentPosture: Flow<Boolean>
+        get() = flowOf(true)
+
     fun setFingerprintEnrolled(isFingerprintEnrolled: Boolean) {
         _isFingerprintEnrolled.value = isFingerprintEnrolled
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDevicePostureRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDevicePostureRepository.kt
new file mode 100644
index 0000000..914c786
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDevicePostureRepository.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.data.repository
+
+import com.android.systemui.keyguard.shared.model.DevicePosture
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+
+class FakeDevicePostureRepository : DevicePostureRepository {
+    private val _currentDevicePosture = MutableStateFlow(DevicePosture.UNKNOWN)
+    override val currentDevicePosture: Flow<DevicePosture>
+        get() = _currentDevicePosture
+
+    fun setCurrentPosture(posture: DevicePosture) {
+        _currentDevicePosture.value = posture
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardBouncerRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardBouncerRepository.kt
index 3374219..9cdce20 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardBouncerRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardBouncerRepository.kt
@@ -21,6 +21,7 @@
 import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
 import com.android.systemui.keyguard.shared.model.KeyguardBouncerModel
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
 
 /** Fake implementation of [KeyguardRepository] */
@@ -44,8 +45,6 @@
     override val panelExpansionAmount = _panelExpansionAmount.asStateFlow()
     private val _keyguardPosition = MutableStateFlow(0f)
     override val keyguardPosition = _keyguardPosition.asStateFlow()
-    private val _onScreenTurnedOff = MutableStateFlow(false)
-    override val onScreenTurnedOff = _onScreenTurnedOff.asStateFlow()
     private val _isBackButtonEnabled = MutableStateFlow<Boolean?>(null)
     override val isBackButtonEnabled = _isBackButtonEnabled.asStateFlow()
     private val _keyguardAuthenticated = MutableStateFlow<Boolean?>(null)
@@ -61,6 +60,8 @@
     override var lastAlternateBouncerVisibleTime: Long = 0L
     private val _isAlternateBouncerUIAvailable = MutableStateFlow<Boolean>(false)
     override val alternateBouncerUIAvailable = _isAlternateBouncerUIAvailable.asStateFlow()
+    private val _sideFpsShowing: MutableStateFlow<Boolean> = MutableStateFlow(false)
+    override val sideFpsShowing: StateFlow<Boolean> = _sideFpsShowing.asStateFlow()
 
     override fun setPrimaryScrimmed(isScrimmed: Boolean) {
         _primaryBouncerScrimmed.value = isScrimmed
@@ -122,7 +123,7 @@
         _isBackButtonEnabled.value = isBackButtonEnabled
     }
 
-    override fun setOnScreenTurnedOff(onScreenTurnedOff: Boolean) {
-        _onScreenTurnedOff.value = onScreenTurnedOff
+    override fun setSideFpsShowing(isShowing: Boolean) {
+        _sideFpsShowing.value = isShowing
     }
 }
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt
index 4622464..c437e5c 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt
@@ -21,7 +21,6 @@
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
 import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_CLOSED
-import com.android.systemui.unfold.updates.FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE
 import com.android.systemui.unfold.updates.FoldStateProvider
 import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdate
 import javax.inject.Inject
@@ -59,12 +58,15 @@
     }
 
     override fun onFoldUpdate(@FoldUpdate update: Int) {
-        when (update) {
-            FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE -> animator.start()
-            FOLD_UPDATE_FINISH_CLOSED -> animator.cancel()
+        if (update == FOLD_UPDATE_FINISH_CLOSED) {
+             animator.cancel()
         }
     }
 
+    override fun onUnfoldedScreenAvailable() {
+        animator.start()
+    }
+
     override fun addCallback(listener: TransitionProgressListener) {
         listeners.add(listener)
     }
@@ -73,8 +75,6 @@
         listeners.remove(listener)
     }
 
-    override fun onHingeAngleUpdate(angle: Float) {}
-
     private object AnimationProgressProperty :
         FloatProperty<FixedTimingTransitionProgressProvider>("animation_progress") {
 
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
index 6ffbe5a..d19b414 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_FULL_OPEN
 import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_HALF_OPEN
 import com.android.systemui.unfold.updates.FOLD_UPDATE_START_CLOSING
-import com.android.systemui.unfold.updates.FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE
 import com.android.systemui.unfold.updates.FoldStateProvider
 import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdate
 import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdatesListener
@@ -78,21 +77,11 @@
 
     override fun onFoldUpdate(@FoldUpdate update: Int) {
         when (update) {
-            FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE -> {
-                startTransition(startValue = 0f)
-
-                // Stop the animation if the device has already opened by the time when
-                // the display is available as we won't receive the full open event anymore
-                if (foldStateProvider.isFinishedOpening) {
-                    cancelTransition(endValue = 1f, animate = true)
-                }
-            }
             FOLD_UPDATE_FINISH_FULL_OPEN, FOLD_UPDATE_FINISH_HALF_OPEN -> {
                 // Do not cancel if we haven't started the transition yet.
                 // This could happen when we fully unfolded the device before the screen
                 // became available. In this case we start and immediately cancel the animation
-                // in FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE event handler, so we don't need to
-                // cancel it here.
+                // in onUnfoldedScreenAvailable event handler, so we don't need to cancel it here.
                 if (isTransitionRunning) {
                     cancelTransition(endValue = 1f, animate = true)
                 }
@@ -125,6 +114,16 @@
         }
     }
 
+    override fun onUnfoldedScreenAvailable() {
+        startTransition(startValue = 0f)
+
+        // Stop the animation if the device has already opened by the time when
+        // the display is available as we won't receive the full open event anymore
+        if (foldStateProvider.isFinishedOpening) {
+            cancelTransition(endValue = 1f, animate = true)
+        }
+    }
+
     private fun cancelTransition(endValue: Float, animate: Boolean) {
         if (isTransitionRunning && animate) {
             if (endValue == 1.0f && !isAnimatedCancelRunning) {
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
index 97c9ba9..82fd225 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
@@ -54,6 +54,7 @@
     @FoldUpdate private var lastFoldUpdate: Int? = null
 
     @FloatRange(from = 0.0, to = 180.0) private var lastHingeAngle: Float = 0f
+    @FloatRange(from = 0.0, to = 180.0) private var lastHingeAngleBeforeTransition: Float = 0f
 
     private val hingeAngleListener = HingeAngleListener()
     private val screenListener = ScreenStatusListener()
@@ -112,29 +113,45 @@
 
     private fun onHingeAngle(angle: Float) {
         if (DEBUG) {
-            Log.d(TAG, "Hinge angle: $angle, lastHingeAngle: $lastHingeAngle")
+            Log.d(
+                TAG,
+                "Hinge angle: $angle, " +
+                    "lastHingeAngle: $lastHingeAngle, " +
+                    "lastHingeAngleBeforeTransition: $lastHingeAngleBeforeTransition"
+            )
             Trace.traceCounter(Trace.TRACE_TAG_APP, "hinge_angle", angle.toInt())
         }
 
-        val isClosing = angle < lastHingeAngle
+        val currentDirection =
+                if (angle < lastHingeAngle) FOLD_UPDATE_START_CLOSING else FOLD_UPDATE_START_OPENING
+        if (isTransitionInProgress && currentDirection != lastFoldUpdate) {
+            lastHingeAngleBeforeTransition = lastHingeAngle
+        }
+
+        val isClosing = angle < lastHingeAngleBeforeTransition
+        val transitionUpdate =
+                if (isClosing) FOLD_UPDATE_START_CLOSING else FOLD_UPDATE_START_OPENING
+        val angleChangeSurpassedThreshold =
+            Math.abs(angle - lastHingeAngleBeforeTransition) > HINGE_ANGLE_CHANGE_THRESHOLD_DEGREES
         val isFullyOpened = FULLY_OPEN_DEGREES - angle < FULLY_OPEN_THRESHOLD_DEGREES
-        val closingEventDispatched = lastFoldUpdate == FOLD_UPDATE_START_CLOSING
+        val eventNotAlreadyDispatched = lastFoldUpdate != transitionUpdate
         val screenAvailableEventSent = isUnfoldHandled
 
-        if (isClosing // hinge angle should be decreasing since last update
-                && !closingEventDispatched  // we haven't sent closing event already
-                && !isFullyOpened // do not send closing event if we are in fully opened hinge
+        if (
+            angleChangeSurpassedThreshold && // Do not react immediately to small changes in angle
+                eventNotAlreadyDispatched && // we haven't sent transition event already
+                !isFullyOpened && // do not send transition event if we are in fully opened hinge
                                   // angle range as closing threshold could overlap this range
-                && screenAvailableEventSent // do not send closing event if we are still in
-                                            // the process of turning on the inner display
-                && isClosingThresholdMet(angle) // hinge angle is below certain threshold.
+                screenAvailableEventSent && // do not send transition event if we are still in the
+                                            // process of turning on the inner display
+                isClosingThresholdMet(angle) // hinge angle is below certain threshold.
         ) {
-            notifyFoldUpdate(FOLD_UPDATE_START_CLOSING)
+            notifyFoldUpdate(transitionUpdate, lastHingeAngle)
         }
 
         if (isTransitionInProgress) {
             if (isFullyOpened) {
-                notifyFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN)
+                notifyFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN, angle)
                 cancelTimeout()
             } else {
                 // The timeout will trigger some constant time after the last angle update.
@@ -146,7 +163,7 @@
         outputListeners.forEach { it.onHingeAngleUpdate(angle) }
     }
 
-    private fun isClosingThresholdMet(currentAngle: Float) : Boolean {
+    private fun isClosingThresholdMet(currentAngle: Float): Boolean {
         val closingThreshold = getClosingThreshold()
         return closingThreshold == null || currentAngle < closingThreshold
     }
@@ -179,23 +196,29 @@
 
             if (isFolded) {
                 hingeAngleProvider.stop()
-                notifyFoldUpdate(FOLD_UPDATE_FINISH_CLOSED)
+                notifyFoldUpdate(FOLD_UPDATE_FINISH_CLOSED, lastHingeAngle)
                 cancelTimeout()
                 isUnfoldHandled = false
             } else {
-                notifyFoldUpdate(FOLD_UPDATE_START_OPENING)
+                notifyFoldUpdate(FOLD_UPDATE_START_OPENING, lastHingeAngle)
                 rescheduleAbortAnimationTimeout()
                 hingeAngleProvider.start()
             }
         }
     }
 
-    private fun notifyFoldUpdate(@FoldUpdate update: Int) {
+    private fun notifyFoldUpdate(@FoldUpdate update: Int, angle: Float) {
         if (DEBUG) {
             Log.d(TAG, update.name())
         }
+        val previouslyTransitioning = isTransitionInProgress
+
         outputListeners.forEach { it.onFoldUpdate(update) }
         lastFoldUpdate = update
+
+        if (previouslyTransitioning != isTransitionInProgress) {
+            lastHingeAngleBeforeTransition = angle
+        }
     }
 
     private fun rescheduleAbortAnimationTimeout() {
@@ -209,7 +232,8 @@
         handler.removeCallbacks(timeoutRunnable)
     }
 
-    private fun cancelAnimation(): Unit = notifyFoldUpdate(FOLD_UPDATE_FINISH_HALF_OPEN)
+    private fun cancelAnimation(): Unit =
+            notifyFoldUpdate(FOLD_UPDATE_FINISH_HALF_OPEN, lastHingeAngle)
 
     private inner class ScreenStatusListener : ScreenStatusProvider.ScreenListener {
 
@@ -221,7 +245,7 @@
             // receive 'folded' event. If SystemUI started when device is already folded it will
             // still receive 'folded' event on startup.
             if (!isFolded && !isUnfoldHandled) {
-                outputListeners.forEach { it.onFoldUpdate(FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE) }
+                outputListeners.forEach { it.onUnfoldedScreenAvailable() }
                 isUnfoldHandled = true
             }
         }
@@ -257,7 +281,6 @@
     when (this) {
         FOLD_UPDATE_START_OPENING -> "START_OPENING"
         FOLD_UPDATE_START_CLOSING -> "START_CLOSING"
-        FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE -> "UNFOLDED_SCREEN_AVAILABLE"
         FOLD_UPDATE_FINISH_HALF_OPEN -> "FINISH_HALF_OPEN"
         FOLD_UPDATE_FINISH_FULL_OPEN -> "FINISH_FULL_OPEN"
         FOLD_UPDATE_FINISH_CLOSED -> "FINISH_CLOSED"
@@ -270,5 +293,8 @@
 /** Threshold after which we consider the device fully unfolded. */
 @VisibleForTesting const val FULLY_OPEN_THRESHOLD_DEGREES = 15f
 
+/** Threshold after which hinge angle updates are considered. This is to eliminate noise. */
+@VisibleForTesting const val HINGE_ANGLE_CHANGE_THRESHOLD_DEGREES = 7.5f
+
 /** Fold animation on top of apps only when the angle exceeds this threshold. */
 @VisibleForTesting const val START_CLOSING_ON_APPS_THRESHOLD_DEGREES = 60
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldStateProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
index c7a8bf3..0af372f 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
@@ -31,8 +31,9 @@
     val isFinishedOpening: Boolean
 
     interface FoldUpdatesListener {
-        fun onHingeAngleUpdate(@FloatRange(from = 0.0, to = 180.0) angle: Float)
-        fun onFoldUpdate(@FoldUpdate update: Int)
+        @JvmDefault fun onHingeAngleUpdate(@FloatRange(from = 0.0, to = 180.0) angle: Float) {}
+        @JvmDefault fun onFoldUpdate(@FoldUpdate update: Int) {}
+        @JvmDefault fun onUnfoldedScreenAvailable() {}
     }
 
     @IntDef(
@@ -40,7 +41,6 @@
             [
                 FOLD_UPDATE_START_OPENING,
                 FOLD_UPDATE_START_CLOSING,
-                FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE,
                 FOLD_UPDATE_FINISH_HALF_OPEN,
                 FOLD_UPDATE_FINISH_FULL_OPEN,
                 FOLD_UPDATE_FINISH_CLOSED])
@@ -50,7 +50,6 @@
 
 const val FOLD_UPDATE_START_OPENING = 0
 const val FOLD_UPDATE_START_CLOSING = 1
-const val FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE = 2
-const val FOLD_UPDATE_FINISH_HALF_OPEN = 3
-const val FOLD_UPDATE_FINISH_FULL_OPEN = 4
-const val FOLD_UPDATE_FINISH_CLOSED = 5
+const val FOLD_UPDATE_FINISH_HALF_OPEN = 2
+const val FOLD_UPDATE_FINISH_FULL_OPEN = 3
+const val FOLD_UPDATE_FINISH_CLOSED = 4
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 29194c5..3818a88 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1848,6 +1848,12 @@
             AccessibilityServiceInfo accessibilityServiceInfo;
             try {
                 accessibilityServiceInfo = new AccessibilityServiceInfo(resolveInfo, mContext);
+                if (!accessibilityServiceInfo.isWithinParcelableSize()) {
+                    Slog.e(LOG_TAG, "Skipping service "
+                            + accessibilityServiceInfo.getResolveInfo().getComponentInfo()
+                            + " because service info size is larger than safe parcelable limits.");
+                    continue;
+                }
                 if (userState.mCrashedServices.contains(serviceInfo.getComponentName())) {
                     // Restore the crashed attribute.
                     accessibilityServiceInfo.crashed = true;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 207c10c..2f95716 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -21,6 +21,7 @@
 import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE;
 
 import android.annotation.NonNull;
+import android.app.AlarmManager;
 import android.app.StatsManager;
 import android.app.usage.NetworkStatsManager;
 import android.bluetooth.BluetoothActivityEnergyInfo;
@@ -356,6 +357,16 @@
         mStats.setRadioScanningTimeoutLocked(mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_radioScanningTimeout) * 1000L);
         mStats.setPowerProfileLocked(mPowerProfile);
+
+        final boolean resetOnUnplugHighBatteryLevel = context.getResources().getBoolean(
+                com.android.internal.R.bool.config_batteryStatsResetOnUnplugHighBatteryLevel);
+        final boolean resetOnUnplugAfterSignificantCharge = context.getResources().getBoolean(
+                com.android.internal.R.bool.config_batteryStatsResetOnUnplugAfterSignificantCharge);
+        mStats.setBatteryStatsConfig(
+                new BatteryStatsImpl.BatteryStatsConfig.Builder()
+                        .setResetOnUnplugHighBatteryLevel(resetOnUnplugHighBatteryLevel)
+                        .setResetOnUnplugAfterSignificantCharge(resetOnUnplugAfterSignificantCharge)
+                        .build());
         mStats.startTrackingSystemServerCpuTime();
 
         if (BATTERY_USAGE_STORE_ENABLED) {
@@ -386,6 +397,18 @@
             Slog.e(TAG, "Could not register INetworkManagement event observer " + e);
         }
 
+        final AlarmManager am = mContext.getSystemService(AlarmManager.class);
+        mHandler.post(() -> {
+            synchronized (mStats) {
+                mStats.setLongPlugInAlarmInterface(new AlarmInterface(am, () -> {
+                    synchronized (mStats) {
+                        if (mStats.isOnBattery()) return;
+                        mStats.maybeResetWhilePluggedInLocked();
+                    }
+                }));
+            }
+        });
+
         synchronized (mPowerStatsLock) {
             mPowerStatsInternal = LocalServices.getService(PowerStatsInternal.class);
             if (mPowerStatsInternal != null) {
@@ -2259,6 +2282,32 @@
         }
     }
 
+    final class AlarmInterface implements BatteryStatsImpl.AlarmInterface,
+            AlarmManager.OnAlarmListener {
+        private AlarmManager mAm;
+        private Runnable mOnAlarm;
+
+        AlarmInterface(AlarmManager am, Runnable onAlarm) {
+            mAm = am;
+            mOnAlarm = onAlarm;
+        }
+
+        @Override
+        public void schedule(long rtcTimeMs, long windowLengthMs) {
+            mAm.setWindow(AlarmManager.RTC, rtcTimeMs, windowLengthMs, TAG, this, mHandler);
+        }
+
+        @Override
+        public void cancel() {
+            mAm.cancel(this);
+        }
+
+        @Override
+        public void onAlarm() {
+            mOnAlarm.run();
+        }
+    }
+
     private static native int nativeWaitWakeup(ByteBuffer outBuffer);
 
     private void dumpHelp(PrintWriter pw) {
@@ -2445,7 +2494,8 @@
                 } else if ("--reset-all".equals(arg)) {
                     awaitCompletion();
                     synchronized (mStats) {
-                        mStats.resetAllStatsCmdLocked();
+                        mStats.resetAllStatsAndHistoryLocked(
+                                BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
                         mBatteryUsageStatsStore.removeAllSnapshots();
                         pw.println("Battery stats and history reset.");
                         noOutput = true;
@@ -2453,7 +2503,8 @@
                 } else if ("--reset".equals(arg)) {
                     awaitCompletion();
                     synchronized (mStats) {
-                        mStats.resetAllStatsCmdLocked();
+                        mStats.resetAllStatsAndHistoryLocked(
+                                BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
                         pw.println("Battery stats reset.");
                         noOutput = true;
                     }
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index cf880eb..6410142 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -1218,6 +1218,10 @@
         sendILMsg(MSG_IL_BTA2DP_TIMEOUT, SENDMSG_QUEUE, a2dpCodec, address, delayMs);
     }
 
+    /*package*/ void setLeAudioTimeout(String address, int device, int delayMs) {
+        sendILMsg(MSG_IL_BTLEAUDIO_TIMEOUT, SENDMSG_QUEUE, device, address, delayMs);
+    }
+
     /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean supported) {
         synchronized (mDeviceStateLock) {
             mBtHelper.setAvrcpAbsoluteVolumeSupported(supported);
@@ -1422,6 +1426,13 @@
                         mDeviceInventory.onMakeA2dpDeviceUnavailableNow((String) msg.obj, msg.arg1);
                     }
                     break;
+                case MSG_IL_BTLEAUDIO_TIMEOUT:
+                    // msg.obj  == address of LE Audio device
+                    synchronized (mDeviceStateLock) {
+                        mDeviceInventory.onMakeLeAudioDeviceUnavailableNow(
+                                (String) msg.obj, msg.arg1);
+                    }
+                    break;
                 case MSG_L_A2DP_DEVICE_CONFIG_CHANGE:
                     final BluetoothDevice btDevice = (BluetoothDevice) msg.obj;
                     synchronized (mDeviceStateLock) {
@@ -1649,11 +1660,14 @@
     // process set volume for Le Audio, obj is BleVolumeInfo
     private static final int MSG_II_SET_LE_AUDIO_OUT_VOLUME = 46;
 
+    private static final int MSG_IL_BTLEAUDIO_TIMEOUT = 49;
+
     private static boolean isMessageHandledUnderWakelock(int msgId) {
         switch(msgId) {
             case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE:
             case MSG_L_SET_BT_ACTIVE_DEVICE:
             case MSG_IL_BTA2DP_TIMEOUT:
+            case MSG_IL_BTLEAUDIO_TIMEOUT:
             case MSG_L_A2DP_DEVICE_CONFIG_CHANGE:
             case MSG_TOGGLE_HDMI:
             case MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT:
@@ -1744,6 +1758,7 @@
                 case MSG_L_SET_BT_ACTIVE_DEVICE:
                 case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE:
                 case MSG_IL_BTA2DP_TIMEOUT:
+                case MSG_IL_BTLEAUDIO_TIMEOUT:
                 case MSG_L_A2DP_DEVICE_CONFIG_CHANGE:
                     if (sLastDeviceConnectMsgTime >= time) {
                         // add a little delay to make sure messages are ordered as expected
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 35da73e..a74f4154 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -374,7 +374,7 @@
                 case BluetoothProfile.LE_AUDIO:
                 case BluetoothProfile.LE_AUDIO_BROADCAST:
                     if (switchToUnavailable) {
-                        makeLeAudioDeviceUnavailable(address, btInfo.mAudioSystemDevice);
+                        makeLeAudioDeviceUnavailableNow(address, btInfo.mAudioSystemDevice);
                     } else if (switchToAvailable) {
                         makeLeAudioDeviceAvailable(address, BtHelper.getName(btInfo.mDevice),
                                 streamType, btInfo.mVolume == -1 ? -1 : btInfo.mVolume * 10,
@@ -486,6 +486,12 @@
         }
     }
 
+    /*package*/ void onMakeLeAudioDeviceUnavailableNow(String address, int device) {
+        synchronized (mDevicesLock) {
+            makeLeAudioDeviceUnavailableNow(address, device);
+        }
+    }
+
     /*package*/ void onReportNewRoutes() {
         int n = mRoutesObservers.beginBroadcast();
         if (n > 0) {
@@ -883,10 +889,11 @@
             new MediaMetrics.Item(mMetricsId + "disconnectLeAudio")
                     .record();
             if (toRemove.size() > 0) {
-                final int delay = checkSendBecomingNoisyIntentInt(device, 0,
+                final int delay = checkSendBecomingNoisyIntentInt(device,
+                        AudioService.CONNECTION_STATE_DISCONNECTED,
                         AudioSystem.DEVICE_NONE);
                 toRemove.stream().forEach(deviceAddress ->
-                        makeLeAudioDeviceUnavailable(deviceAddress, device)
+                        makeLeAudioDeviceUnavailableLater(deviceAddress, device, delay)
                 );
             }
         }
@@ -1187,9 +1194,21 @@
              */
             mDeviceBroker.setBluetoothA2dpOnInt(true, false /*fromA2dp*/, eventSource);
 
-            AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(device, address, name),
+            final int res = AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
+                    device, address, name),
                     AudioSystem.DEVICE_STATE_AVAILABLE,
                     AudioSystem.AUDIO_FORMAT_DEFAULT);
+            if (res != AudioSystem.AUDIO_STATUS_OK) {
+                AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
+                        "APM failed to make available LE Audio device addr=" + address
+                                + " error=" + res).printLog(TAG));
+                // TODO: connection failed, stop here
+                // TODO: return;
+            } else {
+                AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
+                        "LE Audio device addr=" + address + " now available").printLog(TAG));
+            }
+
             mConnectedDevices.put(DeviceInfo.makeDeviceListKey(device, address),
                     new DeviceInfo(device, name, address, AudioSystem.AUDIO_FORMAT_DEFAULT));
             mDeviceBroker.postAccessoryPlugMediaUnmute(device);
@@ -1210,11 +1229,23 @@
     }
 
     @GuardedBy("mDevicesLock")
-    private void makeLeAudioDeviceUnavailable(String address, int device) {
+    private void makeLeAudioDeviceUnavailableNow(String address, int device) {
         if (device != AudioSystem.DEVICE_NONE) {
-            AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(device, address),
+            final int res = AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
+                    device, address),
                     AudioSystem.DEVICE_STATE_UNAVAILABLE,
                     AudioSystem.AUDIO_FORMAT_DEFAULT);
+
+            if (res != AudioSystem.AUDIO_STATUS_OK) {
+                AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
+                        "APM failed to make unavailable LE Audio device addr=" + address
+                                + " error=" + res).printLog(TAG));
+                // TODO:  failed to disconnect, stop here
+                // TODO: return;
+            } else {
+                AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
+                        "LE Audio device addr=" + address + " made unavailable")).printLog(TAG));
+            }
             mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address));
         }
 
@@ -1222,6 +1253,14 @@
     }
 
     @GuardedBy("mDevicesLock")
+    private void makeLeAudioDeviceUnavailableLater(String address, int device, int delayMs) {
+        // the device will be made unavailable later, so consider it disconnected right away
+        mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address));
+        // send the delayed message to make the device unavailable later
+        mDeviceBroker.setLeAudioTimeout(address, device, delayMs);
+    }
+
+    @GuardedBy("mDevicesLock")
     private void setCurrentAudioRouteNameIfPossible(String name, boolean fromA2dp) {
         synchronized (mCurAudioRoutes) {
             if (TextUtils.equals(mCurAudioRoutes.bluetoothName, name)) {
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index f959821..691ce93 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -291,9 +291,9 @@
         if (mA2dp == null) {
             return AudioSystem.AUDIO_FORMAT_DEFAULT;
         }
-        final BluetoothCodecStatus btCodecStatus = null;
+        BluetoothCodecStatus btCodecStatus = null;
         try {
-            mA2dp.getCodecStatus(device);
+            btCodecStatus = mA2dp.getCodecStatus(device);
         } catch (Exception e) {
             Log.e(TAG, "Exception while getting status of " + device, e);
         }
@@ -489,7 +489,7 @@
     }
 
     // @GuardedBy("AudioDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
+    //@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
     /*package*/ synchronized void resetBluetoothSco() {
         mScoAudioState = SCO_STATE_INACTIVE;
         broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
@@ -532,7 +532,7 @@
         }
     }
 
-    //@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
+    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
     /*package*/ synchronized void onBtProfileConnected(int profile, BluetoothProfile proxy) {
         if (profile == BluetoothProfile.HEADSET) {
             onHeadsetProfileConnected((BluetoothHeadset) proxy);
@@ -564,7 +564,7 @@
     }
 
     // @GuardedBy("AudioDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
+    //@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
     /*package*/ synchronized void onHeadsetProfileConnected(BluetoothHeadset headset) {
         // Discard timeout message
         mDeviceBroker.handleCancelFailureToConnectToBtHeadsetService();
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 598e2b9..94b67ce 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -452,6 +452,13 @@
                 return -1;
             }
 
+            if (!Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId)) {
+                // If this happens, something in KeyguardUpdateMonitor is wrong. This should only
+                // ever be invoked when the user is encrypted or lockdown.
+                Slog.e(TAG, "detectFingerprint invoked when user is not encrypted or lockdown");
+                return -1;
+            }
+
             final Pair<Integer, ServiceProvider> provider = getSingleProvider();
             if (provider == null) {
                 Slog.w(TAG, "Null provider for detectFingerprint");
diff --git a/services/core/java/com/android/server/devicestate/DeviceStatePolicy.java b/services/core/java/com/android/server/devicestate/DeviceStatePolicy.java
index 5c4e2f3..c876a8b 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStatePolicy.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStatePolicy.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.text.TextUtils;
+import android.util.Slog;
 
 import com.android.server.policy.DeviceStatePolicyImpl;
 
@@ -92,11 +93,16 @@
 
             try {
                 return (DeviceStatePolicy.Provider) Class.forName(name).newInstance();
-            } catch (ReflectiveOperationException | ClassCastException e) {
+            } catch (ClassCastException e) {
                 throw new IllegalStateException("Couldn't instantiate class " + name
                         + " for config_deviceSpecificDeviceStatePolicyProvider:"
                         + " make sure it has a public zero-argument constructor"
-                        + " and implements DeviceStatePolicy.Provider", e);
+                        + " and implements DeviceStatePolicy.Provider");
+            } catch (ReflectiveOperationException e) {
+                Slog.e("DeviceStatePolicy", "Couldn't instantiate class " + name
+                        + " for config_deviceSpecificDeviceStatePolicyProvider:"
+                        + " using default provider", e);
+                return new DeviceStatePolicy.DefaultProvider();
             }
         }
     }
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 4341634..909c531 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -434,6 +434,8 @@
     private boolean mIsDocked;
     private boolean mIsDreaming;
 
+    private boolean mBootCompleted = false;
+
     private final BroadcastReceiver mIdleModeReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -573,6 +575,12 @@
                 }
             }
         } else if (phase == PHASE_BOOT_COMPLETED) {
+            synchronized (mSyncRoot) {
+                mBootCompleted = true;
+                for (int i = 0; i < mDisplayPowerControllers.size(); i++) {
+                    mDisplayPowerControllers.valueAt(i).onBootCompleted();
+                }
+            }
             mDisplayModeDirector.onBootCompleted();
             mLogicalDisplayMapper.onBootCompleted();
         }
@@ -2680,7 +2688,7 @@
         final DisplayPowerController displayPowerController = new DisplayPowerController(
                 mContext, mDisplayPowerCallbacks, mPowerHandler, mSensorManager,
                 mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
-                () -> handleBrightnessChange(display), hbmMetadata);
+                () -> handleBrightnessChange(display), hbmMetadata, mBootCompleted);
         mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController);
     }
 
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index b431306..5ecc7f2 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -132,6 +132,8 @@
     private static final int MSG_UPDATE_RBC = 11;
     private static final int MSG_BRIGHTNESS_RAMP_DONE = 12;
     private static final int MSG_STATSD_HBM_BRIGHTNESS = 13;
+    private static final int MSG_SWITCH_USER = 14;
+    private static final int MSG_BOOT_COMPLETED = 15;
 
     private static final int PROXIMITY_UNKNOWN = -1;
     private static final int PROXIMITY_NEGATIVE = 0;
@@ -505,6 +507,8 @@
     private boolean mIsEnabled;
     private boolean mIsInTransition;
 
+    private boolean mBootCompleted;
+
     /**
      * Creates the display power controller.
      */
@@ -512,7 +516,8 @@
             DisplayPowerCallbacks callbacks, Handler handler,
             SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
             BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting,
-            Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata) {
+            Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata,
+            boolean bootCompleted) {
         mLogicalDisplay = logicalDisplay;
         mDisplayId = mLogicalDisplay.getDisplayIdLocked();
         final String displayIdStr = "[" + mDisplayId + "]";
@@ -654,6 +659,7 @@
         mTemporaryAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;
         mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;
 
+        mBootCompleted = bootCompleted;
     }
 
     private void applyReduceBrightColorsSplineAdjustment() {
@@ -703,6 +709,11 @@
     }
 
     public void onSwitchUser(@UserIdInt int newUserId) {
+        Message msg = mHandler.obtainMessage(MSG_SWITCH_USER, newUserId);
+        mHandler.sendMessage(msg);
+    }
+
+    private void handleOnSwitchUser(@UserIdInt int newUserId) {
         handleSettingsChange(true /* userSwitch */);
         handleBrightnessModeChange();
         if (mBrightnessTracker != null) {
@@ -1306,7 +1317,7 @@
 
         if (mScreenOffBrightnessSensorController != null) {
             mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness
-                    && (state == Display.STATE_OFF || (state == Display.STATE_DOZE
+                    && mIsEnabled && (state == Display.STATE_OFF || (state == Display.STATE_DOZE
                     && !mAllowAutoBrightnessWhileDozingConfig)));
         }
 
@@ -1364,7 +1375,7 @@
 
         // Initialize things the first time the power state is changed.
         if (mustInitialize) {
-            initialize(state);
+            initialize(readyToUpdateDisplayState() ? state : Display.STATE_UNKNOWN);
         }
 
         // Animate the screen state change unless already animating.
@@ -2044,7 +2055,8 @@
                 }
             }
 
-            if (!reportOnly && mPowerState.getScreenState() != state) {
+            if (!reportOnly && mPowerState.getScreenState() != state
+                    && readyToUpdateDisplayState()) {
                 Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state);
                 // TODO(b/153319140) remove when we can get this from the above trace invocation
                 SystemProperties.set("debug.tracing.screen_state", String.valueOf(state));
@@ -2491,6 +2503,10 @@
         mBrightnessSetting.setBrightness(brightnessValue);
     }
 
+    void onBootCompleted() {
+        mHandler.obtainMessage(MSG_BOOT_COMPLETED).sendToTarget();
+    }
+
     private void updateScreenBrightnessSetting(float brightnessValue) {
         if (!isValidBrightnessValue(brightnessValue)
                 || brightnessValue == mCurrentScreenBrightnessSetting) {
@@ -2636,6 +2652,17 @@
         }
     };
 
+    /**
+     * Indicates whether the display state is ready to update. If this is the default display, we
+     * want to update it right away so that we can draw the boot animation on it. If it is not
+     * the default display, drawing the boot animation on it would look incorrect, so we need
+     * to wait until boot is completed.
+     * @return True if the display state is ready to update
+     */
+    private boolean readyToUpdateDisplayState() {
+        return mDisplayId == Display.DEFAULT_DISPLAY || mBootCompleted;
+    }
+
     public void dump(final PrintWriter pw) {
         synchronized (mLock) {
             pw.println();
@@ -3167,6 +3194,15 @@
                 case MSG_STATSD_HBM_BRIGHTNESS:
                     logHbmBrightnessStats(Float.intBitsToFloat(msg.arg1), msg.arg2);
                     break;
+
+                case MSG_SWITCH_USER:
+                    handleOnSwitchUser(msg.arg1);
+                    break;
+
+                case MSG_BOOT_COMPLETED:
+                    mBootCompleted = true;
+                    updatePowerState();
+                    break;
             }
         }
     }
diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java
index 97ab587..ccab7bc9 100644
--- a/services/core/java/com/android/server/dreams/DreamController.java
+++ b/services/core/java/com/android/server/dreams/DreamController.java
@@ -123,15 +123,14 @@
             final DreamRecord oldDream = mCurrentDream;
             mCurrentDream = new DreamRecord(token, name, isPreviewMode, canDoze, userId, wakeLock);
             if (oldDream != null) {
-                if (!oldDream.mWakingGently) {
-                    // We will stop these previous dreams once the new dream is started.
-                    mPreviousDreams.add(oldDream);
-                } else if (Objects.equals(oldDream.mName, mCurrentDream.mName)) {
+                if (Objects.equals(oldDream.mName, mCurrentDream.mName)) {
                     // We are attempting to start a dream that is currently waking up gently.
                     // Let's silently stop the old instance here to clear the dream state.
                     // This should happen after the new mCurrentDream is set to avoid announcing
                     // a "dream stopped" state.
                     stopDreamInstance(/* immediately */ true, "restarting same dream", oldDream);
+                } else {
+                    mPreviousDreams.add(oldDream);
                 }
             }
 
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 78cffa6..59794f4 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -80,6 +80,7 @@
 import android.hardware.fingerprint.FingerprintManager;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -117,6 +118,7 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.EventLog;
+import android.util.Log;
 import android.util.LongSparseArray;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -203,7 +205,7 @@
     private static final String TAG = "LockSettingsService";
     private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE;
     private static final String BIOMETRIC_PERMISSION = MANAGE_BIOMETRIC;
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.DEBUG);
 
     private static final int PROFILE_KEY_IV_SIZE = 12;
     private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
index 1203769..678698b 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
@@ -25,6 +25,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.app.trust.IStrongAuthTracker;
 import android.content.Context;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -33,6 +34,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.ArrayMap;
+import android.util.Log;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
@@ -46,8 +48,8 @@
  */
 public class LockSettingsStrongAuth {
 
-    private static final String TAG = "LockSettings";
-    private static final boolean DEBUG = false;
+    private static final String TAG = "LockSettingsStrongAuth";
+    private static final boolean DEBUG = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.DEBUG);
 
     private static final int MSG_REQUIRE_STRONG_AUTH = 1;
     private static final int MSG_REGISTER_TRACKER = 2;
@@ -267,6 +269,7 @@
     }
 
     private void handleScheduleStrongAuthTimeout(int userId) {
+        if (DEBUG) Slog.d(TAG, "handleScheduleStrongAuthTimeout for userId=" + userId);
         rescheduleStrongAuthTimeoutAlarm(mInjector.getElapsedRealtimeMs(), userId);
 
         // cancel current non-strong biometric alarm listener for the user (if there was one)
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index b5fceb5..ff10cbc 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -8543,6 +8543,9 @@
             if (interceptBefore && !record.isIntercepted()
                     && record.isNewEnoughForAlerting(System.currentTimeMillis())) {
                 buzzBeepBlinkLocked(record);
+
+                // Log alert after change in intercepted state to Zen Log as well
+                ZenLog.traceAlertOnUpdatedIntercept(record);
             }
         }
         if (changed) {
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index d344306..1501d69 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -114,6 +114,8 @@
 
     // is this notification currently being intercepted by Zen Mode?
     private boolean mIntercept;
+    // has the intercept value been set explicitly? we only want to log it if new or changed
+    private boolean mInterceptSet;
 
     // is this notification hidden since the app pkg is suspended?
     private boolean mHidden;
@@ -914,6 +916,7 @@
 
     public boolean setIntercepted(boolean intercept) {
         mIntercept = intercept;
+        mInterceptSet = true;
         return mIntercept;
     }
 
@@ -934,6 +937,10 @@
         return mIntercept;
     }
 
+    public boolean hasInterceptBeenSet() {
+        return mInterceptSet;
+    }
+
     public boolean isNewEnoughForAlerting(long now) {
         return getFreshnessMs(now) <= MAX_SOUND_DELAY_MS;
     }
diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java
index c0bc474..35b94e7 100644
--- a/services/core/java/com/android/server/notification/ZenLog.java
+++ b/services/core/java/com/android/server/notification/ZenLog.java
@@ -68,20 +68,23 @@
     private static final int TYPE_MATCHES_CALL_FILTER = 18;
     private static final int TYPE_RECORD_CALLER = 19;
     private static final int TYPE_CHECK_REPEAT_CALLER = 20;
+    private static final int TYPE_ALERT_ON_UPDATED_INTERCEPT = 21;
 
     private static int sNext;
     private static int sSize;
 
     public static void traceIntercepted(NotificationRecord record, String reason) {
-        if (record != null && record.isIntercepted()) return;  // already logged
         append(TYPE_INTERCEPTED, record.getKey() + "," + reason);
     }
 
     public static void traceNotIntercepted(NotificationRecord record, String reason) {
-        if (record != null && record.isUpdate) return;  // already logged
         append(TYPE_NOT_INTERCEPTED, record.getKey() + "," + reason);
     }
 
+    public static void traceAlertOnUpdatedIntercept(NotificationRecord record) {
+        append(TYPE_ALERT_ON_UPDATED_INTERCEPT, record.getKey());
+    }
+
     public static void traceSetRingerModeExternal(int ringerModeOld, int ringerModeNew,
             String caller, int ringerModeInternalIn, int ringerModeInternalOut) {
         append(TYPE_SET_RINGER_MODE_EXTERNAL, caller + ",e:" +
@@ -219,6 +222,7 @@
             case TYPE_MATCHES_CALL_FILTER: return "matches_call_filter";
             case TYPE_RECORD_CALLER: return "record_caller";
             case TYPE_CHECK_REPEAT_CALLER: return "check_repeat_caller";
+            case TYPE_ALERT_ON_UPDATED_INTERCEPT: return "alert_on_updated_intercept";
             default: return "unknown";
         }
     }
diff --git a/services/core/java/com/android/server/notification/ZenModeFiltering.java b/services/core/java/com/android/server/notification/ZenModeFiltering.java
index db0ce2e..5b7b0c1 100644
--- a/services/core/java/com/android/server/notification/ZenModeFiltering.java
+++ b/services/core/java/com/android/server/notification/ZenModeFiltering.java
@@ -155,85 +155,85 @@
 
         if (isCritical(record)) {
             // Zen mode is ignored for critical notifications.
-            ZenLog.traceNotIntercepted(record, "criticalNotification");
+            maybeLogInterceptDecision(record, false, "criticalNotification");
             return false;
         }
         // Make an exception to policy for the notification saying that policy has changed
         if (NotificationManager.Policy.areAllVisualEffectsSuppressed(policy.suppressedVisualEffects)
                 && "android".equals(record.getSbn().getPackageName())
                 && SystemMessageProto.SystemMessage.NOTE_ZEN_UPGRADE == record.getSbn().getId()) {
-            ZenLog.traceNotIntercepted(record, "systemDndChangedNotification");
+            maybeLogInterceptDecision(record, false, "systemDndChangedNotification");
             return false;
         }
         switch (zen) {
             case Global.ZEN_MODE_NO_INTERRUPTIONS:
                 // #notevenalarms
-                ZenLog.traceIntercepted(record, "none");
+                maybeLogInterceptDecision(record, true, "none");
                 return true;
             case Global.ZEN_MODE_ALARMS:
                 if (isAlarm(record)) {
                     // Alarms only
-                    ZenLog.traceNotIntercepted(record, "alarm");
+                    maybeLogInterceptDecision(record, false, "alarm");
                     return false;
                 }
-                ZenLog.traceIntercepted(record, "alarmsOnly");
+                maybeLogInterceptDecision(record, true, "alarmsOnly");
                 return true;
             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
                 // allow user-prioritized packages through in priority mode
                 if (record.getPackagePriority() == Notification.PRIORITY_MAX) {
-                    ZenLog.traceNotIntercepted(record, "priorityApp");
+                    maybeLogInterceptDecision(record, false, "priorityApp");
                     return false;
                 }
 
                 if (isAlarm(record)) {
                     if (!policy.allowAlarms()) {
-                        ZenLog.traceIntercepted(record, "!allowAlarms");
+                        maybeLogInterceptDecision(record, true, "!allowAlarms");
                         return true;
                     }
-                    ZenLog.traceNotIntercepted(record, "allowedAlarm");
+                    maybeLogInterceptDecision(record, false, "allowedAlarm");
                     return false;
                 }
                 if (isEvent(record)) {
                     if (!policy.allowEvents()) {
-                        ZenLog.traceIntercepted(record, "!allowEvents");
+                        maybeLogInterceptDecision(record, true, "!allowEvents");
                         return true;
                     }
-                    ZenLog.traceNotIntercepted(record, "allowedEvent");
+                    maybeLogInterceptDecision(record, false, "allowedEvent");
                     return false;
                 }
                 if (isReminder(record)) {
                     if (!policy.allowReminders()) {
-                        ZenLog.traceIntercepted(record, "!allowReminders");
+                        maybeLogInterceptDecision(record, true, "!allowReminders");
                         return true;
                     }
-                    ZenLog.traceNotIntercepted(record, "allowedReminder");
+                    maybeLogInterceptDecision(record, false, "allowedReminder");
                     return false;
                 }
                 if (isMedia(record)) {
                     if (!policy.allowMedia()) {
-                        ZenLog.traceIntercepted(record, "!allowMedia");
+                        maybeLogInterceptDecision(record, true, "!allowMedia");
                         return true;
                     }
-                    ZenLog.traceNotIntercepted(record, "allowedMedia");
+                    maybeLogInterceptDecision(record, false, "allowedMedia");
                     return false;
                 }
                 if (isSystem(record)) {
                     if (!policy.allowSystem()) {
-                        ZenLog.traceIntercepted(record, "!allowSystem");
+                        maybeLogInterceptDecision(record, true, "!allowSystem");
                         return true;
                     }
-                    ZenLog.traceNotIntercepted(record, "allowedSystem");
+                    maybeLogInterceptDecision(record, false, "allowedSystem");
                     return false;
                 }
                 if (isConversation(record)) {
                     if (policy.allowConversations()) {
                         if (policy.priorityConversationSenders == CONVERSATION_SENDERS_ANYONE) {
-                            ZenLog.traceNotIntercepted(record, "conversationAnyone");
+                            maybeLogInterceptDecision(record, false, "conversationAnyone");
                             return false;
                         } else if (policy.priorityConversationSenders
                                 == NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT
                                 && record.getChannel().isImportantConversation()) {
-                            ZenLog.traceNotIntercepted(record, "conversationMatches");
+                            maybeLogInterceptDecision(record, false, "conversationMatches");
                             return false;
                         }
                     }
@@ -244,31 +244,59 @@
                     if (policy.allowRepeatCallers()
                             && REPEAT_CALLERS.isRepeat(
                                     mContext, extras(record), record.getPhoneNumbers())) {
-                        ZenLog.traceNotIntercepted(record, "repeatCaller");
+                        maybeLogInterceptDecision(record, false, "repeatCaller");
                         return false;
                     }
                     if (!policy.allowCalls()) {
-                        ZenLog.traceIntercepted(record, "!allowCalls");
+                        maybeLogInterceptDecision(record, true, "!allowCalls");
                         return true;
                     }
                     return shouldInterceptAudience(policy.allowCallsFrom(), record);
                 }
                 if (isMessage(record)) {
                     if (!policy.allowMessages()) {
-                        ZenLog.traceIntercepted(record, "!allowMessages");
+                        maybeLogInterceptDecision(record, true, "!allowMessages");
                         return true;
                     }
                     return shouldInterceptAudience(policy.allowMessagesFrom(), record);
                 }
 
-                ZenLog.traceIntercepted(record, "!priority");
+                maybeLogInterceptDecision(record, true, "!priority");
                 return true;
             default:
-                ZenLog.traceNotIntercepted(record, "unknownZenMode");
+                maybeLogInterceptDecision(record, false, "unknownZenMode");
                 return false;
         }
     }
 
+    // Consider logging the decision of shouldIntercept for the given record.
+    // This will log the outcome if one of the following is true:
+    //   - it's the first time the intercept decision is set for the record
+    //   - OR it's not the first time, but the intercept decision changed
+    private static void maybeLogInterceptDecision(NotificationRecord record, boolean intercept,
+            String reason) {
+        boolean interceptBefore = record.isIntercepted();
+        if (record.hasInterceptBeenSet() && (interceptBefore == intercept)) {
+            // this record has already been evaluated for whether it should be intercepted, and
+            // the decision has not changed.
+            return;
+        }
+
+        // add a note to the reason indicating whether it's new or updated
+        String annotatedReason = reason;
+        if (!record.hasInterceptBeenSet()) {
+            annotatedReason = "new:" + reason;
+        } else if (interceptBefore != intercept) {
+            annotatedReason = "updated:" + reason;
+        }
+
+        if (intercept) {
+            ZenLog.traceIntercepted(record, annotatedReason);
+        } else {
+            ZenLog.traceNotIntercepted(record, annotatedReason);
+        }
+    }
+
     /**
      * Check if the notification is too critical to be suppressed.
      *
@@ -285,10 +313,10 @@
     private static boolean shouldInterceptAudience(int source, NotificationRecord record) {
         float affinity = record.getContactAffinity();
         if (!audienceMatches(source, affinity)) {
-            ZenLog.traceIntercepted(record, "!audienceMatches,affinity=" + affinity);
+            maybeLogInterceptDecision(record, true, "!audienceMatches,affinity=" + affinity);
             return true;
         }
-        ZenLog.traceNotIntercepted(record, "affinity=" + affinity);
+        maybeLogInterceptDecision(record, false, "affinity=" + affinity);
         return false;
     }
 
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 632a34e..9212331 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -430,6 +430,7 @@
             @NonNull List<ShortcutInfo> changedShortcuts) {
         Preconditions.checkArgument(newShortcut.isEnabled(),
                 "pushDynamicShortcuts() cannot publish disabled shortcuts");
+        ensureShortcutCountBeforePush();
 
         newShortcut.addFlags(ShortcutInfo.FLAG_DYNAMIC);
 
@@ -437,7 +438,7 @@
         final ShortcutInfo oldShortcut = findShortcutById(newShortcut.getId());
         boolean deleted = false;
 
-        if (oldShortcut == null) {
+        if (oldShortcut == null || !oldShortcut.isDynamic()) {
             final ShortcutService service = mShortcutUser.mService;
             final int maxShortcuts = service.getMaxActivityShortcuts();
 
@@ -446,18 +447,12 @@
             final ArrayList<ShortcutInfo> activityShortcuts = all.get(newShortcut.getActivity());
 
             if (activityShortcuts != null && activityShortcuts.size() > maxShortcuts) {
-                Slog.e(TAG, "Error pushing shortcut. There are already "
-                        + activityShortcuts.size() + " shortcuts, exceeding the " + maxShortcuts
-                        + " shortcuts limit when pushing the new shortcut " + newShortcut
-                        + ". Id of shortcuts currently available in system memory are "
-                        + activityShortcuts.stream().map(ShortcutInfo::getId)
-                        .collect(Collectors.joining(",", "[", "]")));
-                // TODO: This should not have happened. If it does, identify the root cause where
-                //  possible, otherwise bail-out early to prevent memory issue.
+                // Root cause was discovered in b/233155034, so this should not be happening.
+                service.wtf("Error pushing shortcut. There are already "
+                        + activityShortcuts.size() + " shortcuts.");
             }
             if (activityShortcuts != null && activityShortcuts.size() == maxShortcuts) {
                 // Max has reached. Delete the shortcut with lowest rank.
-
                 // Sort by isManifestShortcut() and getRank().
                 Collections.sort(activityShortcuts, mShortcutTypeAndRankComparator);
 
@@ -473,7 +468,8 @@
                 deleted = deleteDynamicWithId(shortcut.getId(), /* ignoreInvisible =*/ true,
                         /*ignorePersistedShortcuts=*/ true) != null;
             }
-        } else {
+        }
+        if (oldShortcut != null) {
             // It's an update case.
             // Make sure the target is updatable. (i.e. should be mutable.)
             oldShortcut.ensureUpdatableWith(newShortcut, /*isUpdating=*/ false);
@@ -505,6 +501,32 @@
         return deleted;
     }
 
+    private void ensureShortcutCountBeforePush() {
+        final ShortcutService service = mShortcutUser.mService;
+        // Ensure the total number of shortcuts doesn't exceed the hard limit per app.
+        final int maxShortcutPerApp = service.getMaxAppShortcuts();
+        synchronized (mLock) {
+            final List<ShortcutInfo> appShortcuts = mShortcuts.values().stream().filter(si ->
+                    !si.isPinned()).collect(Collectors.toList());
+            if (appShortcuts.size() >= maxShortcutPerApp) {
+                // Max has reached. Removes shortcuts until they fall within the hard cap.
+                // Sort by isManifestShortcut(), isDynamic() and getLastChangedTimestamp().
+                Collections.sort(appShortcuts, mShortcutTypeRankAndTimeComparator);
+
+                while (appShortcuts.size() >= maxShortcutPerApp) {
+                    final ShortcutInfo shortcut = appShortcuts.remove(appShortcuts.size() - 1);
+                    if (shortcut.isDeclaredInManifest()) {
+                        // All shortcuts are manifest shortcuts and cannot be removed.
+                        throw new IllegalArgumentException(getPackageName() + " has published "
+                                + appShortcuts.size() + " manifest shortcuts across different"
+                                + " activities.");
+                    }
+                    forceDeleteShortcutInner(shortcut.getId());
+                }
+            }
+        }
+    }
+
     /**
      * Remove all shortcuts that aren't pinned, cached nor dynamic.
      *
@@ -1371,6 +1393,61 @@
     };
 
     /**
+     * To sort by isManifestShortcut(), isDynamic(), getRank() and
+     * getLastChangedTimestamp(). i.e. manifest shortcuts come before non-manifest shortcuts,
+     * dynamic shortcuts come before floating shortcuts, then sort by last changed timestamp.
+     *
+     * This is used to decide which shortcuts to remove when the total number of shortcuts retained
+     * for the app exceeds the limit defined in {@link ShortcutService#getMaxAppShortcuts()}.
+     *
+     * (Note the number of manifest shortcuts is always <= the max number, because if there are
+     * more, ShortcutParser would ignore the rest.)
+     */
+    final Comparator<ShortcutInfo> mShortcutTypeRankAndTimeComparator = (ShortcutInfo a,
+            ShortcutInfo b) -> {
+        if (a.isDeclaredInManifest() && !b.isDeclaredInManifest()) {
+            return -1;
+        }
+        if (!a.isDeclaredInManifest() && b.isDeclaredInManifest()) {
+            return 1;
+        }
+        if (a.isDynamic() && b.isDynamic()) {
+            return Integer.compare(a.getRank(), b.getRank());
+        }
+        if (a.isDynamic()) {
+            return -1;
+        }
+        if (b.isDynamic()) {
+            return 1;
+        }
+        if (a.isCached() && b.isCached()) {
+            // if both shortcuts are cached, prioritize shortcuts cached by people tile,
+            if (a.hasFlags(ShortcutInfo.FLAG_CACHED_PEOPLE_TILE)
+                    && !b.hasFlags(ShortcutInfo.FLAG_CACHED_PEOPLE_TILE)) {
+                return -1;
+            } else if (!a.hasFlags(ShortcutInfo.FLAG_CACHED_PEOPLE_TILE)
+                    && b.hasFlags(ShortcutInfo.FLAG_CACHED_PEOPLE_TILE)) {
+                return 1;
+            }
+            // followed by bubbles.
+            if (a.hasFlags(ShortcutInfo.FLAG_CACHED_BUBBLES)
+                    && !b.hasFlags(ShortcutInfo.FLAG_CACHED_BUBBLES)) {
+                return -1;
+            } else if (!a.hasFlags(ShortcutInfo.FLAG_CACHED_BUBBLES)
+                    && b.hasFlags(ShortcutInfo.FLAG_CACHED_BUBBLES)) {
+                return 1;
+            }
+        }
+        if (a.isCached()) {
+            return -1;
+        }
+        if (b.isCached()) {
+            return 1;
+        }
+        return Long.compare(b.getLastChangedTimestamp(), a.getLastChangedTimestamp());
+    };
+
+    /**
      * Build a list of shortcuts for each target activity and return as a map. The result won't
      * contain "floating" shortcuts because they don't belong on any activities.
      */
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 49831d7..7fc46fd 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -181,6 +181,9 @@
     static final int DEFAULT_MAX_SHORTCUTS_PER_ACTIVITY = 15;
 
     @VisibleForTesting
+    static final int DEFAULT_MAX_SHORTCUTS_PER_APP = 100;
+
+    @VisibleForTesting
     static final int DEFAULT_MAX_ICON_DIMENSION_DP = 96;
 
     @VisibleForTesting
@@ -257,6 +260,11 @@
         String KEY_MAX_SHORTCUTS = "max_shortcuts";
 
         /**
+         * Key name for the max shortcuts can be retained in system ram per app. (int)
+         */
+        String KEY_MAX_SHORTCUTS_PER_APP = "max_shortcuts_per_app";
+
+        /**
          * Key name for icon compression quality, 0-100.
          */
         String KEY_ICON_QUALITY = "icon_quality";
@@ -329,11 +337,16 @@
             new SparseArray<>();
 
     /**
-     * Max number of dynamic + manifest shortcuts that each application can have at a time.
+     * Max number of dynamic + manifest shortcuts that each activity can have at a time.
      */
     private int mMaxShortcuts;
 
     /**
+     * Max number of shortcuts that can exists in system ram for each application.
+     */
+    private int mMaxShortcutsPerApp;
+
+    /**
      * Max number of updating API calls that each application can make during the interval.
      */
     int mMaxUpdatesPerInterval;
@@ -807,6 +820,9 @@
         mMaxShortcuts = Math.max(0, (int) parser.getLong(
                 ConfigConstants.KEY_MAX_SHORTCUTS, DEFAULT_MAX_SHORTCUTS_PER_ACTIVITY));
 
+        mMaxShortcutsPerApp = Math.max(0, (int) parser.getLong(
+                ConfigConstants.KEY_MAX_SHORTCUTS_PER_APP, DEFAULT_MAX_SHORTCUTS_PER_APP));
+
         final int iconDimensionDp = Math.max(1, injectIsLowRamDevice()
                 ? (int) parser.getLong(
                 ConfigConstants.KEY_MAX_ICON_DIMENSION_DP_LOWRAM,
@@ -1759,6 +1775,13 @@
     }
 
     /**
+     * Return the max number of shortcuts can be retaiend in system ram for each application.
+     */
+    int getMaxAppShortcuts() {
+        return mMaxShortcutsPerApp;
+    }
+
+    /**
      * - Sends a notification to LauncherApps
      * - Write to file
      */
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 20c9a21..9ed5aa7 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -3268,7 +3268,7 @@
         if (Objects.equals(packageName, PLATFORM_PACKAGE_NAME)) {
             return true;
         }
-        if (!pkg.isPrivileged()) {
+        if (!(pkg.isSystem() && pkg.isPrivileged())) {
             return true;
         }
         if (!mPrivilegedPermissionAllowlistSourcePackageNames
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 7370d61..f913cef 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3324,8 +3324,8 @@
     }
 
     @Override
-    public void onKeyguardOccludedChangedLw(boolean occluded) {
-        if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) {
+    public void onKeyguardOccludedChangedLw(boolean occluded, boolean waitAppTransition) {
+        if (mKeyguardDelegate != null && waitAppTransition) {
             mPendingKeyguardOccluded = occluded;
             mKeyguardOccludedChanged = true;
         } else {
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 4f00992..77007fa 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -166,9 +166,10 @@
 
     /**
      * Called when the Keyguard occluded state changed.
+     *
      * @param occluded Whether Keyguard is currently occluded or not.
      */
-    void onKeyguardOccludedChangedLw(boolean occluded);
+    void onKeyguardOccludedChangedLw(boolean occluded, boolean waitAppTransition);
 
     /**
      * Applies a keyguard occlusion change if one happened.
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 8aca912..5f8e01e 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -341,6 +341,7 @@
 import android.window.WindowContainerToken;
 
 import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.ResolverActivity;
 import com.android.internal.content.ReferrerIntent;
@@ -503,7 +504,10 @@
     private RemoteTransition mPendingRemoteTransition;
     ActivityOptions returningOptions; // options that are coming back via convertToTranslucent
     AppTimeTracker appTimeTracker; // set if we are tracking the time in this app/task/activity
+    @GuardedBy("this")
     ActivityServiceConnectionsHolder mServiceConnectionsHolder; // Service connections.
+    /** @see android.content.Context#BIND_ADJUST_WITH_ACTIVITY */
+    volatile boolean mVisibleForServiceConnection;
     UriPermissionOwner uriPermissions; // current special URI access perms.
     WindowProcessController app;      // if non-null, hosting application
     private State mState;    // current state we are in
@@ -553,7 +557,8 @@
     long lastLaunchTime;    // time of last launch of this activity
     ComponentName requestedVrComponent; // the requested component for handling VR mode.
 
-    boolean inHistory;  // are we in the history task?
+    /** Whether this activity is reachable from hierarchy. */
+    volatile boolean inHistory;
     final ActivityTaskSupervisor mTaskSupervisor;
     final RootWindowContainer mRootWindowContainer;
 
@@ -1904,7 +1909,9 @@
         }
     }
 
-    static @Nullable ActivityRecord forTokenLocked(IBinder token) {
+    /** Gets the corresponding record by the token. Note that it may not exist in the hierarchy. */
+    @Nullable
+    static ActivityRecord forToken(IBinder token) {
         if (token == null) return null;
         final Token activityToken;
         try {
@@ -1913,7 +1920,11 @@
             Slog.w(TAG, "Bad activity token: " + token, e);
             return null;
         }
-        final ActivityRecord r = activityToken.mActivityRef.get();
+        return activityToken.mActivityRef.get();
+    }
+
+    static @Nullable ActivityRecord forTokenLocked(IBinder token) {
+        final ActivityRecord r = forToken(token);
         return r == null || r.getRootTask() == null ? null : r;
     }
 
@@ -4036,17 +4047,32 @@
         mDisplayContent.getDisplayPolicy().removeRelaunchingApp(this);
     }
 
+    ActivityServiceConnectionsHolder getOrCreateServiceConnectionsHolder() {
+        synchronized (this) {
+            if (mServiceConnectionsHolder == null) {
+                mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(this);
+            }
+            return mServiceConnectionsHolder;
+        }
+    }
+
     /**
      * Perform clean-up of service connections in an activity record.
      */
     private void cleanUpActivityServices() {
-        if (mServiceConnectionsHolder == null) {
-            return;
+        synchronized (this) {
+            if (mServiceConnectionsHolder == null) {
+                return;
+            }
+            // Throw away any services that have been bound by this activity.
+            mServiceConnectionsHolder.disconnectActivityFromServices();
+            // This activity record is removing, make sure not to disconnect twice.
+            mServiceConnectionsHolder = null;
         }
-        // Throw away any services that have been bound by this activity.
-        mServiceConnectionsHolder.disconnectActivityFromServices();
-        // This activity record is removing, make sure not to disconnect twice.
-        mServiceConnectionsHolder = null;
+    }
+
+    private void updateVisibleForServiceConnection() {
+        mVisibleForServiceConnection = mVisibleRequested || mState == RESUMED || mState == PAUSING;
     }
 
     /**
@@ -5139,6 +5165,7 @@
             taskFragment.onActivityVisibleRequestedChanged();
         }
         setInsetsFrozen(!visible);
+        updateVisibleForServiceConnection();
         if (app != null) {
             mTaskSupervisor.onProcessActivityStateChanged(app, false /* forceBatch */);
         }
@@ -5617,6 +5644,7 @@
                 return;
             }
         }
+        updateVisibleForServiceConnection();
         if (app != null) {
             mTaskSupervisor.onProcessActivityStateChanged(app, false /* forceBatch */);
         }
@@ -7880,6 +7908,14 @@
     }
 
     /**
+     * @return The {@code true} if the current instance has {@link mCompatDisplayInsets} without
+     * considering the inheritance implemented in {@link #getCompatDisplayInsets()}
+     */
+    boolean hasCompatDisplayInsetsWithoutInheritance() {
+        return mCompatDisplayInsets != null;
+    }
+
+    /**
      * @return {@code true} if this activity is in size compatibility mode that uses the different
      *         density than its parent or its bounds don't fit in parent naturally.
      */
@@ -7887,7 +7923,7 @@
         if (mInSizeCompatModeForBounds) {
             return true;
         }
-        if (mCompatDisplayInsets == null || !shouldCreateCompatDisplayInsets()
+        if (getCompatDisplayInsets() == null || !shouldCreateCompatDisplayInsets()
                 // The orientation is different from parent when transforming.
                 || isFixedRotationTransforming()) {
             return false;
@@ -7958,11 +7994,7 @@
 
     // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
     private void updateCompatDisplayInsets() {
-        if (mLetterboxUiController.hasInheritedLetterboxBehavior()) {
-            mCompatDisplayInsets =  mLetterboxUiController.getInheritedCompatDisplayInsets();
-            return;
-        }
-        if (mCompatDisplayInsets != null || !shouldCreateCompatDisplayInsets()) {
+        if (getCompatDisplayInsets() != null || !shouldCreateCompatDisplayInsets()) {
             // The override configuration is set only once in size compatibility mode.
             return;
         }
@@ -8025,9 +8057,6 @@
 
     @Override
     float getCompatScale() {
-        if (mLetterboxUiController.hasInheritedLetterboxBehavior()) {
-            return mLetterboxUiController.getInheritedSizeCompatScale();
-        }
         return hasSizeCompatBounds() ? mSizeCompatScale : super.getCompatScale();
     }
 
@@ -8071,7 +8100,7 @@
             resolveFixedOrientationConfiguration(newParentConfiguration);
         }
 
-        if (mCompatDisplayInsets != null) {
+        if (getCompatDisplayInsets() != null) {
             resolveSizeCompatModeConfiguration(newParentConfiguration);
         } else if (inMultiWindowMode() && !isFixedOrientationLetterboxAllowed) {
             // We ignore activities' requested orientation in multi-window modes. They may be
@@ -8089,7 +8118,7 @@
             resolveAspectRatioRestriction(newParentConfiguration);
         }
 
-        if (isFixedOrientationLetterboxAllowed || mCompatDisplayInsets != null
+        if (isFixedOrientationLetterboxAllowed || getCompatDisplayInsets() != null
                 // In fullscreen, can be letterboxed for aspect ratio.
                 || !inMultiWindowMode()) {
             updateResolvedBoundsPosition(newParentConfiguration);
@@ -8097,7 +8126,8 @@
 
         boolean isIgnoreOrientationRequest = mDisplayContent != null
                 && mDisplayContent.getIgnoreOrientationRequest();
-        if (mCompatDisplayInsets == null // for size compat mode set in updateCompatDisplayInsets
+        if (getCompatDisplayInsets() == null
+                // for size compat mode set in updateCompatDisplayInsets
                 // Fixed orientation letterboxing is possible on both large screen devices
                 // with ignoreOrientationRequest enabled and on phones in split screen even with
                 // ignoreOrientationRequest disabled.
@@ -8143,7 +8173,7 @@
                         info.neverSandboxDisplayApis(sConstrainDisplayApisConfig),
                         info.alwaysSandboxDisplayApis(sConstrainDisplayApisConfig),
                         !matchParentBounds(),
-                        mCompatDisplayInsets != null,
+                        getCompatDisplayInsets() != null,
                         shouldCreateCompatDisplayInsets());
             }
             resolvedConfig.windowConfiguration.setMaxBounds(mTmpBounds);
@@ -8442,8 +8472,9 @@
                 || orientationRespectedWithInsets)) {
             return;
         }
+        final CompatDisplayInsets compatDisplayInsets = getCompatDisplayInsets();
 
-        if (mCompatDisplayInsets != null && !mCompatDisplayInsets.mIsInFixedOrientationLetterbox) {
+        if (compatDisplayInsets != null && !compatDisplayInsets.mIsInFixedOrientationLetterbox) {
             // App prefers to keep its original size.
             // If the size compat is from previous fixed orientation letterboxing, we may want to
             // have fixed orientation letterbox again, otherwise it will show the size compat
@@ -8498,9 +8529,9 @@
         mIsAspectRatioApplied = applyAspectRatio(resolvedBounds, containingBoundsWithInsets,
                 containingBounds, desiredAspectRatio);
 
-        if (mCompatDisplayInsets != null) {
-            mCompatDisplayInsets.getBoundsByRotation(
-                    mTmpBounds, newParentConfig.windowConfiguration.getRotation());
+        if (compatDisplayInsets != null) {
+            compatDisplayInsets.getBoundsByRotation(mTmpBounds,
+                    newParentConfig.windowConfiguration.getRotation());
             if (resolvedBounds.width() != mTmpBounds.width()
                     || resolvedBounds.height() != mTmpBounds.height()) {
                 // The app shouldn't be resized, we only do fixed orientation letterboxing if the
@@ -8514,7 +8545,7 @@
         // Calculate app bounds using fixed orientation bounds because they will be needed later
         // for comparison with size compat app bounds in {@link resolveSizeCompatModeConfiguration}.
         getTaskFragment().computeConfigResourceOverrides(getResolvedOverrideConfiguration(),
-                newParentConfig, mCompatDisplayInsets);
+                newParentConfig, compatDisplayInsets);
         mLetterboxBoundsForFixedOrientationAndAspectRatio = new Rect(resolvedBounds);
     }
 
@@ -8571,13 +8602,13 @@
                 ? requestedOrientation
                 // We should use the original orientation of the activity when possible to avoid
                 // forcing the activity in the opposite orientation.
-                : mCompatDisplayInsets.mOriginalRequestedOrientation != ORIENTATION_UNDEFINED
-                        ? mCompatDisplayInsets.mOriginalRequestedOrientation
+                : getCompatDisplayInsets().mOriginalRequestedOrientation != ORIENTATION_UNDEFINED
+                        ? getCompatDisplayInsets().mOriginalRequestedOrientation
                         : newParentConfiguration.orientation;
         int rotation = newParentConfiguration.windowConfiguration.getRotation();
         final boolean isFixedToUserRotation = mDisplayContent == null
                 || mDisplayContent.getDisplayRotation().isFixedToUserRotation();
-        if (!isFixedToUserRotation && !mCompatDisplayInsets.mIsFloating) {
+        if (!isFixedToUserRotation && !getCompatDisplayInsets().mIsFloating) {
             // Use parent rotation because the original display can be rotated.
             resolvedConfig.windowConfiguration.setRotation(rotation);
         } else {
@@ -8593,11 +8624,11 @@
         // rely on them to contain the original and unchanging width and height of the app.
         final Rect containingAppBounds = new Rect();
         final Rect containingBounds = mTmpBounds;
-        mCompatDisplayInsets.getContainerBounds(containingAppBounds, containingBounds, rotation,
+        getCompatDisplayInsets().getContainerBounds(containingAppBounds, containingBounds, rotation,
                 orientation, orientationRequested, isFixedToUserRotation);
         resolvedBounds.set(containingBounds);
         // The size of floating task is fixed (only swap), so the aspect ratio is already correct.
-        if (!mCompatDisplayInsets.mIsFloating) {
+        if (!getCompatDisplayInsets().mIsFloating) {
             mIsAspectRatioApplied =
                     applyAspectRatio(resolvedBounds, containingAppBounds, containingBounds);
         }
@@ -8606,7 +8637,7 @@
         // are calculated in compat container space. The actual position on screen will be applied
         // later, so the calculation is simpler that doesn't need to involve offset from parent.
         getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration,
-                mCompatDisplayInsets);
+                getCompatDisplayInsets());
         // Use current screen layout as source because the size of app is independent to parent.
         resolvedConfig.screenLayout = TaskFragment.computeScreenLayoutOverride(
                 getConfiguration().screenLayout, resolvedConfig.screenWidthDp,
@@ -8641,14 +8672,9 @@
 
         // Calculates the scale the size compatibility bounds into the region which is available
         // to application.
-        final int contentW = resolvedAppBounds.width();
-        final int contentH = resolvedAppBounds.height();
-        final int viewportW = containerAppBounds.width();
-        final int viewportH = containerAppBounds.height();
         final float lastSizeCompatScale = mSizeCompatScale;
-        // Only allow to scale down.
-        mSizeCompatScale = (contentW <= viewportW && contentH <= viewportH)
-                ? 1f : Math.min((float) viewportW / contentW, (float) viewportH / contentH);
+        updateSizeCompatScale(resolvedAppBounds, containerAppBounds);
+
         final int containerTopInset = containerAppBounds.top - containerBounds.top;
         final boolean topNotAligned =
                 containerTopInset != resolvedAppBounds.top - resolvedBounds.top;
@@ -8688,6 +8714,20 @@
                 isInSizeCompatModeForBounds(resolvedAppBounds, containerAppBounds);
     }
 
+    void updateSizeCompatScale(Rect resolvedAppBounds, Rect containerAppBounds) {
+        // Only allow to scale down.
+        mSizeCompatScale = mLetterboxUiController.findOpaqueNotFinishingActivityBelow()
+                .map(activityRecord -> activityRecord.mSizeCompatScale)
+                .orElseGet(() -> {
+                    final int contentW = resolvedAppBounds.width();
+                    final int contentH = resolvedAppBounds.height();
+                    final int viewportW = containerAppBounds.width();
+                    final int viewportH = containerAppBounds.height();
+                    return (contentW <= viewportW && contentH <= viewportH) ? 1f : Math.min(
+                            (float) viewportW / contentW, (float) viewportH / contentH);
+                });
+    }
+
     private boolean isInSizeCompatModeForBounds(final Rect appBounds, final Rect containerBounds) {
         if (mLetterboxUiController.hasInheritedLetterboxBehavior()) {
             // To avoid wrong app behaviour, we decided to disable SCM when a translucent activity
@@ -8750,10 +8790,16 @@
 
     @Override
     public Rect getBounds() {
-        if (mSizeCompatBounds != null) {
-            return mSizeCompatBounds;
-        }
-        return super.getBounds();
+        // TODO(b/268458693): Refactor configuration inheritance in case of translucent activities
+        final Rect superBounds = super.getBounds();
+        return mLetterboxUiController.findOpaqueNotFinishingActivityBelow()
+                .map(ActivityRecord::getBounds)
+                .orElseGet(() -> {
+                    if (mSizeCompatBounds != null) {
+                        return mSizeCompatBounds;
+                    }
+                    return superBounds;
+                });
     }
 
     @Override
@@ -8778,7 +8824,7 @@
         // Max bounds should be sandboxed when an activity should have compatDisplayInsets, and it
         // will keep the same bounds and screen configuration when it was first launched regardless
         // how its parent window changes, so that the sandbox API will provide a consistent result.
-        if (mCompatDisplayInsets != null || shouldCreateCompatDisplayInsets()) {
+        if (getCompatDisplayInsets() != null || shouldCreateCompatDisplayInsets()) {
             return true;
         }
 
@@ -8820,7 +8866,7 @@
                 mTransitionController.collect(this);
             }
         }
-        if (mCompatDisplayInsets != null) {
+        if (getCompatDisplayInsets() != null) {
             Configuration overrideConfig = getRequestedOverrideConfiguration();
             // Adapt to changes in orientation locking. The app is still non-resizable, but
             // it can change which orientation is fixed. If the fixed orientation changes,
@@ -8896,7 +8942,7 @@
         if (mVisibleRequested) {
             // It may toggle the UI for user to restart the size compatibility mode activity.
             display.handleActivitySizeCompatModeIfNeeded(this);
-        } else if (mCompatDisplayInsets != null && !visibleIgnoringKeyguard
+        } else if (getCompatDisplayInsets() != null && !visibleIgnoringKeyguard
                 && (app == null || !app.hasVisibleActivities())) {
             // visibleIgnoringKeyguard is checked to avoid clearing mCompatDisplayInsets during
             // displays change. Displays are turned off during the change so mVisibleRequested
diff --git a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
index 0859d40..5f56af7 100644
--- a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
+++ b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
@@ -16,14 +16,14 @@
 
 package com.android.server.wm;
 
-import static com.android.server.wm.ActivityRecord.State.PAUSING;
-import static com.android.server.wm.ActivityRecord.State.RESUMED;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
 
 import android.util.ArraySet;
 import android.util.Slog;
 
+import com.android.internal.annotations.GuardedBy;
+
 import java.io.PrintWriter;
 import java.util.function.Consumer;
 
@@ -38,8 +38,6 @@
  */
 public class ActivityServiceConnectionsHolder<T> {
 
-    private final ActivityTaskManagerService mService;
-
     /** The activity the owns this service connection object. */
     private final ActivityRecord mActivity;
 
@@ -49,19 +47,19 @@
      * on the WM side since we don't perform operations on the object. Mainly here for communication
      * and booking with the AM side.
      */
+    @GuardedBy("mActivity")
     private ArraySet<T> mConnections;
 
     /** Whether all connections of {@link #mActivity} are being removed. */
     private volatile boolean mIsDisconnecting;
 
-    ActivityServiceConnectionsHolder(ActivityTaskManagerService service, ActivityRecord activity) {
-        mService = service;
+    ActivityServiceConnectionsHolder(ActivityRecord activity) {
         mActivity = activity;
     }
 
     /** Adds a connection record that the activity has bound to a specific service. */
     public void addConnection(T c) {
-        synchronized (mService.mGlobalLock) {
+        synchronized (mActivity) {
             if (mIsDisconnecting) {
                 // This is unlikely to happen because the caller should create a new holder.
                 if (DEBUG_CLEANUP) {
@@ -79,7 +77,7 @@
 
     /** Removed a connection record between the activity and a specific service. */
     public void removeConnection(T c) {
-        synchronized (mService.mGlobalLock) {
+        synchronized (mActivity) {
             if (mConnections == null) {
                 return;
             }
@@ -90,20 +88,18 @@
         }
     }
 
+    /** @see android.content.Context#BIND_ADJUST_WITH_ACTIVITY */
     public boolean isActivityVisible() {
-        synchronized (mService.mGlobalLock) {
-            return mActivity.isVisibleRequested() || mActivity.isState(RESUMED, PAUSING);
-        }
+        return mActivity.mVisibleForServiceConnection;
     }
 
     public int getActivityPid() {
-        synchronized (mService.mGlobalLock) {
-            return mActivity.hasProcess() ? mActivity.app.getPid() : -1;
-        }
+        final WindowProcessController wpc = mActivity.app;
+        return wpc != null ? wpc.getPid() : -1;
     }
 
     public void forEachConnection(Consumer<T> consumer) {
-        synchronized (mService.mGlobalLock) {
+        synchronized (mActivity) {
             if (mConnections == null || mConnections.isEmpty()) {
                 return;
             }
@@ -118,6 +114,7 @@
      * general, this method is used to clean up if the activity didn't unbind services before it
      * is destroyed.
      */
+    @GuardedBy("mActivity")
     void disconnectActivityFromServices() {
         if (mConnections == null || mConnections.isEmpty() || mIsDisconnecting) {
             return;
@@ -130,16 +127,14 @@
         // still in the message queue, so keep the reference of {@link #mConnections} to make sure
         // the connection list is up-to-date.
         mIsDisconnecting = true;
-        mService.mH.post(() -> {
-            mService.mAmInternal.disconnectActivityFromServices(this);
+        mActivity.mAtmService.mH.post(() -> {
+            mActivity.mAtmService.mAmInternal.disconnectActivityFromServices(this);
             mIsDisconnecting = false;
         });
     }
 
     public void dump(PrintWriter pw, String prefix) {
-        synchronized (mService.mGlobalLock) {
-            pw.println(prefix + "activity=" + mActivity);
-        }
+        pw.println(prefix + "activity=" + mActivity);
     }
 
     /** Used by {@link ActivityRecord#dump}. */
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 8619615..491e58b 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1486,7 +1486,7 @@
         a.persistableMode = ActivityInfo.PERSIST_NEVER;
         a.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
         a.colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
-        a.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
+        a.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | ActivityInfo.FLAG_NO_HISTORY;
         a.resizeMode = RESIZE_MODE_UNRESIZEABLE;
         a.configChanges = 0xffffffff;
 
@@ -6000,18 +6000,11 @@
 
         @Override
         public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
-            synchronized (mGlobalLock) {
-                final ActivityRecord r = ActivityRecord.isInRootTaskLocked(token);
-                if (r == null) {
-                    return null;
-                }
-                if (r.mServiceConnectionsHolder == null) {
-                    r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
-                            ActivityTaskManagerService.this, r);
-                }
-
-                return r.mServiceConnectionsHolder;
+            final ActivityRecord r = ActivityRecord.forToken(token);
+            if (r == null || !r.inHistory) {
+                return null;
             }
+            return r.getOrCreateServiceConnectionsHolder();
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index b0eeceb..ec355b7 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -4505,24 +4505,8 @@
      */
     @VisibleForTesting
     SurfaceControl computeImeParent() {
-        if (mImeLayeringTarget != null) {
-            // Ensure changing the IME parent when the layering target that may use IME has
-            // became to the input target for preventing IME flickers.
-            // Note that:
-            // 1) For the imeLayeringTarget that may not use IME but requires IME on top
-            // of it (e.g. an overlay window with NOT_FOCUSABLE|ALT_FOCUSABLE_IM flags), we allow
-            // it to re-parent the IME on top the display to keep the legacy behavior.
-            // 2) Even though the starting window won't use IME, the associated activity
-            // behind the starting window may request the input. If so, then we should still hold
-            // the IME parent change until the activity started the input.
-            boolean imeLayeringTargetMayUseIme =
-                    LayoutParams.mayUseInputMethod(mImeLayeringTarget.mAttrs.flags)
-                    || mImeLayeringTarget.mAttrs.type == TYPE_APPLICATION_STARTING;
-            if (imeLayeringTargetMayUseIme && (mImeInputTarget == null
-                    || mImeLayeringTarget.mActivityRecord != mImeInputTarget.getActivityRecord())) {
-                // Do not change parent if the window hasn't requested IME.
-                return null;
-            }
+        if (!canComputeImeParent(mImeLayeringTarget, mImeInputTarget)) {
+            return null;
         }
         // Attach it to app if the target is part of an app and such app is covering the entire
         // screen. If it's not covering the entire screen the IME might extend beyond the apps
@@ -4535,6 +4519,76 @@
                 ? mImeWindowsContainer.getParent().getSurfaceControl() : null;
     }
 
+    private static boolean canComputeImeParent(@Nullable WindowState imeLayeringTarget,
+            @Nullable InputTarget imeInputTarget) {
+        if (imeLayeringTarget == null) {
+            return false;
+        }
+        if (shouldComputeImeParentForEmbeddedActivity(imeLayeringTarget, imeInputTarget)) {
+            return true;
+        }
+        // Ensure changing the IME parent when the layering target that may use IME has
+        // became to the input target for preventing IME flickers.
+        // Note that:
+        // 1) For the imeLayeringTarget that may not use IME but requires IME on top
+        // of it (e.g. an overlay window with NOT_FOCUSABLE|ALT_FOCUSABLE_IM flags), we allow
+        // it to re-parent the IME on top the display to keep the legacy behavior.
+        // 2) Even though the starting window won't use IME, the associated activity
+        // behind the starting window may request the input. If so, then we should still hold
+        // the IME parent change until the activity started the input.
+        boolean imeLayeringTargetMayUseIme =
+                LayoutParams.mayUseInputMethod(imeLayeringTarget.mAttrs.flags)
+                        || imeLayeringTarget.mAttrs.type == TYPE_APPLICATION_STARTING;
+
+        if (imeLayeringTargetMayUseIme && (imeInputTarget == null
+                || imeLayeringTarget.mActivityRecord != imeInputTarget.getActivityRecord())) {
+            // Do not change parent if the window hasn't requested IME.
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Called from {@link #computeImeParent()} to check the given IME targets if the IME surface
+     * parent should be updated in ActivityEmbeddings.
+     *
+     * As the IME layering target is calculated according to the window hierarchy by
+     * {@link #computeImeTarget}, the layering target and input target may be different when the
+     * window hasn't started input connection, WindowManagerService hasn't yet received the
+     * input target which reported from InputMethodManagerService. To make the IME surface will be
+     * shown on the best fit IME layering target, we basically won't update IME parent until both
+     * IME input and layering target updated for better IME transition.
+     *
+     * However, in activity embedding, tapping a window won't update it to the top window so the
+     * calculated IME layering target may higher than input target. Update IME parent for this case.
+     *
+     * @return {@code true} means the layer of IME layering target is higher than the input target
+     * and {@link #computeImeParent()} should keep progressing to update the IME
+     * surface parent on the display in case the IME surface left behind.
+     */
+    private static boolean shouldComputeImeParentForEmbeddedActivity(
+            @Nullable WindowState imeLayeringTarget, @Nullable InputTarget imeInputTarget) {
+        if (imeInputTarget == null || imeLayeringTarget == null) {
+            return false;
+        }
+        final WindowState inputTargetWindow = imeInputTarget.getWindowState();
+        if (inputTargetWindow == null || !imeLayeringTarget.isAttached()
+                || !inputTargetWindow.isAttached()) {
+            return false;
+        }
+
+        final ActivityRecord inputTargetRecord = imeInputTarget.getActivityRecord();
+        final ActivityRecord layeringTargetRecord = imeLayeringTarget.getActivityRecord();
+        if (inputTargetRecord == null || layeringTargetRecord == null
+                || inputTargetRecord == layeringTargetRecord
+                || inputTargetRecord.getTask() != layeringTargetRecord.getTask()
+                || !inputTargetRecord.isEmbedded() || !layeringTargetRecord.isEmbedded()) {
+            // Check whether the input target and layering target are embedded in the same Task.
+            return false;
+        }
+        return imeLayeringTarget.compareTo(inputTargetWindow) > 0;
+    }
+
     void setLayoutNeeded() {
         if (DEBUG_LAYOUT) Slog.w(TAG_WM, "setLayoutNeeded: callers=" + Debug.getCallers(3));
         mLayoutNeeded = true;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 8e9a214..4113081 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1577,9 +1577,8 @@
         applyKeyguardPolicy(win, imeTarget);
 
         // Check if the freeform window overlaps with the navigation bar area.
-        final boolean isOverlappingWithNavBar = isOverlappingWithNavBar(win);
-        if (isOverlappingWithNavBar && !mIsFreeformWindowOverlappingWithNavBar
-                && win.inFreeformWindowingMode()) {
+        if (!mIsFreeformWindowOverlappingWithNavBar && win.inFreeformWindowingMode()
+                && win.mActivityRecord != null && isOverlappingWithNavBar(win)) {
             mIsFreeformWindowOverlappingWithNavBar = true;
         }
 
@@ -1637,7 +1636,7 @@
             // mode; if it's in gesture navigation mode, the navigation bar will be
             // NAV_BAR_FORCE_TRANSPARENT and its appearance won't be decided by overlapping
             // windows.
-            if (isOverlappingWithNavBar) {
+            if (isOverlappingWithNavBar(win)) {
                 if (mNavBarColorWindowCandidate == null) {
                     mNavBarColorWindowCandidate = win;
                     addSystemBarColorApp(win);
@@ -1665,7 +1664,7 @@
                     addSystemBarColorApp(win);
                 }
             }
-            if (isOverlappingWithNavBar && mNavBarColorWindowCandidate == null) {
+            if (isOverlappingWithNavBar(win) && mNavBarColorWindowCandidate == null) {
                 mNavBarColorWindowCandidate = win;
             }
         }
@@ -2858,7 +2857,7 @@
 
     @VisibleForTesting
     static boolean isOverlappingWithNavBar(@NonNull WindowState win) {
-        if (win.mActivityRecord == null || !win.isVisible()) {
+        if (!win.isVisible()) {
             return false;
         }
 
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 48258a1..1d21b9d 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -403,8 +403,10 @@
             return;
         }
 
-        mWindowManager.mPolicy.onKeyguardOccludedChangedLw(isDisplayOccluded(DEFAULT_DISPLAY));
-        if (isKeyguardLocked(displayId)) {
+        final boolean waitAppTransition = isKeyguardLocked(displayId);
+        mWindowManager.mPolicy.onKeyguardOccludedChangedLw(isDisplayOccluded(DEFAULT_DISPLAY),
+                waitAppTransition);
+        if (waitAppTransition) {
             mService.deferWindowLayout();
             try {
                 mRootWindowContainer.getDefaultDisplay()
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
index 5136670..fa49a6ba 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -22,6 +22,7 @@
 import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ENABLE_CAMERA_COMPAT_TREATMENT;
 import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ENABLE_COMPAT_FAKE_FOCUS;
 import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY;
+import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -296,7 +297,6 @@
                 R.bool.config_isCompatFakeFocusEnabled);
         mIsPolicyForIgnoringRequestedOrientationEnabled = mContext.getResources().getBoolean(
                 R.bool.config_letterboxIsPolicyForIgnoringRequestedOrientationEnabled);
-
         mIsDisplayRotationImmersiveAppCompatPolicyEnabled = mContext.getResources().getBoolean(
                 R.bool.config_letterboxIsDisplayRotationImmersiveAppCompatPolicyEnabled);
         mDeviceConfig.updateFlagActiveStatus(
@@ -311,7 +311,9 @@
         mDeviceConfig.updateFlagActiveStatus(
                 /* isActive */ mIsCompatFakeFocusEnabled,
                 /* key */ KEY_ENABLE_COMPAT_FAKE_FOCUS);
-
+        mDeviceConfig.updateFlagActiveStatus(
+                /* isActive */ mTranslucentLetterboxingEnabled,
+                /* key */ KEY_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY);
         mLetterboxConfigurationPersister = letterboxConfigurationPersister;
         mLetterboxConfigurationPersister.start();
     }
@@ -1003,7 +1005,7 @@
 
     boolean isTranslucentLetterboxingEnabled() {
         return mTranslucentLetterboxingOverrideEnabled || (mTranslucentLetterboxingEnabled
-                && isTranslucentLetterboxingAllowed());
+                && mDeviceConfig.getFlag(KEY_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY));
     }
 
     void setTranslucentLetterboxingEnabled(boolean translucentLetterboxingEnabled) {
@@ -1051,13 +1053,6 @@
                 isDeviceInTabletopMode, nextVerticalPosition);
     }
 
-    // TODO(b/262378106): Cache a runtime flag and implement
-    // DeviceConfig.OnPropertiesChangedListener
-    static boolean isTranslucentLetterboxingAllowed() {
-        return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
-                "enable_translucent_activity_letterbox", false);
-    }
-
     /** Whether fake sending focus is enabled for unfocused apps in splitscreen */
     boolean isCompatFakeFocusEnabled() {
         return mIsCompatFakeFocusEnabled && mDeviceConfig.getFlag(KEY_ENABLE_COMPAT_FAKE_FOCUS);
diff --git a/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java b/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java
index b364872..df3c8f0 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java
@@ -48,6 +48,11 @@
     static final String KEY_ENABLE_COMPAT_FAKE_FOCUS = "enable_compat_fake_focus";
     private static final boolean DEFAULT_VALUE_ENABLE_COMPAT_FAKE_FOCUS = true;
 
+    static final String KEY_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY =
+            "enable_letterbox_translucent_activity";
+
+    private static final boolean DEFAULT_VALUE_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY = true;
+
     @VisibleForTesting
     static final Map<String, Boolean> sKeyToDefaultValueMap = Map.of(
             KEY_ENABLE_CAMERA_COMPAT_TREATMENT,
@@ -57,7 +62,9 @@
             KEY_ALLOW_IGNORE_ORIENTATION_REQUEST,
             DEFAULT_VALUE_ALLOW_IGNORE_ORIENTATION_REQUEST,
             KEY_ENABLE_COMPAT_FAKE_FOCUS,
-            DEFAULT_VALUE_ENABLE_COMPAT_FAKE_FOCUS
+            DEFAULT_VALUE_ENABLE_COMPAT_FAKE_FOCUS,
+            KEY_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY,
+            DEFAULT_VALUE_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY
     );
 
     // Whether camera compatibility treatment is enabled.
@@ -82,6 +89,10 @@
     // which isn't guaranteed by default in multi-window modes.
     private boolean mIsCompatFakeFocusAllowed = DEFAULT_VALUE_ENABLE_COMPAT_FAKE_FOCUS;
 
+    // Whether the letterbox strategy for transparent activities is allowed
+    private boolean mIsTranslucentLetterboxingAllowed =
+            DEFAULT_VALUE_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY;
+
     // Set of active device configs that need to be updated in
     // DeviceConfig.OnPropertiesChangedListener#onPropertiesChanged.
     private final ArraySet<String> mActiveDeviceConfigsSet = new ArraySet<>();
@@ -129,6 +140,8 @@
                 return mIsAllowIgnoreOrientationRequest;
             case KEY_ENABLE_COMPAT_FAKE_FOCUS:
                 return mIsCompatFakeFocusAllowed;
+            case KEY_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY:
+                return mIsTranslucentLetterboxingAllowed;
             default:
                 throw new AssertionError("Unexpected flag name: " + key);
         }
@@ -141,20 +154,20 @@
         }
         switch (key) {
             case KEY_ENABLE_CAMERA_COMPAT_TREATMENT:
-                mIsCameraCompatTreatmentEnabled =
-                        getDeviceConfig(key, defaultValue);
+                mIsCameraCompatTreatmentEnabled = getDeviceConfig(key, defaultValue);
                 break;
             case KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY:
                 mIsDisplayRotationImmersiveAppCompatPolicyEnabled =
                         getDeviceConfig(key, defaultValue);
                 break;
             case KEY_ALLOW_IGNORE_ORIENTATION_REQUEST:
-                mIsAllowIgnoreOrientationRequest =
-                        getDeviceConfig(key, defaultValue);
+                mIsAllowIgnoreOrientationRequest = getDeviceConfig(key, defaultValue);
                 break;
             case KEY_ENABLE_COMPAT_FAKE_FOCUS:
-                mIsCompatFakeFocusAllowed =
-                        getDeviceConfig(key, defaultValue);
+                mIsCompatFakeFocusAllowed = getDeviceConfig(key, defaultValue);
+                break;
+            case KEY_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY:
+                mIsTranslucentLetterboxingAllowed = getDeviceConfig(key, defaultValue);
                 break;
             default:
                 throw new AssertionError("Unexpected flag name: " + key);
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index 5a481f4..e1dbe01a 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -193,12 +193,6 @@
     // The app compat state for the opaque activity if any
     private int mInheritedAppCompatState = APP_COMPAT_STATE_CHANGED__STATE__UNKNOWN;
 
-    // If true it means that the opaque activity beneath a translucent one is in SizeCompatMode.
-    private boolean mIsInheritedInSizeCompatMode;
-
-    // This is the SizeCompatScale of the opaque activity beneath a translucent one
-    private float mInheritedSizeCompatScale;
-
     // The CompatDisplayInsets of the opaque activity beneath the translucent one.
     private ActivityRecord.CompatDisplayInsets mInheritedCompatDisplayInsets;
 
@@ -735,8 +729,21 @@
                     : mActivityRecord.inMultiWindowMode()
                             ? mActivityRecord.getTask().getBounds()
                             : mActivityRecord.getRootTask().getParent().getBounds();
+            // In case of translucent activities an option is to use the WindowState#getFrame() of
+            // the first opaque activity beneath. In some cases (e.g. an opaque activity is using
+            // non MATCH_PARENT layouts or a Dialog theme) this might not provide the correct
+            // information and in particular it might provide a value for a smaller area making
+            // the letterbox overlap with the translucent activity's frame.
+            // If we use WindowState#getFrame() for the translucent activity's letterbox inner
+            // frame, the letterbox will then be overlapped with the translucent activity's frame.
+            // Because the surface layer of letterbox is lower than an activity window, this
+            // won't crop the content, but it may affect other features that rely on values stored
+            // in mLetterbox, e.g. transitions, a status bar scrim and recents preview in Launcher
+            // For this reason we use ActivityRecord#getBounds() that the translucent activity
+            // inherits from the first opaque activity beneath and also takes care of the scaling
+            // in case of activities in size compat mode.
             final Rect innerFrame = hasInheritedLetterboxBehavior()
-                    ? mActivityRecord.getWindowConfiguration().getBounds() : w.getFrame();
+                    ? mActivityRecord.getBounds() : w.getFrame();
             mLetterbox.layout(spaceToFill, innerFrame, mTmpPoint);
         } else if (mLetterbox != null) {
             mLetterbox.hide();
@@ -962,8 +969,8 @@
                 && (parentConfiguration.orientation == ORIENTATION_LANDSCAPE
                         && mActivityRecord.getOrientationForReachability() == ORIENTATION_PORTRAIT)
                 // Check whether the activity fills the parent vertically.
-                && parentConfiguration.windowConfiguration.getBounds().height()
-                        == mActivityRecord.getBounds().height();
+                && parentConfiguration.windowConfiguration.getAppBounds().height()
+                        <= mActivityRecord.getBounds().height();
     }
 
     @VisibleForTesting
@@ -1386,10 +1393,10 @@
             mLetterboxConfigListener.onRemoved();
             clearInheritedConfig();
         }
-        // In case mActivityRecord.getCompatDisplayInsets() is not null we don't apply the
+        // In case mActivityRecord.hasCompatDisplayInsetsWithoutOverride() we don't apply the
         // opaque activity constraints because we're expecting the activity is already letterboxed.
-        if (mActivityRecord.getTask() == null || mActivityRecord.getCompatDisplayInsets() != null
-                || mActivityRecord.fillsParent()) {
+        if (mActivityRecord.getTask() == null || mActivityRecord.fillsParent()
+                || mActivityRecord.hasCompatDisplayInsetsWithoutInheritance()) {
             return;
         }
         final ActivityRecord firstOpaqueActivityBeneath = mActivityRecord.getTask().getActivity(
@@ -1417,6 +1424,7 @@
                     // We need to initialize appBounds to avoid NPE. The actual value will
                     // be set ahead when resolving the Configuration for the activity.
                     mutatedConfiguration.windowConfiguration.setAppBounds(new Rect());
+                    inheritConfiguration(firstOpaqueActivityBeneath);
                     return mutatedConfiguration;
                 });
     }
@@ -1457,16 +1465,12 @@
         return mInheritedAppCompatState;
     }
 
-    float getInheritedSizeCompatScale() {
-        return mInheritedSizeCompatScale;
-    }
-
     @Configuration.Orientation
     int getInheritedOrientation() {
         return mInheritedOrientation;
     }
 
-    public ActivityRecord.CompatDisplayInsets getInheritedCompatDisplayInsets() {
+    ActivityRecord.CompatDisplayInsets getInheritedCompatDisplayInsets() {
         return mInheritedCompatDisplayInsets;
     }
 
@@ -1486,7 +1490,7 @@
      * @return The first not finishing opaque activity beneath the current translucent activity
      * if it exists and the strategy is enabled.
      */
-    private Optional<ActivityRecord> findOpaqueNotFinishingActivityBelow() {
+    Optional<ActivityRecord> findOpaqueNotFinishingActivityBelow() {
         if (!hasInheritedLetterboxBehavior() || mActivityRecord.getTask() == null) {
             return Optional.empty();
         }
@@ -1508,8 +1512,6 @@
         }
         mInheritedOrientation = firstOpaque.getRequestedConfigurationOrientation();
         mInheritedAppCompatState = firstOpaque.getAppCompatState();
-        mIsInheritedInSizeCompatMode = firstOpaque.inSizeCompatMode();
-        mInheritedSizeCompatScale = firstOpaque.getCompatScale();
         mInheritedCompatDisplayInsets = firstOpaque.getCompatDisplayInsets();
     }
 
@@ -1519,8 +1521,6 @@
         mInheritedMaxAspectRatio = UNDEFINED_ASPECT_RATIO;
         mInheritedOrientation = Configuration.ORIENTATION_UNDEFINED;
         mInheritedAppCompatState = APP_COMPAT_STATE_CHANGED__STATE__UNKNOWN;
-        mIsInheritedInSizeCompatMode = false;
-        mInheritedSizeCompatScale = 1f;
         mInheritedCompatDisplayInsets = null;
     }
 }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 3aa80c4..adaaa25 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -3455,6 +3455,11 @@
                 && top.getOrganizedTask() == this && top.isState(RESUMED);
         // Whether the direct top activity is in size compat mode on foreground.
         info.topActivityInSizeCompat = isTopActivityResumed && top.inSizeCompatMode();
+        if (info.topActivityInSizeCompat
+                && mWmService.mLetterboxConfiguration.isTranslucentLetterboxingEnabled()) {
+            // We hide the restart button in case of transparent activities.
+            info.topActivityInSizeCompat = top.fillsParent();
+        }
         // Whether the direct top activity is eligible for letterbox education.
         info.topActivityEligibleForLetterboxEducation = isTopActivityResumed
                 && top.isEligibleForLetterboxEducation();
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 22da56a..19e45ff 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1953,7 +1953,7 @@
                         1f);
                 mBackScreenshots.put(r.mActivityComponent.flattenToString(), backBuffer);
             }
-            child.asActivityRecord().inHistory = true;
+            addingActivity.inHistory = true;
             task.onDescendantActivityAdded(taskHadActivity, activityType, addingActivity);
         }
     }
diff --git a/services/people/java/com/android/server/people/data/DataManager.java b/services/people/java/com/android/server/people/data/DataManager.java
index eff9e8d..37f0624 100644
--- a/services/people/java/com/android/server/people/data/DataManager.java
+++ b/services/people/java/com/android/server/people/data/DataManager.java
@@ -113,6 +113,7 @@
     private static final long USAGE_STATS_QUERY_INTERVAL_SEC = 120L;
     @VisibleForTesting
     static final int MAX_CACHED_RECENT_SHORTCUTS = 30;
+    private static final int DEBOUNCE_LENGTH_MS = 500;
 
     private final Context mContext;
     private final Injector mInjector;
@@ -129,6 +130,7 @@
     private final List<PeopleService.ConversationsListener> mConversationsListeners =
             new ArrayList<>(1);
     private final Handler mHandler;
+    private final PerPackageThrottler mShortcutsThrottler;
 
     private ContentObserver mCallLogContentObserver;
     private ContentObserver mMmsSmsContentObserver;
@@ -140,14 +142,17 @@
     private ConversationStatusExpirationBroadcastReceiver mStatusExpReceiver;
 
     public DataManager(Context context) {
-        this(context, new Injector(), BackgroundThread.get().getLooper());
+        this(context, new Injector(), BackgroundThread.get().getLooper(),
+                new PerPackageThrottlerImpl(BackgroundThread.getHandler(), DEBOUNCE_LENGTH_MS));
     }
 
-    DataManager(Context context, Injector injector, Looper looper) {
+    DataManager(Context context, Injector injector, Looper looper,
+            PerPackageThrottler shortcutsThrottler) {
         mContext = context;
         mInjector = injector;
         mScheduledExecutor = mInjector.createScheduledExecutor();
         mHandler = new Handler(looper);
+        mShortcutsThrottler = shortcutsThrottler;
     }
 
     /** Initialization. Called when the system services are up running. */
@@ -851,12 +856,12 @@
         // pair of <package name, conversation info>
         List<Pair<String, ConversationInfo>> cachedConvos = new ArrayList<>();
         userData.forAllPackages(packageData -> {
-                packageData.forAllConversations(conversationInfo -> {
-                    if (isEligibleForCleanUp(conversationInfo)) {
-                        cachedConvos.add(
-                                Pair.create(packageData.getPackageName(), conversationInfo));
-                    }
-                });
+            packageData.forAllConversations(conversationInfo -> {
+                if (isEligibleForCleanUp(conversationInfo)) {
+                    cachedConvos.add(
+                            Pair.create(packageData.getPackageName(), conversationInfo));
+                }
+            });
         });
         if (cachedConvos.size() <= targetCachedCount) {
             return;
@@ -867,8 +872,8 @@
                 numToUncache + 1,
                 Comparator.comparingLong((Pair<String, ConversationInfo> pair) ->
                         Math.max(
-                            pair.second.getLastEventTimestamp(),
-                            pair.second.getCreationTimestamp())).reversed());
+                                pair.second.getLastEventTimestamp(),
+                                pair.second.getCreationTimestamp())).reversed());
         for (Pair<String, ConversationInfo> cached : cachedConvos) {
             if (hasActiveNotifications(cached.first, userId, cached.second.getShortcutId())) {
                 continue;
@@ -1104,26 +1109,35 @@
         @Override
         public void onShortcutsAddedOrUpdated(@NonNull String packageName,
                 @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) {
-            mInjector.getBackgroundExecutor().execute(() -> {
-                PackageData packageData = getPackage(packageName, user.getIdentifier());
-                for (ShortcutInfo shortcut : shortcuts) {
-                    if (ShortcutHelper.isConversationShortcut(
-                            shortcut, mShortcutServiceInternal, user.getIdentifier())) {
-                        if (shortcut.isCached()) {
-                            ConversationInfo conversationInfo = packageData != null
-                                    ? packageData.getConversationInfo(shortcut.getId()) : null;
-                            if (conversationInfo == null
-                                    || !conversationInfo.isShortcutCachedForNotification()) {
-                                // This is a newly cached shortcut. Clean up the existing cached
-                                // shortcuts to ensure the cache size is under the limit.
-                                cleanupCachedShortcuts(user.getIdentifier(),
-                                        MAX_CACHED_RECENT_SHORTCUTS - 1);
+            mShortcutsThrottler.scheduleDebounced(
+                    new Pair<>(packageName, user.getIdentifier()),
+                    () -> {
+                        PackageData packageData = getPackage(packageName, user.getIdentifier());
+                        List<ShortcutInfo> queriedShortcuts = getShortcuts(packageName,
+                                user.getIdentifier(), null);
+                        boolean hasCachedShortcut = false;
+                        for (ShortcutInfo shortcut : queriedShortcuts) {
+                            if (ShortcutHelper.isConversationShortcut(
+                                    shortcut, mShortcutServiceInternal, user.getIdentifier())) {
+                                if (shortcut.isCached()) {
+                                    ConversationInfo info = packageData != null
+                                            ? packageData.getConversationInfo(shortcut.getId())
+                                            : null;
+                                    if (info == null
+                                            || !info.isShortcutCachedForNotification()) {
+                                        hasCachedShortcut = true;
+                                    }
+                                }
+                                addOrUpdateConversationInfo(shortcut);
                             }
                         }
-                        addOrUpdateConversationInfo(shortcut);
-                    }
-                }
-            });
+                        // Added at least one new conversation. Uncache older existing cached
+                        // shortcuts to ensure the cache size is under the limit.
+                        if (hasCachedShortcut) {
+                            cleanupCachedShortcuts(user.getIdentifier(),
+                                    MAX_CACHED_RECENT_SHORTCUTS);
+                        }
+                    });
         }
 
         @Override
diff --git a/services/people/java/com/android/server/people/data/PerPackageThrottler.java b/services/people/java/com/android/server/people/data/PerPackageThrottler.java
new file mode 100644
index 0000000..3d6cd84
--- /dev/null
+++ b/services/people/java/com/android/server/people/data/PerPackageThrottler.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.people.data;
+
+import android.util.Pair;
+
+/** The interface for throttling expensive runnables per package. */
+interface PerPackageThrottler {
+    /**
+     * Schedule a runnable to run in the future, and debounce runnables for same {@code pkgUserId}
+     * that occur until that future has run.
+     */
+    void scheduleDebounced(Pair<String, Integer> pkgUserId, Runnable runnable);
+}
diff --git a/services/people/java/com/android/server/people/data/PerPackageThrottlerImpl.java b/services/people/java/com/android/server/people/data/PerPackageThrottlerImpl.java
new file mode 100644
index 0000000..fa5a67b
--- /dev/null
+++ b/services/people/java/com/android/server/people/data/PerPackageThrottlerImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.people.data;
+
+import android.os.Handler;
+import android.util.Pair;
+
+import java.util.HashSet;
+
+/**
+ * A class that implements a per-package throttler that prevents a runnable from executing more than
+ * once every {@code debounceTime}.
+ */
+public class PerPackageThrottlerImpl implements PerPackageThrottler {
+    private final Handler mBackgroundHandler;
+    private final int mDebounceTime;
+    private final HashSet<Pair<String, Integer>> mPkgScheduledTasks = new HashSet<>();
+
+    PerPackageThrottlerImpl(Handler backgroundHandler, int debounceTime) {
+        mBackgroundHandler = backgroundHandler;
+        mDebounceTime = debounceTime;
+    }
+
+    @Override
+    public synchronized void scheduleDebounced(
+            Pair<String, Integer> pkgUserId, Runnable runnable) {
+        if (mPkgScheduledTasks.contains(pkgUserId)) {
+            return;
+        }
+        mPkgScheduledTasks.add(pkgUserId);
+        mBackgroundHandler.postDelayed(() -> {
+            synchronized (this) {
+                mPkgScheduledTasks.remove(pkgUserId);
+                runnable.run();
+            }
+        }, mDebounceTime);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStatePolicyProviderTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStatePolicyProviderTest.java
index 0bd81b7..18dc35c 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStatePolicyProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStatePolicyProviderTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.devicestate;
 
+import static org.hamcrest.Matchers.instanceOf;
+import static org.junit.Assert.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertThrows;
@@ -24,8 +26,6 @@
 import android.content.res.Resources;
 import android.platform.test.annotations.Presubmit;
 
-import org.hamcrest.Matchers;
-import org.junit.Assert;
 import org.junit.Test;
 
 /**
@@ -39,37 +39,35 @@
 
     @Test
     public void test_emptyPolicyProvider() {
-        Assert.assertThat(DeviceStatePolicy.Provider.fromResources(resourcesWithProvider("")),
-                Matchers.instanceOf(DeviceStatePolicy.DefaultProvider.class));
+        assertThat(DeviceStatePolicy.Provider.fromResources(resourcesWithProvider("")),
+                instanceOf(DeviceStatePolicy.DefaultProvider.class));
     }
 
     @Test
     public void test_nullPolicyProvider() {
-        Assert.assertThat(DeviceStatePolicy.Provider.fromResources(resourcesWithProvider(null)),
-                Matchers.instanceOf(DeviceStatePolicy.DefaultProvider.class));
+        assertThat(DeviceStatePolicy.Provider.fromResources(resourcesWithProvider(null)),
+                instanceOf(DeviceStatePolicy.DefaultProvider.class));
     }
 
     @Test
     public void test_customPolicyProvider() {
-        Assert.assertThat(DeviceStatePolicy.Provider.fromResources(resourcesWithProvider(
-                TestProvider.class.getName())),
-                Matchers.instanceOf(TestProvider.class));
+        assertThat(DeviceStatePolicy.Provider.fromResources(resourcesWithProvider(
+                        TestProvider.class.getName())),
+                instanceOf(TestProvider.class));
     }
 
     @Test
     public void test_badPolicyProvider_notImplementingProviderInterface() {
-        assertThrows(IllegalStateException.class, () -> {
-            DeviceStatePolicy.Provider.fromResources(resourcesWithProvider(
-                    Object.class.getName()));
-        });
+        assertThrows(IllegalStateException.class, () ->
+                DeviceStatePolicy.Provider.fromResources(resourcesWithProvider(
+                        Object.class.getName())));
     }
 
     @Test
-    public void test_badPolicyProvider_doesntExist() {
-        assertThrows(IllegalStateException.class, () -> {
-            DeviceStatePolicy.Provider.fromResources(resourcesWithProvider(
-                    "com.android.devicestate.nonexistent.policy"));
-        });
+    public void test_badPolicyProvider_returnsDefault() {
+        assertThat(DeviceStatePolicy.Provider.fromResources(
+                        resourcesWithProvider("com.android.devicestate.nonexistent.policy")),
+                instanceOf(DeviceStatePolicy.DefaultProvider.class));
     }
 
     private static Resources resourcesWithProvider(String provider) {
diff --git a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
index a27602d..454a23b 100644
--- a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
@@ -86,6 +86,7 @@
 import android.telecom.TelecomManager;
 import android.telephony.TelephonyManager;
 import android.text.format.DateUtils;
+import android.util.Pair;
 import android.util.Range;
 
 import com.android.internal.app.ChooserActivity;
@@ -186,6 +187,7 @@
     private ShortcutInfo mShortcutInfo;
     private TestInjector mInjector;
     private TestLooper mLooper;
+    private TestPerPackageThrottler mShortcutThrottler;
 
     @Before
     public void setUp() throws PackageManager.NameNotFoundException {
@@ -275,7 +277,9 @@
 
         mInjector = new TestInjector();
         mLooper = new TestLooper();
-        mDataManager = new DataManager(mContext, mInjector, mLooper.getLooper());
+        mShortcutThrottler = new TestPerPackageThrottler();
+        mDataManager = new DataManager(mContext, mInjector, mLooper.getLooper(),
+                mShortcutThrottler);
         mDataManager.initialize();
 
         when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
@@ -283,10 +287,7 @@
 
         mShortcutInfo = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
                 buildPerson());
-        when(mShortcutServiceInternal.getShortcuts(
-                anyInt(), anyString(), anyLong(), anyString(), anyList(), any(), any(),
-                anyInt(), anyInt(), anyInt(), anyInt()))
-                .thenReturn(Collections.singletonList(mShortcutInfo));
+        mockGetShortcuts(Collections.singletonList(mShortcutInfo));
         verify(mShortcutServiceInternal).addShortcutChangeCallback(
                 mShortcutChangeCallbackCaptor.capture());
         mShortcutChangeCallback = mShortcutChangeCallbackCaptor.getValue();
@@ -972,6 +973,7 @@
                 buildPerson());
         ShortcutInfo shortcut3 = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, "sc3",
                 buildPerson());
+        mockGetShortcuts(List.of(shortcut1, shortcut2, shortcut3));
         mShortcutChangeCallback.onShortcutsAddedOrUpdated(TEST_PKG_NAME,
                 Arrays.asList(shortcut1, shortcut2, shortcut3), UserHandle.of(USER_ID_PRIMARY));
         mShortcutChangeCallback.onShortcutsRemoved(TEST_PKG_NAME,
@@ -1223,7 +1225,6 @@
                     eq(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS));
         }
     }
-
     @Test
     public void testUncacheOldestCachedShortcut_missingNotificationEvents() {
         mDataManager.onUserUnlocked(USER_ID_PRIMARY);
@@ -1233,6 +1234,7 @@
             ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, shortcutId,
                     buildPerson());
             shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS);
+            mockGetShortcuts(Collections.singletonList(shortcut));
             mShortcutChangeCallback.onShortcutsAddedOrUpdated(
                     TEST_PKG_NAME,
                     Collections.singletonList(shortcut),
@@ -1252,7 +1254,6 @@
                     eq(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS));
         }
     }
-
     @Test
     public void testUncacheOldestCachedShortcut_legacyConversation() {
         mDataManager.onUserUnlocked(USER_ID_PRIMARY);
@@ -1274,6 +1275,7 @@
             ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, shortcutId,
                     buildPerson());
             shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS);
+            mockGetShortcuts(Collections.singletonList(shortcut));
             mShortcutChangeCallback.onShortcutsAddedOrUpdated(
                     TEST_PKG_NAME,
                     Collections.singletonList(shortcut),
@@ -1311,7 +1313,8 @@
         mDataManager.reportShareTargetEvent(appTargetEvent, intentFilter);
         byte[] payload = mDataManager.getBackupPayload(USER_ID_PRIMARY);
 
-        DataManager dataManager = new DataManager(mContext, mInjector, mLooper.getLooper());
+        DataManager dataManager = new DataManager(
+                mContext, mInjector, mLooper.getLooper(), mShortcutThrottler);
         dataManager.onUserUnlocked(USER_ID_PRIMARY);
         dataManager.restore(USER_ID_PRIMARY, payload);
         ConversationInfo conversationInfo = dataManager.getPackage(TEST_PKG_NAME, USER_ID_PRIMARY)
@@ -1723,6 +1726,13 @@
         return (queryFlags & flag) != 0;
     }
 
+    private void mockGetShortcuts(List<ShortcutInfo> shortcutInfoList) {
+        when(mShortcutServiceInternal.getShortcuts(
+                anyInt(), anyString(), anyLong(), anyString(), any(), any(), any(),
+                anyInt(), anyInt(), anyInt(), anyInt()))
+                .thenReturn(shortcutInfoList);
+    }
+
     // "Sends" a notification to a non-customized notification channel - the notification channel
     // is something generic like "messages" and the notification has a  shortcut id
     private void sendGenericNotification() {
@@ -1948,4 +1958,11 @@
             return mUsageStatsQueryHelper;
         }
     }
+
+    private static class TestPerPackageThrottler implements PerPackageThrottler {
+        @Override
+        public void scheduleDebounced(Pair<String, Integer> pkgUserId, Runnable runnable) {
+            runnable.run();
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/people/data/PerPackageThrottlerImplTest.java b/services/tests/servicestests/src/com/android/server/people/data/PerPackageThrottlerImplTest.java
new file mode 100644
index 0000000..672cbb9
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/people/data/PerPackageThrottlerImplTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.people.data;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.util.Pair;
+
+import com.android.server.testutils.OffsettableClock;
+import com.android.server.testutils.TestHandler;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+@RunWith(JUnit4.class)
+public class PerPackageThrottlerImplTest {
+    private static final int DEBOUNCE_INTERVAL = 500;
+    private static final String PKG_ONE = "pkg_one";
+    private static final String PKG_TWO = "pkg_two";
+    private static final int USER_ID = 10;
+
+    private final OffsettableClock mClock = new OffsettableClock.Stopped();
+    private final TestHandler mTestHandler = new TestHandler(null, mClock);
+    private PerPackageThrottlerImpl mThrottler;
+
+    @Before
+    public void setUp() {
+        mThrottler = new PerPackageThrottlerImpl(mTestHandler, DEBOUNCE_INTERVAL);
+    }
+
+    @Test
+    public void scheduleDebounced() {
+        AtomicBoolean pkgOneRan = new AtomicBoolean();
+        AtomicBoolean pkgTwoRan = new AtomicBoolean();
+
+        mThrottler.scheduleDebounced(new Pair<>(PKG_ONE, USER_ID), () -> pkgOneRan.set(true));
+        mThrottler.scheduleDebounced(new Pair<>(PKG_ONE, USER_ID), () -> pkgOneRan.set(true));
+        mThrottler.scheduleDebounced(new Pair<>(PKG_TWO, USER_ID), () -> pkgTwoRan.set(true));
+        mThrottler.scheduleDebounced(new Pair<>(PKG_TWO, USER_ID), () -> pkgTwoRan.set(true));
+
+        assertFalse(pkgOneRan.get());
+        assertFalse(pkgTwoRan.get());
+        mClock.fastForward(DEBOUNCE_INTERVAL);
+        mTestHandler.timeAdvance();
+        assertTrue(pkgOneRan.get());
+        assertTrue(pkgTwoRan.get());
+    }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
index 949455a1..b2754d2 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
@@ -32,22 +32,24 @@
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeConfig.EventInfo;
 import android.service.notification.ZenPolicy;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.TypedXmlPullParser;
 import android.util.TypedXmlSerializer;
 import android.util.Xml;
 
+import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.UiServiceTestCase;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -189,8 +191,6 @@
 
     @Test
     public void testRuleXml() throws Exception {
-        String tag = "tag";
-
         ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
         rule.configurationActivity = new ComponentName("a", "a");
         rule.component = new ComponentName("b", "b");
@@ -205,20 +205,11 @@
         rule.snoozing = true;
         rule.pkg = "b";
 
-        TypedXmlSerializer out = Xml.newFastSerializer();
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        out.setOutput(new BufferedOutputStream(baos), "utf-8");
-        out.startDocument(null, true);
-        out.startTag(null, tag);
-        ZenModeConfig.writeRuleXml(rule, out);
-        out.endTag(null, tag);
-        out.endDocument();
+        writeRuleXml(rule, baos);
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ZenModeConfig.ZenRule fromXml = readRuleXml(bais);
 
-        TypedXmlPullParser parser = Xml.newFastPullParser();
-        parser.setInput(new BufferedInputStream(
-                new ByteArrayInputStream(baos.toByteArray())), null);
-        parser.nextTag();
-        ZenModeConfig.ZenRule fromXml = ZenModeConfig.readRuleXml(parser);
         assertEquals("b", fromXml.pkg);
         // always resets on reboot
         assertFalse(fromXml.snoozing);
@@ -237,75 +228,41 @@
 
     @Test
     public void testRuleXml_pkg_component() throws Exception {
-        String tag = "tag";
-
         ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
         rule.configurationActivity = new ComponentName("a", "a");
         rule.component = new ComponentName("b", "b");
 
-        TypedXmlSerializer out = Xml.newFastSerializer();
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        out.setOutput(new BufferedOutputStream(baos), "utf-8");
-        out.startDocument(null, true);
-        out.startTag(null, tag);
-        ZenModeConfig.writeRuleXml(rule, out);
-        out.endTag(null, tag);
-        out.endDocument();
+        writeRuleXml(rule, baos);
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ZenModeConfig.ZenRule fromXml = readRuleXml(bais);
 
-        TypedXmlPullParser parser = Xml.newFastPullParser();
-        parser.setInput(new BufferedInputStream(
-                new ByteArrayInputStream(baos.toByteArray())), null);
-        parser.nextTag();
-        ZenModeConfig.ZenRule fromXml = ZenModeConfig.readRuleXml(parser);
         assertEquals("b", fromXml.pkg);
     }
 
     @Test
     public void testRuleXml_pkg_configActivity() throws Exception {
-        String tag = "tag";
-
         ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
         rule.configurationActivity = new ComponentName("a", "a");
 
-        TypedXmlSerializer out = Xml.newFastSerializer();
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        out.setOutput(new BufferedOutputStream(baos), "utf-8");
-        out.startDocument(null, true);
-        out.startTag(null, tag);
-        ZenModeConfig.writeRuleXml(rule, out);
-        out.endTag(null, tag);
-        out.endDocument();
+        writeRuleXml(rule, baos);
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ZenModeConfig.ZenRule fromXml = readRuleXml(bais);
 
-        TypedXmlPullParser parser = Xml.newFastPullParser();
-        parser.setInput(new BufferedInputStream(
-                new ByteArrayInputStream(baos.toByteArray())), null);
-        parser.nextTag();
-        ZenModeConfig.ZenRule fromXml = ZenModeConfig.readRuleXml(parser);
         assertNull(fromXml.pkg);
     }
 
     @Test
     public void testRuleXml_getPkg_nullPkg() throws Exception {
-        String tag = "tag";
-
         ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
         rule.enabled = true;
         rule.configurationActivity = new ComponentName("a", "a");
 
-        TypedXmlSerializer out = Xml.newFastSerializer();
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        out.setOutput(new BufferedOutputStream(baos), "utf-8");
-        out.startDocument(null, true);
-        out.startTag(null, tag);
-        ZenModeConfig.writeRuleXml(rule, out);
-        out.endTag(null, tag);
-        out.endDocument();
-
-        TypedXmlPullParser parser = Xml.newFastPullParser();
-        parser.setInput(new BufferedInputStream(
-                new ByteArrayInputStream(baos.toByteArray())), null);
-        parser.nextTag();
-        ZenModeConfig.ZenRule fromXml = ZenModeConfig.readRuleXml(parser);
+        writeRuleXml(rule, baos);
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ZenModeConfig.ZenRule fromXml = readRuleXml(bais);
         assertEquals("a", fromXml.getPkg());
 
         fromXml.condition = new Condition(Uri.EMPTY, "", Condition.STATE_TRUE);
@@ -313,25 +270,26 @@
     }
 
     @Test
-    public void testZenPolicyXml_allUnset() throws Exception {
-        String tag = "tag";
+    public void testRuleXml_emptyConditionId() throws Exception {
+        ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
+        rule.conditionId = Uri.EMPTY;
 
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        writeRuleXml(rule, baos);
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ZenModeConfig.ZenRule fromXml = readRuleXml(bais);
+
+        assertEquals(rule.condition, fromXml.condition);
+    }
+
+    @Test
+    public void testZenPolicyXml_allUnset() throws Exception {
         ZenPolicy policy = new ZenPolicy.Builder().build();
 
-        TypedXmlSerializer out = Xml.newFastSerializer();
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        out.setOutput(new BufferedOutputStream(baos), "utf-8");
-        out.startDocument(null, true);
-        out.startTag(null, tag);
-        ZenModeConfig.writeZenPolicyXml(policy, out);
-        out.endTag(null, tag);
-        out.endDocument();
-
-        TypedXmlPullParser parser = Xml.newFastPullParser();
-        parser.setInput(new BufferedInputStream(
-                new ByteArrayInputStream(baos.toByteArray())), null);
-        parser.nextTag();
-        ZenPolicy fromXml = ZenModeConfig.readZenPolicyXml(parser);
+        writePolicyXml(policy, baos);
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ZenPolicy fromXml = readPolicyXml(bais);
 
         // nothing was set, so we should have nothing from the parser
         assertNull(fromXml);
@@ -339,8 +297,6 @@
 
     @Test
     public void testZenPolicyXml() throws Exception {
-        String tag = "tag";
-
         ZenPolicy policy = new ZenPolicy.Builder()
                 .allowCalls(ZenPolicy.PEOPLE_TYPE_CONTACTS)
                 .allowMessages(ZenPolicy.PEOPLE_TYPE_NONE)
@@ -355,20 +311,10 @@
                 .showVisualEffect(ZenPolicy.VISUAL_EFFECT_AMBIENT, true)
                 .build();
 
-        TypedXmlSerializer out = Xml.newFastSerializer();
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        out.setOutput(new BufferedOutputStream(baos), "utf-8");
-        out.startDocument(null, true);
-        out.startTag(null, tag);
-        ZenModeConfig.writeZenPolicyXml(policy, out);
-        out.endTag(null, tag);
-        out.endDocument();
-
-        TypedXmlPullParser parser = Xml.newFastPullParser();
-        parser.setInput(new BufferedInputStream(
-                new ByteArrayInputStream(baos.toByteArray())), null);
-        parser.nextTag();
-        ZenPolicy fromXml = ZenModeConfig.readZenPolicyXml(parser);
+        writePolicyXml(policy, baos);
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ZenPolicy fromXml = readPolicyXml(bais);
 
         assertNotNull(fromXml);
         assertEquals(policy.getPriorityCategoryCalls(), fromXml.getPriorityCategoryCalls());
@@ -457,4 +403,45 @@
         config.suppressedVisualEffects = 0;
         return config;
     }
+
+    private void writeRuleXml(ZenModeConfig.ZenRule rule, ByteArrayOutputStream os)
+            throws IOException {
+        String tag = "tag";
+
+        TypedXmlSerializer out = Xml.newFastSerializer();
+        out.setOutput(new BufferedOutputStream(os), "utf-8");
+        out.startDocument(null, true);
+        out.startTag(null, tag);
+        ZenModeConfig.writeRuleXml(rule, out);
+        out.endTag(null, tag);
+        out.endDocument();
+    }
+
+    private ZenModeConfig.ZenRule readRuleXml(ByteArrayInputStream is)
+            throws XmlPullParserException, IOException {
+        TypedXmlPullParser parser = Xml.newFastPullParser();
+        parser.setInput(new BufferedInputStream(is), null);
+        parser.nextTag();
+        return ZenModeConfig.readRuleXml(parser);
+    }
+
+    private void writePolicyXml(ZenPolicy policy, ByteArrayOutputStream os) throws IOException {
+        String tag = "tag";
+
+        TypedXmlSerializer out = Xml.newFastSerializer();
+        out.setOutput(new BufferedOutputStream(os), "utf-8");
+        out.startDocument(null, true);
+        out.startTag(null, tag);
+        ZenModeConfig.writeZenPolicyXml(policy, out);
+        out.endTag(null, tag);
+        out.endDocument();
+    }
+
+    private ZenPolicy readPolicyXml(ByteArrayInputStream is)
+            throws XmlPullParserException, IOException {
+        TypedXmlPullParser parser = Xml.newFastPullParser();
+        parser.setInput(new BufferedInputStream(is), null);
+        parser.nextTag();
+        return ZenModeConfig.readZenPolicyXml(parser);
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index a017bd6..ea50179 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -2324,6 +2324,32 @@
     }
 
     @Test
+    public void testActivityServiceConnectionsHolder() {
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
+        final ActivityServiceConnectionsHolder<Object> holder =
+                mAtm.mInternal.getServiceConnectionsHolder(activity.token);
+        assertNotNull(holder);
+        final Object connection = new Object();
+        holder.addConnection(connection);
+        assertTrue(holder.isActivityVisible());
+        final int[] count = new int[1];
+        final Consumer<Object> c = conn -> count[0]++;
+        holder.forEachConnection(c);
+        assertEquals(1, count[0]);
+
+        holder.removeConnection(connection);
+        holder.forEachConnection(c);
+        assertEquals(1, count[0]);
+
+        activity.setVisibleRequested(false);
+        activity.setState(STOPPED, "test");
+        assertFalse(holder.isActivityVisible());
+
+        activity.removeImmediately();
+        assertNull(mAtm.mInternal.getServiceConnectionsHolder(activity.token));
+    }
+
+    @Test
     public void testTransferLaunchCookieWhenFinishing() {
         final ActivityRecord activity1 = createActivityWithTask();
         final Binder launchCookie = new Binder();
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 de84655..318fff2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -274,7 +274,8 @@
     public void testTranslucentActivitiesWhenUnfolding() {
         mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
         setUpDisplaySizeWithApp(2800, 1400);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(
+                true /* ignoreOrientationRequest */);
         mActivity.mWmService.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
                 1.0f /*letterboxVerticalPositionMultiplier*/);
         prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
@@ -285,18 +286,23 @@
                 .build();
         doReturn(false).when(translucentActivity).fillsParent();
         mTask.addChild(translucentActivity);
+        assertEquals(translucentActivity.getBounds(), mActivity.getBounds());
 
         mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
         spyOn(mActivity);
 
         // Halffold
-        setFoldablePosture(translucentActivity, true /* isHalfFolded */, false /* isTabletop */);
+        setFoldablePosture(translucentActivity, true /* isHalfFolded */,
+                false /* isTabletop */);
         verify(mActivity).recomputeConfiguration();
+        assertEquals(translucentActivity.getBounds(), mActivity.getBounds());
         clearInvocations(mActivity);
 
         // Unfold
-        setFoldablePosture(translucentActivity, false /* isHalfFolded */, false /* isTabletop */);
+        setFoldablePosture(translucentActivity, false /* isHalfFolded */,
+                false /* isTabletop */);
         verify(mActivity).recomputeConfiguration();
+        assertEquals(translucentActivity.getBounds(), mActivity.getBounds());
     }
 
     @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 c893255..132aa90 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -24,6 +24,7 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
@@ -603,4 +604,34 @@
         assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, tf1.getOrientation(SCREEN_ORIENTATION_UNSET));
         assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, task.getOrientation(SCREEN_ORIENTATION_UNSET));
     }
+
+    @Test
+    public void testUpdateImeParentForActivityEmbedding() {
+        // Setup two activities in ActivityEmbedding.
+        final Task task = createTask(mDisplayContent);
+        final TaskFragment tf0 = new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
+                .createActivityCount(1)
+                .setOrganizer(mOrganizer)
+                .setFragmentToken(new Binder())
+                .build();
+        final TaskFragment tf1 = new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
+                .createActivityCount(1)
+                .setOrganizer(mOrganizer)
+                .setFragmentToken(new Binder())
+                .build();
+        final ActivityRecord activity0 = tf0.getTopMostActivity();
+        final ActivityRecord activity1 = tf1.getTopMostActivity();
+        final WindowState win0 = createWindow(null, TYPE_BASE_APPLICATION, activity0, "win0");
+        final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity1, "win1");
+        doReturn(false).when(mDisplayContent).shouldImeAttachedToApp();
+
+        mDisplayContent.setImeInputTarget(win0);
+        mDisplayContent.setImeLayeringTarget(win1);
+
+        // The ImeParent should be the display.
+        assertEquals(mDisplayContent.getImeContainer().getParent().getSurfaceControl(),
+                mDisplayContent.computeImeParent());
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index d2cb7ba..e2db2e6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -222,7 +222,7 @@
     }
 
     @Override
-    public void onKeyguardOccludedChangedLw(boolean occluded) {
+    public void onKeyguardOccludedChangedLw(boolean occluded, boolean waitAppTransition) {
     }
 
     public void setSafeMode(boolean safeMode) {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 6ea416b..468bf17 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -510,7 +510,6 @@
         private boolean mUsbAccessoryConnected;
         private boolean mSourcePower;
         private boolean mSinkPower;
-        private boolean mConfigured;
         private boolean mAudioAccessoryConnected;
         private boolean mAudioAccessorySupported;
 
@@ -543,7 +542,12 @@
         private final UsbPermissionManager mPermissionManager;
         private NotificationManager mNotificationManager;
 
+        /**
+         * Do not debounce for the first disconnect after resetUsbGadget.
+         */
+        protected boolean mResetUsbGadgetDisableDebounce;
         protected boolean mConnected;
+        protected boolean mConfigured;
         protected long mScreenUnlockedFunctions;
         protected boolean mBootCompleted;
         protected boolean mCurrentFunctionsApplied;
@@ -650,15 +654,29 @@
                 Slog.e(TAG, "unknown state " + state);
                 return;
             }
-            if (configured == 0) removeMessages(MSG_UPDATE_STATE);
             if (connected == 1) removeMessages(MSG_FUNCTION_SWITCH_TIMEOUT);
             Message msg = Message.obtain(this, MSG_UPDATE_STATE);
             msg.arg1 = connected;
             msg.arg2 = configured;
-            // debounce disconnects to avoid problems bringing up USB tethering
-            sendMessageDelayed(msg,
+            if (DEBUG) {
+                Slog.i(TAG, "mResetUsbGadgetDisableDebounce:" + mResetUsbGadgetDisableDebounce
+                       + " connected:" + connected + "configured:" + configured);
+            }
+            if (mResetUsbGadgetDisableDebounce) {
+                // Do not debounce disconnect after resetUsbGadget.
+                sendMessage(msg);
+                if (connected == 1) mResetUsbGadgetDisableDebounce = false;
+            } else {
+                if (configured == 0) {
+                    removeMessages(MSG_UPDATE_STATE);
+                    if (DEBUG) Slog.i(TAG, "removeMessages MSG_UPDATE_STATE");
+                }
+                if (connected == 1) removeMessages(MSG_FUNCTION_SWITCH_TIMEOUT);
+                // debounce disconnects to avoid problems bringing up USB tethering.
+                sendMessageDelayed(msg,
                     (connected == 0) ? (mScreenLocked ? DEVICE_STATE_UPDATE_DELAY
                                                       : DEVICE_STATE_UPDATE_DELAY_EXT) : 0);
+            }
         }
 
         public void updateHostState(UsbPort port, UsbPortStatus status) {
@@ -904,7 +922,10 @@
                 case MSG_UPDATE_STATE:
                     mConnected = (msg.arg1 == 1);
                     mConfigured = (msg.arg2 == 1);
-
+                    if (DEBUG) {
+                        Slog.i(TAG, "handleMessage MSG_UPDATE_STATE " + "mConnected:" + mConnected
+                               + " mConfigured:" + mConfigured);
+                    }
                     updateUsbNotification(false);
                     updateAdbNotification(false);
                     if (mBootCompleted) {
@@ -2010,12 +2031,19 @@
                         }
 
                         try {
+                            // MSG_ACCESSORY_MODE_ENTER_TIMEOUT has to be removed to allow exiting
+                            // AOAP mode during resetUsbGadget.
+                            removeMessages(MSG_ACCESSORY_MODE_ENTER_TIMEOUT);
+                            if (mConfigured) {
+                                mResetUsbGadgetDisableDebounce = true;
+                            }
                             android.hardware.usb.gadget.V1_1.IUsbGadget gadgetProxy =
                                     android.hardware.usb.gadget.V1_1.IUsbGadget
                                             .castFrom(mGadgetProxy);
                             gadgetProxy.reset();
                         } catch (RemoteException e) {
                             Slog.e(TAG, "reset Usb Gadget failed", e);
+                            mResetUsbGadgetDisableDebounce = false;
                         }
                     }
                     break;
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
index a8cbc5d..e05312f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
@@ -18,12 +18,15 @@
 
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.RequiresDevice
+import android.platform.test.rule.SettingOverrideRule
+import android.provider.Settings
 import androidx.test.filters.FlakyTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group1
 import com.android.server.wm.flicker.dsl.FlickerBuilder
+import org.junit.ClassRule
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -98,5 +101,16 @@
             return com.android.server.wm.flicker.FlickerTestParameterFactory.getInstance()
                     .getConfigNonRotationTests(repetitions = 3)
         }
+
+        /**
+         * Ensures that posted notifications will be visible on the lockscreen and not
+         * suppressed due to being marked as seen.
+         */
+        @ClassRule
+        @JvmField
+        val disableUnseenNotifFilterRule = SettingOverrideRule(
+            Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS,
+            /* value= */ "0",
+        )
     }
-}
\ No newline at end of file
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
index cd8dea0..fcec79f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
@@ -18,6 +18,8 @@
 
 import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.RequiresDevice
+import android.platform.test.rule.SettingOverrideRule
+import android.provider.Settings
 import androidx.test.filters.FlakyTest
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
@@ -25,6 +27,7 @@
 import com.android.server.wm.flicker.annotation.Group1
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.traces.common.FlickerComponentName
+import org.junit.ClassRule
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -124,5 +127,16 @@
             return com.android.server.wm.flicker.FlickerTestParameterFactory.getInstance()
                     .getConfigNonRotationTests(repetitions = 3)
         }
+
+        /**
+         * Ensures that posted notifications will be visible on the lockscreen and not
+         * suppressed due to being marked as seen.
+         */
+        @ClassRule
+        @JvmField
+        val disableUnseenNotifFilterRule = SettingOverrideRule(
+            Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS,
+            /* value= */ "0",
+        )
     }
-}
\ No newline at end of file
+}